ia64/xen-unstable

changeset 19:78ce779f901c

bitkeeper revision 1.7.1.7 (3df0b21aFrBUXjYnKdTMgt_D5mJJbg)

conflict resolutions
author akw27@labyrinth.cl.cam.ac.uk
date Fri Dec 06 14:20:10 2002 +0000 (2002-12-06)
parents 8d92e87aa174 46df14441a61
children d421c8e84808
files .rootkeys BitKeeper/etc/logging_ok xen-2.4.16/common/domain.c xen-2.4.16/common/kernel.c xen-2.4.16/common/network.c xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h xen-2.4.16/include/hypervisor-ifs/network.h xen-2.4.16/include/xeno/in.h xen-2.4.16/include/xeno/skbuff.h xen-2.4.16/include/xeno/vif.h xen-2.4.16/net/dev.c xen-2.4.16/net/skbuff.c xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/vfr.c xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c xenolinux-2.4.16-sparse/include/asm-xeno/irq.h
line diff
     1.1 --- a/.rootkeys	Fri Dec 06 11:40:56 2002 +0000
     1.2 +++ b/.rootkeys	Fri Dec 06 14:20:10 2002 +0000
     1.3 @@ -195,6 +195,7 @@ 3ddb79c0MM575N4YvMSiw9EqKH4JDA xen-2.4.1
     1.4  3ddb79c1yHLp08JhgPxIMcZ8DwN9hg xen-2.4.16/include/xeno/if.h
     1.5  3ddb79c1RCWOkWPQRzbYVTX_e-E7CA xen-2.4.16/include/xeno/if_ether.h
     1.6  3ddb79c2IYah7z7hkzPyOiG8szKkyw xen-2.4.16/include/xeno/if_packet.h
     1.7 +3df0af1c-QrOEqpPHq4uL3NZzCeJCg xen-2.4.16/include/xeno/in.h
     1.8  3ddb79c0GurNF9tDWqQbAwJFH8ugfA xen-2.4.16/include/xeno/init.h
     1.9  3ddb79c1Vi5VleJAOKHAlY0G2zAsgw xen-2.4.16/include/xeno/interrupt.h
    1.10  3ddb79c2J6EnruiygRhBCgftzMzTeQ xen-2.4.16/include/xeno/ioctl.h
     2.1 --- a/BitKeeper/etc/logging_ok	Fri Dec 06 11:40:56 2002 +0000
     2.2 +++ b/BitKeeper/etc/logging_ok	Fri Dec 06 14:20:10 2002 +0000
     2.3 @@ -1,4 +1,5 @@
     2.4  akw27@boulderdash.cl.cam.ac.uk
     2.5 +akw27@labyrinth.cl.cam.ac.uk
     2.6  kaf24@labyrinth.cl.cam.ac.uk
     2.7  kaf24@plym.cl.cam.ac.uk
     2.8  kaf24@striker.cl.cam.ac.uk
     3.1 --- a/xen-2.4.16/common/domain.c	Fri Dec 06 11:40:56 2002 +0000
     3.2 +++ b/xen-2.4.16/common/domain.c	Fri Dec 06 14:20:10 2002 +0000
     3.3 @@ -410,6 +410,8 @@ int setup_guestos(struct task_struct *p,
     3.4      l1_pgentry_t *l1tab = NULL;
     3.5      struct pfn_info *page = NULL;
     3.6      net_ring_t *net_ring;
     3.7 +    blk_ring_t *blk_ring;
     3.8 +    net_vif_t *net_vif;
     3.9  
    3.10      if ( strncmp(__va(mod[0].mod_start), "XenoGues", 8) )
    3.11      {
    3.12 @@ -574,7 +576,8 @@ int setup_guestos(struct task_struct *p,
    3.13  
    3.14      /* Add virtual network interfaces and point to them in startinfo. */
    3.15      while (params->num_vifs-- > 0) {
    3.16 -        net_ring = create_net_vif(dom);
    3.17 +        net_vif = create_net_vif(dom);
    3.18 +        net_ring = net_vif->net_ring;
    3.19          if (!net_ring) panic("no network ring!\n");
    3.20      }
    3.21  
     4.1 --- a/xen-2.4.16/common/kernel.c	Fri Dec 06 11:40:56 2002 +0000
     4.2 +++ b/xen-2.4.16/common/kernel.c	Fri Dec 06 14:20:10 2002 +0000
     4.3 @@ -176,6 +176,7 @@ void cmain (unsigned long magic, multibo
     4.4      /* Create initial domain 0. */
     4.5      dom0_params.num_vifs  = 1;
     4.6      dom0_params.memory_kb = opt_dom0_mem;
     4.7 +    add_default_net_rule(0, opt_ipbase); // add vfr info for dom0
     4.8  
     4.9      new_dom = do_newdomain();
    4.10      if ( new_dom == NULL ) panic("Error creating domain 0\n");
     5.1 --- a/xen-2.4.16/common/network.c	Fri Dec 06 11:40:56 2002 +0000
     5.2 +++ b/xen-2.4.16/common/network.c	Fri Dec 06 14:20:10 2002 +0000
     5.3 @@ -11,6 +11,10 @@
     5.4  #include <xeno/init.h>
     5.5  #include <xeno/slab.h>
     5.6  #include <xeno/spinlock.h>
     5.7 +#include <xeno/if_ether.h>
     5.8 +#include <linux/skbuff.h>
     5.9 +#include <xeno/netdevice.h>
    5.10 +#include <xeno/in.h>
    5.11  
    5.12  /* vif globals 
    5.13   * sys_vif_list is a lookup table for vifs, used in packet forwarding.
    5.14 @@ -23,8 +27,11 @@ net_rule_ent_t *net_rule_list;
    5.15  kmem_cache_t *net_vif_cache;
    5.16  kmem_cache_t *net_rule_cache;
    5.17  static rwlock_t net_rule_lock = RW_LOCK_UNLOCKED;
    5.18 +static rwlock_t sys_vif_lock = RW_LOCK_UNLOCKED;
    5.19  
    5.20 -net_ring_t *create_net_vif(int domain)
    5.21 +void print_net_rule_list();
    5.22 +
    5.23 +net_vif_t *create_net_vif(int domain)
    5.24  {
    5.25      net_vif_t *new_vif;
    5.26      net_ring_t *new_ring;
    5.27 @@ -39,18 +46,23 @@ net_ring_t *create_net_vif(int domain)
    5.28      {
    5.29              return NULL;
    5.30      }
    5.31 -    dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif;
    5.32      
    5.33      new_ring = dom_task->net_ring_base + dom_task->num_net_vifs;
    5.34      memset(new_ring, 0, sizeof(net_ring_t));
    5.35  
    5.36 -    dom_task->net_vif_list[dom_task->num_net_vifs]->net_ring = new_ring;
    5.37 -    skb_queue_head_init(
    5.38 -                    &dom_task->net_vif_list[dom_task->num_net_vifs]->skb_list);
    5.39 -    dom_task->net_vif_list[dom_task->num_net_vifs]->id = sys_vif_count++;
    5.40 +    new_vif->net_ring = new_ring;
    5.41 +    skb_queue_head_init(&new_vif->skb_list);
    5.42 +    new_vif->domain = domain;
    5.43 +    
    5.44 +    write_lock(&sys_vif_lock);
    5.45 +    new_vif->id = sys_vif_count;
    5.46 +    sys_vif_list[sys_vif_count++] = new_vif;
    5.47 +    write_unlock(&sys_vif_lock);
    5.48 +
    5.49 +    dom_task->net_vif_list[dom_task->num_net_vifs] = new_vif;
    5.50      dom_task->num_net_vifs++;
    5.51 -
    5.52 -    return new_ring;
    5.53 +    
    5.54 +    return new_vif;
    5.55  }
    5.56  
    5.57  /* delete the last vif in the given domain. There doesn't seem to be any reason
    5.58 @@ -68,9 +80,28 @@ void destroy_net_vif(struct task_struct 
    5.59      {
    5.60          kfree_skb(skb);
    5.61      }
    5.62 +    
    5.63 +    write_lock(&sys_vif_lock);
    5.64 +    sys_vif_list[p->net_vif_list[i]->id] = NULL; // system vif list not gc'ed
    5.65 +    write_unlock(&sys_vif_lock);        
    5.66 +    
    5.67      kmem_cache_free(net_vif_cache, p->net_vif_list[i]);
    5.68  }
    5.69  
    5.70 +void print_vif_list()
    5.71 +{
    5.72 +    int i;
    5.73 +    net_vif_t *v;
    5.74 +
    5.75 +    printk("Currently, there are %d VIFs.\n", sys_vif_count);
    5.76 +    for (i=0; i<sys_vif_count; i++)
    5.77 +    {
    5.78 +        v = sys_vif_list[i];
    5.79 +        printk("] VIF Entry %d(%d):\n", i, v->id);
    5.80 +        printk("   > net_ring*:  %p\n", v->net_ring);
    5.81 +        printk("   > domain   :  %u\n", v->domain);
    5.82 +    }
    5.83 +}
    5.84  
    5.85  int add_net_rule(net_rule_t *rule)
    5.86  {
    5.87 @@ -94,17 +125,16 @@ int add_net_rule(net_rule_t *rule)
    5.88  int delete_net_rule(net_rule_t *rule)
    5.89  {
    5.90      net_rule_ent_t *ent = net_rule_list, *prev = NULL;
    5.91 -
    5.92 -    while ( (ent) && (!(memcmp(rule, &ent->r, sizeof(net_rule_t)))) )
    5.93 +    while ( (ent) && ((memcmp(rule, &ent->r, sizeof(net_rule_t))) != 0) )
    5.94      {
    5.95          prev = ent;
    5.96          ent = ent->next;
    5.97      }
    5.98  
    5.99 -    if (ent)
   5.100 +    if (ent != NULL)
   5.101      {
   5.102          write_lock(&net_rule_lock);
   5.103 -        if (prev)
   5.104 +        if (prev != NULL)
   5.105          {
   5.106              prev->next = ent->next;
   5.107          }
   5.108 @@ -115,10 +145,39 @@ int delete_net_rule(net_rule_t *rule)
   5.109          kmem_cache_free(net_rule_cache, ent);
   5.110          write_unlock(&net_rule_lock);
   5.111      }
   5.112 -
   5.113      return 0;
   5.114  }
   5.115 -        
   5.116 + 
   5.117 +/* add_default_net_rule.
   5.118 + * this is a utility function to route all traffic with the specified
   5.119 + * ip address to the specified vif.  It's used to set up domain zero.
   5.120 + */
   5.121 +void add_default_net_rule(int vif_id, u32 ipaddr)
   5.122 +{
   5.123 +    net_rule_t new_rule;
   5.124 +
   5.125 +    //outbound rule.
   5.126 +    memset(&new_rule, 0, sizeof(net_rule_t));
   5.127 +    new_rule.src_addr = ipaddr;
   5.128 +    new_rule.src_addr_mask = 0xffffffff;
   5.129 +    new_rule.src_interface = vif_id;
   5.130 +    new_rule.dst_interface = VIF_PHYSICAL_INTERFACE;
   5.131 +    new_rule.action = NETWORK_ACTION_ACCEPT;
   5.132 +    new_rule.proto = NETWORK_PROTO_ANY;
   5.133 +    add_net_rule(&new_rule);
   5.134 +
   5.135 +    //inbound rule;
   5.136 +    memset(&new_rule, 0, sizeof(net_rule_t));
   5.137 +    new_rule.dst_addr = ipaddr;
   5.138 +    new_rule.dst_addr_mask = 0xffffffff;
   5.139 +    new_rule.src_interface = VIF_PHYSICAL_INTERFACE;
   5.140 +    new_rule.dst_interface = vif_id;
   5.141 +    new_rule.action = NETWORK_ACTION_ACCEPT;
   5.142 +    new_rule.proto = NETWORK_PROTO_ANY;
   5.143 +    add_net_rule(&new_rule);
   5.144 +
   5.145 +}
   5.146 +
   5.147  void print_net_rule(net_rule_t *r)
   5.148  {
   5.149      printk("===] NET RULE:\n");
   5.150 @@ -131,8 +190,8 @@ void print_net_rule(net_rule_t *r)
   5.151      printk("=] dst_port         : %u\n", r->dst_port);
   5.152      printk("=] dst_port_mask    : %u\n", r->dst_port_mask);
   5.153      printk("=] dst_proto        : %u\n", r->proto);
   5.154 -    printk("=] src_interface    : %u\n", r->src_interface);
   5.155 -    printk("=] dst_interface    : %u\n", r->dst_interface);
   5.156 +    printk("=] src_interface    : %d\n", r->src_interface);
   5.157 +    printk("=] dst_interface    : %d\n", r->dst_interface);
   5.158      printk("=] action           : %u\n", r->action);
   5.159  }
   5.160  
   5.161 @@ -150,6 +209,93 @@ void print_net_rule_list()
   5.162      printk("\nTotal of %d rules.\n", count);
   5.163  }
   5.164  
   5.165 +/* Apply the rules to this skbuff and return the vif id that it is bound for.
   5.166 + * -1 to drop.
   5.167 + */
   5.168 +
   5.169 +int net_find_rule(u8 nproto, u8 tproto, u32 src_addr, u32 dst_addr, u16 src_port, u16 dst_port, 
   5.170 +                  int src_vif)
   5.171 +{
   5.172 +    net_rule_ent_t *ent;
   5.173 +    int dest = VIF_DROP;
   5.174 +    
   5.175 +    read_lock(&net_rule_lock);
   5.176 +    
   5.177 +    ent = net_rule_list;
   5.178 +    
   5.179 +    while (ent)
   5.180 +    {
   5.181 +        if (    (    (ent->r.src_interface == src_vif) 
   5.182 +                  || (ent->r.src_interface == VIF_ANY_INTERFACE) )
   5.183 +
   5.184 +             && (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask ))
   5.185 +             && (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask ))
   5.186 +             && (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask ))
   5.187 +             && (!((ent->r.dst_port ^ dst_port) & ent->r.dst_port_mask ))
   5.188 +
   5.189 +             && (
   5.190 +                     (ent->r.proto == NETWORK_PROTO_ANY)
   5.191 +                  || ((ent->r.proto == NETWORK_PROTO_IP)  && (nproto == (u8)ETH_P_IP))
   5.192 +                  || ((ent->r.proto == NETWORK_PROTO_ARP) && (nproto == (u8)ETH_P_ARP))
   5.193 +                  || ((ent->r.proto == NETWORK_PROTO_TCP) && (tproto == IPPROTO_TCP))
   5.194 +                  || ((ent->r.proto == NETWORK_PROTO_UDP) && (tproto == IPPROTO_UDP))
   5.195 +                )
   5.196 +           )
   5.197 +        {
   5.198 +            break;
   5.199 +        }
   5.200 +        ent = ent->next;
   5.201 +    }
   5.202 +
   5.203 +    if (ent) (dest = ent->r.dst_interface);
   5.204 +    read_unlock(&net_rule_lock);
   5.205 +    return dest;
   5.206 +}
   5.207 +
   5.208 +int net_get_target_vif(struct sk_buff *skb)
   5.209 +{
   5.210 +    int target = VIF_DROP;
   5.211 +    skb->h.raw = skb->nh.raw = skb->data;
   5.212 +    if ( skb->len < 2 ) goto drop;
   5.213 +    switch ( ntohs(skb->mac.ethernet->h_proto) )
   5.214 +    {
   5.215 +    case ETH_P_ARP:
   5.216 +        if ( skb->len < 28 ) goto drop;
   5.217 +        target = net_find_rule((u8)ETH_P_ARP, 0, ntohl(*(u32 *)(skb->nh.raw + 14)),
   5.218 +                        ntohl(*(u32 *)(skb->nh.raw + 24)), 0, 0, 
   5.219 +                        skb->src_vif);
   5.220 +        break;
   5.221 +    case ETH_P_IP:
   5.222 +        if ( skb->len < 20 ) goto drop;
   5.223 +        skb->h.raw += ((*(unsigned char *)(skb->nh.raw)) & 0x0f) * 4;
   5.224 +        switch ( *(unsigned char *)(skb->nh.raw + 9) )
   5.225 +        {
   5.226 +        case IPPROTO_TCP:
   5.227 +        case IPPROTO_UDP:
   5.228 +            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(skb->nh.raw + 9),
   5.229 +                    ntohl(*(u32 *)(skb->nh.raw + 12)),
   5.230 +                    ntohl(*(u32 *)(skb->nh.raw + 16)),
   5.231 +                    ntohs(*(u16 *)(skb->h.raw)),
   5.232 +                    ntohs(*(u16 *)(skb->h.raw + 2)), 
   5.233 +                    skb->src_vif);
   5.234 +            break;
   5.235 +        default: // ip-based protocol where we don't have ports.
   5.236 +            target = net_find_rule((u8)ETH_P_IP,  *(u8 *)(skb->nh.raw + 9),
   5.237 +                    ntohl(*(u32 *)(skb->nh.raw + 12)),
   5.238 +                    ntohl(*(u32 *)(skb->nh.raw + 16)),
   5.239 +                    0,
   5.240 +                    0, 
   5.241 +                    skb->src_vif);
   5.242 +        }
   5.243 +        break;
   5.244 +    }
   5.245 +    skb->dst_vif=target;
   5.246 +    return target;
   5.247 +    
   5.248 +    drop:
   5.249 +    return VIF_DROP;
   5.250 +}
   5.251 +
   5.252  /* 
   5.253   * This is the hook function to handle guest-invoked traps requesting 
   5.254   * changes to the network system.
   5.255 @@ -199,6 +345,7 @@ long do_network_op(network_op_t *u_netwo
   5.256  void __init net_init (void)
   5.257  {
   5.258      sys_vif_count = 0;
   5.259 +    memset(sys_vif_list, 0, sizeof(sys_vif_list));
   5.260      net_rule_list = NULL;
   5.261      net_vif_cache = kmem_cache_create("net_vif_cache", sizeof(net_vif_t),
   5.262                                      0, SLAB_HWCACHE_ALIGN, NULL, NULL);
     6.1 --- a/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Fri Dec 06 11:40:56 2002 +0000
     6.2 +++ b/xen-2.4.16/include/hypervisor-ifs/hypervisor-if.h	Fri Dec 06 14:20:10 2002 +0000
     6.3 @@ -44,21 +44,162 @@ typedef struct
     6.4  #define TRAP_INSTR "int $0x82"
     6.5  
     6.6  
     6.7 +static inline int HYPERVISOR_set_trap_table(trap_info_t *table)
     6.8 +{
     6.9 +    int ret;
    6.10 +    __asm__ __volatile__ (
    6.11 +        TRAP_INSTR
    6.12 +        : "=a" (ret) : "0" (__HYPERVISOR_set_trap_table),
    6.13 +        "b" (table) );
    6.14 +
    6.15 +    return ret;
    6.16 +}
    6.17 +
    6.18 +
    6.19 +static inline int HYPERVISOR_pt_update(page_update_request_t *req, int count)
    6.20 +{
    6.21 +    int ret;
    6.22 +    __asm__ __volatile__ (
    6.23 +        TRAP_INSTR
    6.24 +        : "=a" (ret) : "0" (__HYPERVISOR_pt_update), 
    6.25 +        "b" (req), "c" (count) );
    6.26 +
    6.27 +    return ret;
    6.28 +}
    6.29 +
    6.30 +
    6.31 +static inline int HYPERVISOR_console_write(const char *str, int count)
    6.32 +{
    6.33 +    int ret;
    6.34 +    __asm__ __volatile__ (
    6.35 +        TRAP_INSTR
    6.36 +        : "=a" (ret) : "0" (__HYPERVISOR_console_write), 
    6.37 +        "b" (str), "c" (count) );
    6.38 +
    6.39 +
    6.40 +    return ret;
    6.41 +}
    6.42 +
    6.43 +static inline int HYPERVISOR_set_pagetable(unsigned long ptr)
    6.44 +{
    6.45 +    int ret;
    6.46 +    __asm__ __volatile__ (
    6.47 +        TRAP_INSTR
    6.48 +        : "=a" (ret) : "0" (__HYPERVISOR_set_pagetable),
    6.49 +        "b" (ptr) );
    6.50 +
    6.51 +    return ret;
    6.52 +}
    6.53 +
    6.54 +static inline int HYPERVISOR_set_guest_stack(
    6.55 +    unsigned long ss, unsigned long esp)
    6.56 +{
    6.57 +    int ret;
    6.58 +    __asm__ __volatile__ (
    6.59 +        TRAP_INSTR
    6.60 +        : "=a" (ret) : "0" (__HYPERVISOR_set_guest_stack),
    6.61 +        "b" (ss), "c" (esp) );
    6.62 +
    6.63 +    return ret;
    6.64 +}
    6.65 +
    6.66 +static inline int HYPERVISOR_net_update(void)
    6.67 +{
    6.68 +    int ret;
    6.69 +    __asm__ __volatile__ (
    6.70 +        TRAP_INSTR
    6.71 +        : "=a" (ret) : "0" (__HYPERVISOR_net_update) );
    6.72 +
    6.73 +    return ret;
    6.74 +}
    6.75 +
    6.76 +static inline int HYPERVISOR_fpu_taskswitch(void)
    6.77 +{
    6.78 +    int ret;
    6.79 +    __asm__ __volatile__ (
    6.80 +        TRAP_INSTR
    6.81 +        : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) );
    6.82 +
    6.83 +    return ret;
    6.84 +}
    6.85 +
    6.86 +static inline int HYPERVISOR_yield(void)
    6.87 +{
    6.88 +    int ret;
    6.89 +    __asm__ __volatile__ (
    6.90 +        TRAP_INSTR
    6.91 +        : "=a" (ret) : "0" (__HYPERVISOR_yield) );
    6.92 +
    6.93 +    return ret;
    6.94 +}
    6.95 +
    6.96 +static inline int HYPERVISOR_exit(void)
    6.97 +{
    6.98 +    int ret;
    6.99 +    __asm__ __volatile__ (
   6.100 +        TRAP_INSTR
   6.101 +        : "=a" (ret) : "0" (__HYPERVISOR_exit) );
   6.102 +
   6.103 +    return ret;
   6.104 +}
   6.105 +
   6.106 +static inline int HYPERVISOR_dom0_op(void *dom0_op)
   6.107 +{
   6.108 +    int ret;
   6.109 +    __asm__ __volatile__ (
   6.110 +        TRAP_INSTR
   6.111 +        : "=a" (ret) : "0" (__HYPERVISOR_dom0_op),
   6.112 +        "b" (dom0_op) );
   6.113 +
   6.114 +    return ret;
   6.115 +}
   6.116 +
   6.117 +static inline int HYPERVISOR_network_op(void *network_op)
   6.118 +{
   6.119 +    int ret;
   6.120 +    __asm__ __volatile__ (
   6.121 +        TRAP_INSTR
   6.122 +        : "=a" (ret) : "0" (__HYPERVISOR_network_op),
   6.123 +        "b" (network_op) );
   6.124 +
   6.125 +    return ret;
   6.126 +}
   6.127 +
   6.128 +/* Event message note:
   6.129 + *
   6.130 + * Here, as in the interrupts to the guestos, additional network interfaces
   6.131 + * are defined.  These definitions server as placeholders for the event bits,
   6.132 + * however, in the code these events will allways be referred to as shifted
   6.133 + * offsets from the base NET events.
   6.134 + */
   6.135 +
   6.136  /* Events that a guest OS may receive from the hypervisor. */
   6.137 -#define EVENT_NET_TX  0x01 /* packets for transmission. */
   6.138 -#define EVENT_NET_RX  0x02 /* empty buffers for receive. */
   6.139 -#define EVENT_TIMER   0x04 /* a timeout has been updated. */
   6.140 -#define EVENT_DIE     0x08 /* OS is about to be killed. Clean up please! */
   6.141 -#define EVENT_BLK_TX  0x10 /* packets for transmission. */
   6.142 -#define EVENT_BLK_RX  0x20 /* empty buffers for receive. */
   6.143 +#define EVENT_BLK_TX   0x01 /* packets for transmission. */
   6.144 +#define EVENT_BLK_RX   0x02 /* empty buffers for receive. */
   6.145 +#define EVENT_TIMER    0x04 /* a timeout has been updated. */
   6.146 +#define EVENT_DIE      0x08 /* OS is about to be killed. Clean up please! */
   6.147 +#define EVENT_NET_TX   0x10 /* packets for transmission. */
   6.148 +#define EVENT_NET_RX   0x20 /* empty buffers for receive. */
   6.149 +#define EVENT_NET2_TX  0x40 /* packets for transmission. */
   6.150 +#define EVENT_NET2_RX  0x80 /* empty buffers for receive. */
   6.151 +
   6.152 +/* should these macros and the ones below test for range violation? */
   6.153 +#define EVENT_NET_TX_FOR_VIF(x)    (EVENT_NET_TX << (2 * x))
   6.154 +#define EVENT_NET_RX_FOR_VIF(x)    (EVENT_NET_RX << (2 * x))
   6.155 +
   6.156  
   6.157  /* Bit offsets, as opposed to the above masks. */
   6.158 -#define _EVENT_NET_TX 0
   6.159 -#define _EVENT_NET_RX 1
   6.160 -#define _EVENT_TIMER  2
   6.161 -#define _EVENT_DIE    3
   6.162 -#define _EVENT_BLK_TX 4
   6.163 -#define _EVENT_BLK_RX 5
   6.164 +#define _EVENT_BLK_TX  0
   6.165 +#define _EVENT_BLK_RX  1
   6.166 +#define _EVENT_TIMER   2
   6.167 +#define _EVENT_DIE     3
   6.168 +#define _EVENT_NET_TX  4
   6.169 +#define _EVENT_NET_RX  5
   6.170 +#define _EVENT_NET2_TX 6
   6.171 +#define _EVENT_NET2_RX 7
   6.172 +
   6.173 +#define _EVENT_NET_TX_FOR_VIF(x)    (_EVENT_NET_TX + (2 * x))
   6.174 +#define _EVENT_NET_RX_FOR_VIF(x)    (_EVENT_NET_RX + (2 * x))
   6.175  
   6.176  /*
   6.177   * NB. We expect that this struct is smaller than a page.
   6.178 @@ -70,7 +211,7 @@ typedef struct shared_info_st {
   6.179      /*
   6.180       * Hypervisor will only signal event delivery via the "callback
   6.181       * exception" when this value is non-zero. Hypervisor clears this when
   6.182 -     * notiying the guest OS -- thsi prevents unbounded reentrancy and
   6.183 +     * notiying the guest OS -- this prevents unbounded reentrancy and
   6.184       * stack overflow (in this way, acts as an interrupt-enable flag).
   6.185       */
   6.186      unsigned long events_enable;
     7.1 --- a/xen-2.4.16/include/hypervisor-ifs/network.h	Fri Dec 06 11:40:56 2002 +0000
     7.2 +++ b/xen-2.4.16/include/hypervisor-ifs/network.h	Fri Dec 06 14:20:10 2002 +0000
     7.3 @@ -52,7 +52,7 @@ typedef struct net_ring_st {
     7.4  } net_ring_t;
     7.5  
     7.6  /* Specify base of per-domain array. Get returned free slot in the array. */
     7.7 -net_ring_t *create_net_vif(int domain);
     7.8 +//net_ring_t *create_net_vif(int domain);
     7.9  
    7.10  /* Packet routing/filtering code follows:
    7.11   */
    7.12 @@ -60,10 +60,11 @@ net_ring_t *create_net_vif(int domain);
    7.13  #define NETWORK_ACTION_ACCEPT   0
    7.14  #define NETWORK_ACTION_COUNT    1
    7.15  
    7.16 -#define NETWORK_PROTO_IP        0
    7.17 -#define NETWORK_PROTO_TCP       1
    7.18 -#define NETWORK_PROTO_UDP       2
    7.19 -#define NETWORK_PROTO_ARP       3
    7.20 +#define NETWORK_PROTO_ANY       0
    7.21 +#define NETWORK_PROTO_IP        1
    7.22 +#define NETWORK_PROTO_TCP       2
    7.23 +#define NETWORK_PROTO_UDP       3
    7.24 +#define NETWORK_PROTO_ARP       4
    7.25  
    7.26  typedef struct net_rule_st 
    7.27  {
    7.28 @@ -77,8 +78,8 @@ typedef struct net_rule_st
    7.29      u16  dst_port_mask;
    7.30      u16  proto;
    7.31      
    7.32 -    u16  src_interface;
    7.33 -    u16 dst_interface;
    7.34 +    int  src_interface;
    7.35 +    int  dst_interface;
    7.36      u16  action;
    7.37  } net_rule_t;
    7.38  
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/xen-2.4.16/include/xeno/in.h	Fri Dec 06 14:20:10 2002 +0000
     8.3 @@ -0,0 +1,190 @@
     8.4 +/*
     8.5 + * INET		An implementation of the TCP/IP protocol suite for the LINUX
     8.6 + *		operating system.  INET is implemented using the  BSD Socket
     8.7 + *		interface as the means of communication with the user level.
     8.8 + *
     8.9 + *		Definitions of the Internet Protocol.
    8.10 + *
    8.11 + * Version:	@(#)in.h	1.0.1	04/21/93
    8.12 + *
    8.13 + * Authors:	Original taken from the GNU Project <netinet/in.h> file.
    8.14 + *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
    8.15 + *
    8.16 + *		This program is free software; you can redistribute it and/or
    8.17 + *		modify it under the terms of the GNU General Public License
    8.18 + *		as published by the Free Software Foundation; either version
    8.19 + *		2 of the License, or (at your option) any later version.
    8.20 + */
    8.21 +#ifndef _LINUX_IN_H
    8.22 +#define _LINUX_IN_H
    8.23 +
    8.24 +#include <linux/types.h>
    8.25 +
    8.26 +/* Standard well-defined IP protocols.  */
    8.27 +enum {
    8.28 +  IPPROTO_IP = 0,		/* Dummy protocol for TCP		*/
    8.29 +  IPPROTO_ICMP = 1,		/* Internet Control Message Protocol	*/
    8.30 +  IPPROTO_IGMP = 2,		/* Internet Group Management Protocol	*/
    8.31 +  IPPROTO_IPIP = 4,		/* IPIP tunnels (older KA9Q tunnels use 94) */
    8.32 +  IPPROTO_TCP = 6,		/* Transmission Control Protocol	*/
    8.33 +  IPPROTO_EGP = 8,		/* Exterior Gateway Protocol		*/
    8.34 +  IPPROTO_PUP = 12,		/* PUP protocol				*/
    8.35 +  IPPROTO_UDP = 17,		/* User Datagram Protocol		*/
    8.36 +  IPPROTO_IDP = 22,		/* XNS IDP protocol			*/
    8.37 +  IPPROTO_RSVP = 46,		/* RSVP protocol			*/
    8.38 +  IPPROTO_GRE = 47,		/* Cisco GRE tunnels (rfc 1701,1702)	*/
    8.39 +
    8.40 +  IPPROTO_IPV6	 = 41,		/* IPv6-in-IPv4 tunnelling		*/
    8.41 +
    8.42 +  IPPROTO_PIM    = 103,		/* Protocol Independent Multicast	*/
    8.43 +
    8.44 +  IPPROTO_ESP = 50,            /* Encapsulation Security Payload protocol */
    8.45 +  IPPROTO_AH = 51,             /* Authentication Header protocol       */
    8.46 +  IPPROTO_COMP   = 108,                /* Compression Header protocol */
    8.47 +
    8.48 +  IPPROTO_RAW	 = 255,		/* Raw IP packets			*/
    8.49 +  IPPROTO_MAX
    8.50 +};
    8.51 +
    8.52 +
    8.53 +/* Internet address. */
    8.54 +struct in_addr {
    8.55 +	__u32	s_addr;
    8.56 +};
    8.57 +
    8.58 +#define IP_TOS		1
    8.59 +#define IP_TTL		2
    8.60 +#define IP_HDRINCL	3
    8.61 +#define IP_OPTIONS	4
    8.62 +#define IP_ROUTER_ALERT	5
    8.63 +#define IP_RECVOPTS	6
    8.64 +#define IP_RETOPTS	7
    8.65 +#define IP_PKTINFO	8
    8.66 +#define IP_PKTOPTIONS	9
    8.67 +#define IP_MTU_DISCOVER	10
    8.68 +#define IP_RECVERR	11
    8.69 +#define IP_RECVTTL	12
    8.70 +#define	IP_RECVTOS	13
    8.71 +#define IP_MTU		14
    8.72 +#define IP_FREEBIND	15
    8.73 +
    8.74 +/* BSD compatibility */
    8.75 +#define IP_RECVRETOPTS	IP_RETOPTS
    8.76 +
    8.77 +/* IP_MTU_DISCOVER values */
    8.78 +#define IP_PMTUDISC_DONT		0	/* Never send DF frames */
    8.79 +#define IP_PMTUDISC_WANT		1	/* Use per route hints	*/
    8.80 +#define IP_PMTUDISC_DO			2	/* Always DF		*/
    8.81 +
    8.82 +#define IP_MULTICAST_IF			32
    8.83 +#define IP_MULTICAST_TTL 		33
    8.84 +#define IP_MULTICAST_LOOP 		34
    8.85 +#define IP_ADD_MEMBERSHIP		35
    8.86 +#define IP_DROP_MEMBERSHIP		36
    8.87 +
    8.88 +/* These need to appear somewhere around here */
    8.89 +#define IP_DEFAULT_MULTICAST_TTL        1
    8.90 +#define IP_DEFAULT_MULTICAST_LOOP       1
    8.91 +
    8.92 +/* Request struct for multicast socket ops */
    8.93 +
    8.94 +struct ip_mreq 
    8.95 +{
    8.96 +	struct in_addr imr_multiaddr;	/* IP multicast address of group */
    8.97 +	struct in_addr imr_interface;	/* local IP address of interface */
    8.98 +};
    8.99 +
   8.100 +struct ip_mreqn
   8.101 +{
   8.102 +	struct in_addr	imr_multiaddr;		/* IP multicast address of group */
   8.103 +	struct in_addr	imr_address;		/* local IP address of interface */
   8.104 +	int		imr_ifindex;		/* Interface index */
   8.105 +};
   8.106 +
   8.107 +struct in_pktinfo
   8.108 +{
   8.109 +	int		ipi_ifindex;
   8.110 +	struct in_addr	ipi_spec_dst;
   8.111 +	struct in_addr	ipi_addr;
   8.112 +};
   8.113 +
   8.114 +/* Structure describing an Internet (IP) socket address. */
   8.115 +#define __SOCK_SIZE__	16		/* sizeof(struct sockaddr)	*/
   8.116 +struct sockaddr_in {
   8.117 +  sa_family_t		sin_family;	/* Address family		*/
   8.118 +  unsigned short int	sin_port;	/* Port number			*/
   8.119 +  struct in_addr	sin_addr;	/* Internet address		*/
   8.120 +
   8.121 +  /* Pad to size of `struct sockaddr'. */
   8.122 +  unsigned char		__pad[__SOCK_SIZE__ - sizeof(short int) -
   8.123 +			sizeof(unsigned short int) - sizeof(struct in_addr)];
   8.124 +};
   8.125 +#define sin_zero	__pad		/* for BSD UNIX comp. -FvK	*/
   8.126 +
   8.127 +
   8.128 +/*
   8.129 + * Definitions of the bits in an Internet address integer.
   8.130 + * On subnets, host and network parts are found according
   8.131 + * to the subnet mask, not these masks.
   8.132 + */
   8.133 +#define	IN_CLASSA(a)		((((long int) (a)) & 0x80000000) == 0)
   8.134 +#define	IN_CLASSA_NET		0xff000000
   8.135 +#define	IN_CLASSA_NSHIFT	24
   8.136 +#define	IN_CLASSA_HOST		(0xffffffff & ~IN_CLASSA_NET)
   8.137 +#define	IN_CLASSA_MAX		128
   8.138 +
   8.139 +#define	IN_CLASSB(a)		((((long int) (a)) & 0xc0000000) == 0x80000000)
   8.140 +#define	IN_CLASSB_NET		0xffff0000
   8.141 +#define	IN_CLASSB_NSHIFT	16
   8.142 +#define	IN_CLASSB_HOST		(0xffffffff & ~IN_CLASSB_NET)
   8.143 +#define	IN_CLASSB_MAX		65536
   8.144 +
   8.145 +#define	IN_CLASSC(a)		((((long int) (a)) & 0xe0000000) == 0xc0000000)
   8.146 +#define	IN_CLASSC_NET		0xffffff00
   8.147 +#define	IN_CLASSC_NSHIFT	8
   8.148 +#define	IN_CLASSC_HOST		(0xffffffff & ~IN_CLASSC_NET)
   8.149 +
   8.150 +#define	IN_CLASSD(a)		((((long int) (a)) & 0xf0000000) == 0xe0000000)
   8.151 +#define	IN_MULTICAST(a)		IN_CLASSD(a)
   8.152 +#define IN_MULTICAST_NET	0xF0000000
   8.153 +
   8.154 +#define	IN_EXPERIMENTAL(a)	((((long int) (a)) & 0xf0000000) == 0xf0000000)
   8.155 +#define	IN_BADCLASS(a)		IN_EXPERIMENTAL((a))
   8.156 +
   8.157 +/* Address to accept any incoming messages. */
   8.158 +#define	INADDR_ANY		((unsigned long int) 0x00000000)
   8.159 +
   8.160 +/* Address to send to all hosts. */
   8.161 +#define	INADDR_BROADCAST	((unsigned long int) 0xffffffff)
   8.162 +
   8.163 +/* Address indicating an error return. */
   8.164 +#define	INADDR_NONE		((unsigned long int) 0xffffffff)
   8.165 +
   8.166 +/* Network number for local host loopback. */
   8.167 +#define	IN_LOOPBACKNET		127
   8.168 +
   8.169 +/* Address to loopback in software to local host.  */
   8.170 +#define	INADDR_LOOPBACK		0x7f000001	/* 127.0.0.1   */
   8.171 +#define	IN_LOOPBACK(a)		((((long int) (a)) & 0xff000000) == 0x7f000000)
   8.172 +
   8.173 +/* Defines for Multicast INADDR */
   8.174 +#define INADDR_UNSPEC_GROUP   	0xe0000000U	/* 224.0.0.0   */
   8.175 +#define INADDR_ALLHOSTS_GROUP 	0xe0000001U	/* 224.0.0.1   */
   8.176 +#define INADDR_ALLRTRS_GROUP    0xe0000002U	/* 224.0.0.2 */
   8.177 +#define INADDR_MAX_LOCAL_GROUP  0xe00000ffU	/* 224.0.0.255 */
   8.178 +
   8.179 +
   8.180 +/* <asm/byteorder.h> contains the htonl type stuff.. */
   8.181 +#include <asm/byteorder.h> 
   8.182 +
   8.183 +#ifdef __KERNEL__
   8.184 +/* Some random defines to make it easier in the kernel.. */
   8.185 +#define LOOPBACK(x)	(((x) & htonl(0xff000000)) == htonl(0x7f000000))
   8.186 +#define MULTICAST(x)	(((x) & htonl(0xf0000000)) == htonl(0xe0000000))
   8.187 +#define BADCLASS(x)	(((x) & htonl(0xf0000000)) == htonl(0xf0000000))
   8.188 +#define ZERONET(x)	(((x) & htonl(0xff000000)) == htonl(0x00000000))
   8.189 +#define LOCAL_MCAST(x)	(((x) & htonl(0xFFFFFF00)) == htonl(0xE0000000))
   8.190 +
   8.191 +#endif
   8.192 +
   8.193 +#endif	/* _LINUX_IN_H */
     9.1 --- a/xen-2.4.16/include/xeno/skbuff.h	Fri Dec 06 11:40:56 2002 +0000
     9.2 +++ b/xen-2.4.16/include/xeno/skbuff.h	Fri Dec 06 14:20:10 2002 +0000
     9.3 @@ -28,6 +28,12 @@
     9.4  #include <linux/mm.h>
     9.5  //#include <linux/highmem.h>
     9.6  
     9.7 +// vif special values.
     9.8 +#define VIF_PHYSICAL_INTERFACE  -1
     9.9 +#define VIF_UNKNOWN_INTERFACE   -2
    9.10 +#define VIF_DROP                -3
    9.11 +#define VIF_ANY_INTERFACE       -4
    9.12 +
    9.13  #define HAVE_ALLOC_SKB		/* For the drivers to know */
    9.14  #define HAVE_ALIGNABLE_SKB	/* Ditto 8)		   */
    9.15  #define SLAB_SKB 		/* Slabified skbuffs 	   */
    9.16 @@ -196,6 +202,12 @@ struct sk_buff {
    9.17  	unsigned char 	*end;			/* End pointer					*/
    9.18  
    9.19  	void 		(*destructor)(struct sk_buff *);	/* Destruct function		*/
    9.20 +
    9.21 +        int src_vif;                            /* vif we came from */
    9.22 +        int dst_vif;                            /* vif we are bound for */
    9.23 +
    9.24 +                
    9.25 +        
    9.26  #ifdef CONFIG_NETFILTER
    9.27  	/* Can be used for communication between hooks. */
    9.28          unsigned long	nfmark;
    10.1 --- a/xen-2.4.16/include/xeno/vif.h	Fri Dec 06 11:40:56 2002 +0000
    10.2 +++ b/xen-2.4.16/include/xeno/vif.h	Fri Dec 06 14:20:10 2002 +0000
    10.3 @@ -20,6 +20,7 @@ typedef struct net_vif_st {
    10.4      net_ring_t  *net_ring;
    10.5      int          id;
    10.6      struct sk_buff_head skb_list;
    10.7 +    unsigned int domain;
    10.8      // rules table goes here in next revision.
    10.9  } net_vif_t;
   10.10  
   10.11 @@ -32,6 +33,8 @@ extern int sys_vif_count;
   10.12  extern net_vif_t *sys_vif_list[];
   10.13  
   10.14  /* vif prototypes */
   10.15 -net_ring_t *create_net_vif(int domain);
   10.16 +net_vif_t *create_net_vif(int domain);
   10.17  void destroy_net_vif(struct task_struct *p);
   10.18 -
   10.19 +void add_default_net_rule(int vif_id, u32 ipaddr);
   10.20 +int net_get_target_vif(struct sk_buff *skb);
   10.21 +void add_default_net_rule(int vif_id, u32 ipaddr);
    11.1 --- a/xen-2.4.16/net/dev.c	Fri Dec 06 11:40:56 2002 +0000
    11.2 +++ b/xen-2.4.16/net/dev.c	Fri Dec 06 14:20:10 2002 +0000
    11.3 @@ -687,7 +687,7 @@ int netif_rx(struct sk_buff *skb)
    11.4          unsigned long cpu_mask;
    11.5  #endif
    11.6          struct task_struct *p;
    11.7 -        unsigned int dest_dom;
    11.8 +//        unsigned int dest_dom;
    11.9  	int this_cpu = smp_processor_id();
   11.10  	struct softnet_data *queue;
   11.11  	unsigned long flags;
   11.12 @@ -703,7 +703,7 @@ int netif_rx(struct sk_buff *skb)
   11.13  	local_irq_save(flags);
   11.14          
   11.15  	netdev_rx_stat[this_cpu].total++;
   11.16 -
   11.17 +/*
   11.18          skb->h.raw = skb->nh.raw = skb->data;
   11.19          
   11.20          if ( skb->len < 2 ) goto drop;
   11.21 @@ -741,8 +741,36 @@ int netif_rx(struct sk_buff *skb)
   11.22          while ( (p = p->next_task) != &idle0_task );
   11.23          read_unlock(&tasklist_lock);
   11.24          goto drop;
   11.25 +*/
   11.26 +        if (skb->src_vif == VIF_UNKNOWN_INTERFACE)
   11.27 +            skb->src_vif = VIF_PHYSICAL_INTERFACE;
   11.28  
   11.29 - found:
   11.30 +        if (skb->dst_vif == VIF_UNKNOWN_INTERFACE)
   11.31 +            net_get_target_vif(skb);
   11.32 +if (skb->dst_vif > 1)
   11.33 +printk("netifrx got packet bound for system vif %d.\n", skb->dst_vif);
   11.34 +        if (sys_vif_list[skb->dst_vif] == NULL)
   11.35 +        {
   11.36 +            // the target vif does not exist.
   11.37 +            goto drop;
   11.38 +        }
   11.39 +
   11.40 +        if ( skb->dst_vif >= VIF_PHYSICAL_INTERFACE )
   11.41 +        {
   11.42 +            read_lock(&tasklist_lock);
   11.43 +            p = &idle0_task;
   11.44 +            do {
   11.45 +                if ( p->domain != sys_vif_list[skb->dst_vif]->domain ) continue;
   11.46 +                skb_queue_tail(&sys_vif_list[skb->dst_vif]->skb_list, skb);
   11.47 +                cpu_mask = mark_hyp_event(p, _HYP_EVENT_NET_RX);
   11.48 +                read_unlock(&tasklist_lock);
   11.49 +                goto found;
   11.50 +            }
   11.51 +            while ( (p = p->next_task) != &idle0_task );
   11.52 +            read_unlock(&tasklist_lock); 
   11.53 +            goto drop;
   11.54 +        }
   11.55 +// found:
   11.56  #if 0
   11.57          __skb_queue_tail(&queue->input_pkt_queue,skb);
   11.58          /* Runs from irqs or BH's, no need to wake BH */
   11.59 @@ -750,7 +778,7 @@ int netif_rx(struct sk_buff *skb)
   11.60          local_irq_restore(flags);
   11.61          get_sample_stats(this_cpu);
   11.62          return softnet_data[this_cpu].cng_level;
   11.63 -#else
   11.64 +//#else
   11.65          hyp_event_notify(cpu_mask);
   11.66          local_irq_restore(flags);
   11.67          return 0;
   11.68 @@ -762,6 +790,11 @@ drop:
   11.69  
   11.70  	kfree_skb(skb);
   11.71  	return NET_RX_DROP;
   11.72 +
   11.73 +found:
   11.74 +        hyp_event_notify(cpu_mask);
   11.75 +        local_irq_restore(flags);
   11.76 +        return 0;
   11.77  }
   11.78  
   11.79  /* Deliver skb to an old protocol, which is not threaded well
   11.80 @@ -890,6 +923,18 @@ void flush_rx_queue(void)
   11.81      unsigned int i, nvif;
   11.82      rx_entry_t rx;
   11.83  
   11.84 +    /* I have changed this to batch flush all vifs for a guest
   11.85 +     * at once, whenever this is called.  Since the guest is about to be
   11.86 +     * scheduled and issued an RX interrupt for one nic, it might as well
   11.87 +     * receive all pending traffic  although it will still only get
   11.88 +     * interrupts about rings that pass the event marker.  
   11.89 +     *
   11.90 +     * If this doesn't make sense, _HYP_EVENT_NET_RX can be modified to
   11.91 +     * represent individual interrups as _EVENT_NET_RX and the outer for
   11.92 +     * loop can be replaced with a translation to the specific NET 
   11.93 +     * interrupt to serve. --akw
   11.94 +     */
   11.95 +    
   11.96      clear_bit(_HYP_EVENT_NET_RX, &current->hyp_events);
   11.97  
   11.98      for (nvif = 0; nvif < current->num_net_vifs; nvif++)
   11.99 @@ -898,15 +943,25 @@ void flush_rx_queue(void)
  11.100          while ( (skb = skb_dequeue(&current->net_vif_list[nvif]->skb_list)) 
  11.101                          != NULL )
  11.102          {
  11.103 +if (nvif > 0)
  11.104 +printk("flushrxqueue on vif %d (sys: %d) (pkt_type=%d)\n", nvif, current->net_vif_list[nvif]->id, skb->pkt_type);
  11.105              /*
  11.106               * Write the virtual MAC address into the destination field
  11.107               * of the ethernet packet. Furthermore, do the same for ARP
  11.108               * reply packets. This is easy because the virtual MAC address
  11.109               * is always 00-00-00-00-00-00.
  11.110 +             *
  11.111 +             * Actually, the MAC address is now all zeros, except for the
  11.112 +             * first sixteen bits, which are the per-host vif id.
  11.113 +             * (so eth0 should be 00-00-..., eth1 is 01-00-...)
  11.114               */
  11.115              memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
  11.116 +            *(unsigned int *)(skb->mac.ethernet->h_dest) = nvif;
  11.117              if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
  11.118 +            {
  11.119                  memset(skb->nh.raw + 18, 0, ETH_ALEN);
  11.120 +                *(unsigned int *)(skb->nh.raw + 18) = nvif;
  11.121 +            }
  11.122  
  11.123              i = net_ring->rx_cons;
  11.124              if ( i != net_ring->rx_prod )
  11.125 @@ -920,7 +975,7 @@ void flush_rx_queue(void)
  11.126                  }
  11.127                  net_ring->rx_cons = (i+1) & (RX_RING_SIZE-1);
  11.128                  if ( net_ring->rx_cons == net_ring->rx_event )
  11.129 -                    set_bit(_EVENT_NET_RX, &s->events);
  11.130 +                    set_bit(_EVENT_NET_RX_FOR_VIF(nvif), &s->events);
  11.131              }
  11.132              kfree_skb(skb);
  11.133          }
  11.134 @@ -1912,20 +1967,24 @@ long do_net_update(void)
  11.135  {
  11.136      shared_info_t *shared = current->shared_info;    
  11.137      net_ring_t *net_ring = current->net_ring_base;
  11.138 +    net_vif_t *current_vif;
  11.139      unsigned int i, j;
  11.140      struct sk_buff *skb;
  11.141      tx_entry_t tx;
  11.142  
  11.143      for ( j = 0; j < current->num_net_vifs; j++)
  11.144      {
  11.145 -        net_ring = current->net_vif_list[j]->net_ring;
  11.146 +        current_vif = current->net_vif_list[j];
  11.147 +        net_ring = current_vif->net_ring;
  11.148          for ( i = net_ring->tx_cons; i != net_ring->tx_prod; i = TX_RING_INC(i) )
  11.149          {
  11.150 +if (j > 0)
  11.151 +printk("net_update called with packet on vif %d system: %d)\n", j, current_vif->id);
  11.152              if ( copy_from_user(&tx, net_ring->tx_ring+i, sizeof(tx)) )
  11.153                  continue;
  11.154  
  11.155              if ( TX_RING_INC(i) == net_ring->tx_event )
  11.156 -                set_bit(_EVENT_NET_TX, &shared->events);
  11.157 +                set_bit(_EVENT_NET_TX_FOR_VIF(j), &shared->events);
  11.158  
  11.159              skb = alloc_skb(tx.size, GFP_KERNEL);
  11.160              if ( skb == NULL ) continue;
  11.161 @@ -1965,17 +2024,44 @@ long do_net_update(void)
  11.162              {
  11.163                  skb_get(skb); /* get a reference for non-local delivery */
  11.164                  skb->protocol = eth_type_trans(skb, skb->dev);
  11.165 +                skb->src_vif = current_vif->id; 
  11.166 +                net_get_target_vif(skb);
  11.167 +                if ( skb->dst_vif > VIF_PHYSICAL_INTERFACE )
  11.168 +                {
  11.169 +if (j > 0)
  11.170 +    printk("Sent to netif_rx.\n");
  11.171 +                    if (netif_rx(skb) == 0)
  11.172 +                        /* Give up non-local reference. Packet delivered locally. */
  11.173 +                        kfree_skb(skb);
  11.174 +                }
  11.175 +                else if ( skb->dst_vif == VIF_PHYSICAL_INTERFACE )
  11.176 +                {
  11.177 +if (j > 0)
  11.178 +    printk("Sent to physical device.\n");
  11.179 +
  11.180 +                        skb_push(skb, skb->dev->hard_header_len);
  11.181 +                        dev_queue_xmit(skb);
  11.182 +                } 
  11.183 +                else
  11.184 +                {
  11.185 +if (j > 0)
  11.186 +    printk("dropped.\n");
  11.187 +                    kfree_skb(skb);
  11.188 +                }
  11.189 +
  11.190 +                /*
  11.191 +                skb_get(skb); 
  11.192 +                skb->protocol = eth_type_trans(skb, skb->dev);
  11.193                  if ( netif_rx(skb) == 0 )
  11.194                  {
  11.195 -                    /* Give up non-local reference. Packet delivered locally. */
  11.196                      kfree_skb(skb);
  11.197                  }
  11.198                  else
  11.199                  {
  11.200 -                    /* Pass the non-local reference to the net device. */
  11.201                      skb_push(skb, skb->dev->hard_header_len);
  11.202                      dev_queue_xmit(skb);
  11.203                  }
  11.204 +                */
  11.205              }
  11.206          }
  11.207          net_ring->tx_cons = i;
    12.1 --- a/xen-2.4.16/net/skbuff.c	Fri Dec 06 11:40:56 2002 +0000
    12.2 +++ b/xen-2.4.16/net/skbuff.c	Fri Dec 06 14:20:10 2002 +0000
    12.3 @@ -211,6 +211,8 @@ struct sk_buff *alloc_skb(unsigned int s
    12.4  	skb->len = 0;
    12.5  	skb->cloned = 0;
    12.6  	skb->data_len = 0;
    12.7 +        skb->src_vif = VIF_UNKNOWN_INTERFACE;
    12.8 +        skb->dst_vif = VIF_UNKNOWN_INTERFACE;
    12.9  
   12.10  	atomic_set(&skb->users, 1); 
   12.11  	atomic_set(&(skb_shinfo(skb)->dataref), 1);
    13.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/vfr.c	Fri Dec 06 11:40:56 2002 +0000
    13.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/dom0/vfr.c	Fri Dec 06 14:20:10 2002 +0000
    13.3 @@ -23,6 +23,7 @@ static unsigned char readbuf[1024];
    13.4  /* Helpers, implemented at the bottom. */
    13.5  u32 getipaddr(const char *buff, unsigned int len);
    13.6  u16 antous(const char *buff, int len);
    13.7 +int anton(const char *buff, int len);
    13.8  
    13.9  static int vfr_read_proc(char *page, char **start, off_t off,
   13.10                                            int count, int *eof, void *data)
   13.11 @@ -136,53 +137,55 @@ static int vfr_write_proc(struct file *f
   13.12  
   13.13      if (strncmp(&buffer[fs], "srcaddr", fl) == 0) 
   13.14      {  
   13.15 -      op.u.net_rule.src_addr = getipaddr(&buffer[ts], tl-1);
   13.16 +      op.u.net_rule.src_addr = getipaddr(&buffer[ts], tl);
   13.17      }
   13.18      else if (strncmp(&buffer[fs], "dstaddr", fl) == 0)
   13.19      {    
   13.20 -      op.u.net_rule.dst_addr = getipaddr(&buffer[ts], tl-1);
   13.21 +      op.u.net_rule.dst_addr = getipaddr(&buffer[ts], tl);
   13.22      }
   13.23      else if (strncmp(&buffer[fs], "srcaddrmask", fl) == 0) 
   13.24      {
   13.25 -      op.u.net_rule.src_addr_mask = getipaddr(&buffer[ts], tl-1);
   13.26 +      op.u.net_rule.src_addr_mask = getipaddr(&buffer[ts], tl);
   13.27      }
   13.28      else if (strncmp(&buffer[fs], "dstaddrmask", fl) == 0)
   13.29      {
   13.30 -      op.u.net_rule.dst_addr_mask = getipaddr(&buffer[ts], tl-1);
   13.31 +      op.u.net_rule.dst_addr_mask = getipaddr(&buffer[ts], tl);
   13.32      }
   13.33      else if (strncmp(&buffer[fs], "srcport", fl) == 0)
   13.34      {
   13.35 -      op.u.net_rule.src_port = antous(&buffer[ts], tl-1);
   13.36 +      op.u.net_rule.src_port = antous(&buffer[ts], tl);
   13.37      }
   13.38      else if (strncmp(&buffer[fs], "dstport", fl) == 0)
   13.39      {
   13.40 -      op.u.net_rule.dst_port = antous(&buffer[ts], tl-1);
   13.41 +      op.u.net_rule.dst_port = antous(&buffer[ts], tl);
   13.42      }
   13.43      else if (strncmp(&buffer[fs], "srcportmask", fl) == 0)
   13.44      {
   13.45 -      op.u.net_rule.src_port_mask = antous(&buffer[ts], tl-1);
   13.46 +      op.u.net_rule.src_port_mask = antous(&buffer[ts], tl);
   13.47      }
   13.48      else if (strncmp(&buffer[fs], "dstportmask", fl) == 0)
   13.49      {
   13.50 -      op.u.net_rule.dst_port_mask = antous(&buffer[ts], tl-1);
   13.51 +      op.u.net_rule.dst_port_mask = antous(&buffer[ts], tl);
   13.52      }
   13.53      else if (strncmp(&buffer[fs], "srcint", fl) == 0)
   13.54      {
   13.55 -      op.u.net_rule.src_interface = antous(&buffer[ts], tl-1);
   13.56 +      op.u.net_rule.src_interface = anton(&buffer[ts], tl);
   13.57      }
   13.58      else if (strncmp(&buffer[fs], "dstint", fl) == 0)
   13.59      {
   13.60 -      op.u.net_rule.dst_interface = antous(&buffer[ts], tl-1);
   13.61 +      op.u.net_rule.dst_interface = anton(&buffer[ts], tl);
   13.62      }
   13.63      else if ( (strncmp(&buffer[fs], "proto", fl) == 0))
   13.64      {
   13.65 -      if (strncmp(&buffer[ts], "ip", tl))
   13.66 +      if (strncmp(&buffer[ts], "any", tl) == 0)
   13.67 +          op.u.net_rule.proto = NETWORK_PROTO_ANY;
   13.68 +      if (strncmp(&buffer[ts], "ip", tl) == 0)
   13.69  	  op.u.net_rule.proto = NETWORK_PROTO_IP;
   13.70 -      if (strncmp(&buffer[ts], "tcp", tl))
   13.71 +      if (strncmp(&buffer[ts], "tcp", tl) == 0) 
   13.72  	  op.u.net_rule.proto = NETWORK_PROTO_TCP;
   13.73 -      if (strncmp(&buffer[ts], "udp", tl))
   13.74 +      if (strncmp(&buffer[ts], "udp", tl) == 0)
   13.75  	  op.u.net_rule.proto = NETWORK_PROTO_UDP;
   13.76 -      if (strncmp(&buffer[ts], "arp", tl))
   13.77 +      if (strncmp(&buffer[ts], "arp", tl) == 0)
   13.78  	  op.u.net_rule.proto = NETWORK_PROTO_ARP;
   13.79        
   13.80      }
   13.81 @@ -225,9 +228,31 @@ module_exit(cleanup_module);
   13.82  
   13.83  /* Helper functions start here: */
   13.84  
   13.85 +int anton(const char *buff, int len)
   13.86 +{
   13.87 +    int ret;
   13.88 +    char c;
   13.89 +    int sign = 1;
   13.90 +    
   13.91 +    ret = 0;
   13.92 +
   13.93 +    if (len == 0) return 0;
   13.94 +    if (*buff == '-') { sign = -1; buff++; len--; }
   13.95 +
   13.96 +    while ( (len) && ((c = *buff) >= '0') && (c <= '9') )
   13.97 +    {
   13.98 +        ret *= 10;
   13.99 +        ret += c - '0';
  13.100 +        buff++; len--;
  13.101 +    }
  13.102 +
  13.103 +    ret *= sign;
  13.104 +    return ret;
  13.105 +}
  13.106 +    
  13.107  u16 antous(const char *buff, int len)
  13.108  {
  13.109 -  int ret;
  13.110 +  u16 ret;
  13.111    char c;
  13.112  
  13.113    ret = 0;
    14.1 --- a/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c	Fri Dec 06 11:40:56 2002 +0000
    14.2 +++ b/xenolinux-2.4.16-sparse/arch/xeno/drivers/network/network.c	Fri Dec 06 14:20:10 2002 +0000
    14.3 @@ -20,12 +20,16 @@
    14.4  #include <linux/etherdevice.h>
    14.5  #include <linux/skbuff.h>
    14.6  #include <linux/init.h>
    14.7 +#include <linux/ip.h> //remove this.
    14.8  
    14.9  #include <net/sock.h>
   14.10  
   14.11  #define NET_TX_IRQ _EVENT_NET_TX
   14.12  #define NET_RX_IRQ _EVENT_NET_RX
   14.13  
   14.14 +#define NET_TX_IRQ_FOR_VIF(x) _EVENT_NET_TX_FOR_VIF(x)
   14.15 +#define NET_RX_IRQ_FOR_VIF(x) _EVENT_NET_RX_FOR_VIF(x)
   14.16 +
   14.17  #define TX_MAX_ENTRIES (TX_RING_SIZE - 2)
   14.18  #define RX_MAX_ENTRIES (RX_RING_SIZE - 2)
   14.19  
   14.20 @@ -62,6 +66,7 @@ struct net_private
   14.21      unsigned int rx_idx, tx_idx, tx_full;
   14.22      net_ring_t *net_ring;
   14.23      spinlock_t tx_lock;
   14.24 +    unsigned int id;
   14.25  };
   14.26  
   14.27   
   14.28 @@ -69,7 +74,15 @@ static int network_open(struct net_devic
   14.29  {
   14.30      struct net_private *np = dev->priv;
   14.31      int error;
   14.32 +    char *rxlabel, *txlabel;
   14.33  
   14.34 +    // This is inevitably not the right way to allocate a couple of static strings.
   14.35 +    rxlabel = kmalloc(sizeof("net-rx- "), GFP_KERNEL);
   14.36 +    txlabel = kmalloc(sizeof("net-tx- "), GFP_KERNEL);
   14.37 +    if ((rxlabel == NULL) || (txlabel == NULL)) goto fail;
   14.38 +    sprintf(rxlabel, "net-rx-%d", np->id);
   14.39 +    sprintf(txlabel, "net-tx-%d", np->id);
   14.40 +    
   14.41      np->rx_idx = np->tx_idx = np->tx_full = 0;
   14.42  
   14.43      memset(&np->stats, 0, sizeof(np->stats));
   14.44 @@ -101,7 +114,8 @@ static int network_open(struct net_devic
   14.45  
   14.46      network_alloc_rx_buffers(dev);
   14.47  
   14.48 -    error = request_irq(NET_RX_IRQ, network_rx_int, 0, "net-rx", dev);
   14.49 +    error = request_irq(NET_RX_IRQ_FOR_VIF(np->id), network_rx_int, 0, 
   14.50 +                    rxlabel, dev);
   14.51      if ( error )
   14.52      {
   14.53          printk(KERN_WARNING "%s: Could not allocate receive interrupt\n",
   14.54 @@ -109,12 +123,13 @@ static int network_open(struct net_devic
   14.55          goto fail;
   14.56      }
   14.57  
   14.58 -    error = request_irq(NET_TX_IRQ, network_tx_int, 0, "net-tx", dev);
   14.59 +    error = request_irq(NET_TX_IRQ_FOR_VIF(np->id), network_tx_int, 0, 
   14.60 +                    txlabel, dev);
   14.61      if ( error )
   14.62      {
   14.63          printk(KERN_WARNING "%s: Could not allocate transmit interrupt\n",
   14.64                 dev->name);
   14.65 -        free_irq(NET_RX_IRQ, dev);
   14.66 +        free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
   14.67          goto fail;
   14.68      }
   14.69  
   14.70 @@ -127,6 +142,8 @@ static int network_open(struct net_devic
   14.71      return 0;
   14.72  
   14.73   fail:
   14.74 +    if ( rxlabel ) kfree(rxlabel);
   14.75 +    if ( txlabel ) kfree(txlabel);
   14.76      if ( np->net_ring->rx_ring ) kfree(np->net_ring->rx_ring);
   14.77      if ( np->net_ring->tx_ring ) kfree(np->net_ring->tx_ring);
   14.78      if ( np->rx_skb_ring ) kfree(np->rx_skb_ring);
   14.79 @@ -208,7 +225,12 @@ static int network_start_xmit(struct sk_
   14.80  {
   14.81      unsigned int i;
   14.82      struct net_private *np = (struct net_private *)dev->priv;
   14.83 -
   14.84 +    
   14.85 +if ((np->id > 0) || ((skb->len > 20) 
   14.86 +                && (skb->nh.iph != NULL) 
   14.87 +                && (skb->nh.iph->protocol == 1)))
   14.88 +    printk(KERN_WARNING "TX on vif %d (dev:%p)\n", np->id, dev);
   14.89 +    
   14.90      if ( np->tx_full )
   14.91      {
   14.92          printk(KERN_WARNING "%s: full queue wasn't stopped!\n", dev->name);
   14.93 @@ -265,8 +287,17 @@ static void network_rx_int(int irq, void
   14.94          skb->protocol = eth_type_trans(skb, dev);
   14.95          np->stats.rx_packets++;
   14.96          np->stats.rx_bytes += np->net_ring->rx_ring[i].size;
   14.97 +
   14.98 +if (((skb->len > 20)
   14.99 +    && ((*(unsigned char *)(skb->data + 9) == 1) || (np->id > 0)) ))
  14.100 +    printk(KERN_WARNING "RX on vif %d (dev:%p)\n", np->id, dev);
  14.101 +if ((skb != NULL) && (skb->data != NULL) && (skb->len > 20) && ntohl(*(unsigned long *)(skb->data + 16)) == 167903489)
  14.102 +    printk(KERN_WARNING "RX INT (driver): pkt_type is %d.!", skb->pkt_type);
  14.103 +
  14.104          netif_rx(skb);
  14.105          dev->last_rx = jiffies;
  14.106 +                
  14.107 +
  14.108      }
  14.109  
  14.110      np->rx_idx = i;
  14.111 @@ -275,7 +306,10 @@ static void network_rx_int(int irq, void
  14.112      
  14.113      /* Deal with hypervisor racing our resetting of rx_event. */
  14.114      smp_mb();
  14.115 -    if ( np->net_ring->rx_cons != i ) goto again;
  14.116 +    if ( np->net_ring->rx_cons != i ) { 
  14.117 +//printk("redoing network rx...\n"); 
  14.118 +                goto again;
  14.119 +        }
  14.120  }
  14.121  
  14.122  
  14.123 @@ -286,13 +320,13 @@ static void network_tx_int(int irq, void
  14.124  }
  14.125  
  14.126  
  14.127 -static int network_close(struct net_device *dev)
  14.128 +int network_close(struct net_device *dev)
  14.129  {
  14.130      struct net_private *np = dev->priv;
  14.131  
  14.132      netif_stop_queue(dev);
  14.133 -    free_irq(NET_RX_IRQ, dev);
  14.134 -    free_irq(NET_TX_IRQ, dev);
  14.135 +    free_irq(NET_RX_IRQ_FOR_VIF(np->id), dev);
  14.136 +    free_irq(NET_TX_IRQ_FOR_VIF(np->id), dev);
  14.137      network_free_rx_buffers(dev);
  14.138      kfree(np->net_ring->rx_ring);
  14.139      kfree(np->net_ring->tx_ring);
  14.140 @@ -310,7 +344,7 @@ static struct net_device_stats *network_
  14.141  }
  14.142  
  14.143  
  14.144 -static int __init init_module(void)
  14.145 +int __init init_module(void)
  14.146  {
  14.147      int i, err;
  14.148      struct net_device *dev;
  14.149 @@ -336,6 +370,9 @@ static int __init init_module(void)
  14.150          dev->stop            = network_close;
  14.151          dev->get_stats       = network_get_stats;
  14.152  
  14.153 +        memset(dev->dev_addr, 0, ETH_ALEN);
  14.154 +        *(unsigned int *)(dev->dev_addr) = i;
  14.155 +
  14.156          if ( (err = register_netdev(dev)) != 0 )
  14.157          {
  14.158              kfree(dev);
  14.159 @@ -343,7 +380,9 @@ static int __init init_module(void)
  14.160          }
  14.161  
  14.162          np->dev = dev;
  14.163 +        np->id = i;
  14.164          list_add(&np->list, &dev_list);
  14.165 +printk(KERN_WARNING "Added VIF, ifindex is %d.\n", dev->ifindex);
  14.166      }
  14.167  
  14.168      return 0;
    15.1 --- a/xenolinux-2.4.16-sparse/include/asm-xeno/irq.h	Fri Dec 06 11:40:56 2002 +0000
    15.2 +++ b/xenolinux-2.4.16-sparse/include/asm-xeno/irq.h	Fri Dec 06 14:20:10 2002 +0000
    15.3 @@ -16,6 +16,8 @@
    15.4  
    15.5  #define NET_TX_IRQ  _EVENT_NET_TX
    15.6  #define NET_RX_IRQ  _EVENT_NET_RX
    15.7 +#define NET2_TX_IRQ  _EVENT_NET2_TX
    15.8 +#define NET2_RX_IRQ  _EVENT_NET2_RX
    15.9  #define TIMER_IRQ   _EVENT_TIMER
   15.10  
   15.11  #define NR_IRQS (sizeof(HYPERVISOR_shared_info->events) * 8)