direct-io.hg

changeset 444:5c7227b5427c

bitkeeper revision 1.225 (3ec0d7a2BpgJXl0j-8Y1KilL1argzw)

lib.h, network.c, lib.c, kernel.c:
A better method for calculating virtual MAC addresses. Dom0/VIF0 (the boot VIF) can be forced to use the physical MAC address by specifying 'phys_bootmac' on Xen's command line.
author kaf24@scramble.cl.cam.ac.uk
date Tue May 13 11:31:46 2003 +0000 (2003-05-13)
parents 67bf82322cc1
children 53f6ba7cee5d
files xen/common/kernel.c xen/common/lib.c xen/common/network.c xen/include/xeno/lib.h
line diff
     1.1 --- a/xen/common/kernel.c	Sun May 11 11:06:23 2003 +0000
     1.2 +++ b/xen/common/kernel.c	Tue May 13 11:31:46 2003 +0000
     1.3 @@ -40,21 +40,23 @@ unsigned int opt_ser_baud = 9600;  /* de
     1.4  unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */
     1.5  unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */
     1.6  unsigned char opt_ifname[10] = "eth0";
     1.7 -int opt_noht=0, opt_noacpi=0, opt_nosmp;
     1.8 +int opt_noht=0, opt_noacpi=0, opt_nosmp=0;
     1.9 +int opt_phys_bootmac=0; /* Is DOM0/VIF0 allocated the physical MAC address? */
    1.10  enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL };
    1.11  static struct {
    1.12      unsigned char *name;
    1.13      int type;
    1.14      void *var;
    1.15  } opts[] = {
    1.16 -    { "console",  OPT_UINT, &opt_console },
    1.17 -    { "ser_baud", OPT_UINT, &opt_ser_baud },
    1.18 -    { "dom0_mem", OPT_UINT, &opt_dom0_mem }, 
    1.19 -    { "ne_base",  OPT_UINT, &opt_ne_base },
    1.20 -    { "ifname",   OPT_STR,  &opt_ifname },
    1.21 -    { "noht",     OPT_BOOL, &opt_noht },
    1.22 -    { "noacpi",   OPT_BOOL, &opt_noacpi },
    1.23 -    { "nosmp",    OPT_BOOL, &opt_nosmp },
    1.24 +    { "console",      OPT_UINT, &opt_console },
    1.25 +    { "ser_baud",     OPT_UINT, &opt_ser_baud },
    1.26 +    { "dom0_mem",     OPT_UINT, &opt_dom0_mem }, 
    1.27 +    { "ne_base",      OPT_UINT, &opt_ne_base },
    1.28 +    { "ifname",       OPT_STR,  &opt_ifname },
    1.29 +    { "noht",         OPT_BOOL, &opt_noht },
    1.30 +    { "noacpi",       OPT_BOOL, &opt_noacpi },
    1.31 +    { "nosmp",        OPT_BOOL, &opt_nosmp },
    1.32 +    { "phys_bootmac", OPT_BOOL, &opt_phys_bootmac },
    1.33      { NULL,       0,        NULL     }
    1.34  };
    1.35  
     2.1 --- a/xen/common/lib.c	Sun May 11 11:06:23 2003 +0000
     2.2 +++ b/xen/common/lib.c	Tue May 13 11:31:46 2003 +0000
     2.3 @@ -525,3 +525,67 @@ u64
     2.4  
     2.5          return (__qdivrem(a, b, (u64 *)0));
     2.6  }
     2.7 +
     2.8 +
     2.9 +
    2.10 +
    2.11 +/* HASH/RANDOMISATION FUNCTION
    2.12 + * Based on lookup2.c, by Bob Jenkins, December 1996, Public Domain.
    2.13 + * You can use this free for any purpose.  It has no warranty.
    2.14 + * See http://burlteburtle.net/bob/hash/evahash.html 
    2.15 + */
    2.16 +
    2.17 +typedef unsigned long ub4;
    2.18 +
    2.19 +#define mix(a,b,c)                                      \
    2.20 +    do {                                                \
    2.21 +        a -= b; a -= c; a ^= (c>>13);                   \
    2.22 +        b -= c; b -= a; b ^= (a<< 8);                   \
    2.23 +        c -= a; c -= b; c ^= ((b&0xffffffff)>>13);      \
    2.24 +        a -= b; a -= c; a ^= ((c&0xffffffff)>>12);      \
    2.25 +        b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
    2.26 +        c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
    2.27 +        a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
    2.28 +        b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
    2.29 +        c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
    2.30 +    } while ( 0 )
    2.31 +
    2.32 +unsigned long hash(unsigned char *k, unsigned long len)
    2.33 +{
    2.34 +    unsigned long a, b, c, l;
    2.35 +
    2.36 +    l = len;
    2.37 +    a = b = 0x9e3779b9;  /* the golden ratio; an arbitrary value */
    2.38 +    c = 0xa5a5a5a5;      /* another arbitrary value (KAF, 13/5/03) */
    2.39 +
    2.40 +    while ( l >= 12 )
    2.41 +    {
    2.42 +        a += (k[0] + ((ub4)k[1]<<8) + ((ub4)k[2]<<16)  + ((ub4)k[3]<<24));
    2.43 +        b += (k[4] + ((ub4)k[5]<<8) + ((ub4)k[6]<<16)  + ((ub4)k[7]<<24));
    2.44 +        c += (k[8] + ((ub4)k[9]<<8) + ((ub4)k[10]<<16) + ((ub4)k[11]<<24));
    2.45 +        mix(a,b,c);
    2.46 +        k += 12; l -= 12;
    2.47 +    }
    2.48 +
    2.49 +    c += len;
    2.50 +    switch ( l )
    2.51 +    {
    2.52 +    case 11: c+=((ub4)k[10]<<24);
    2.53 +    case 10: c+=((ub4)k[9]<<16);
    2.54 +    case 9 : c+=((ub4)k[8]<<8);
    2.55 +        /* the first byte of c is reserved for the length */
    2.56 +    case 8 : b+=((ub4)k[7]<<24);
    2.57 +    case 7 : b+=((ub4)k[6]<<16);
    2.58 +    case 6 : b+=((ub4)k[5]<<8);
    2.59 +    case 5 : b+=k[4];
    2.60 +    case 4 : a+=((ub4)k[3]<<24);
    2.61 +    case 3 : a+=((ub4)k[2]<<16);
    2.62 +    case 2 : a+=((ub4)k[1]<<8);
    2.63 +    case 1 : a+=k[0];
    2.64 +        /* case 0: nothing left to add */
    2.65 +    }
    2.66 +
    2.67 +    mix(a,b,c);
    2.68 +
    2.69 +    return c;
    2.70 +}
     3.1 --- a/xen/common/network.c	Sun May 11 11:06:23 2003 +0000
     3.2 +++ b/xen/common/network.c	Tue May 13 11:31:46 2003 +0000
     3.3 @@ -69,7 +69,9 @@ net_vif_t *create_net_vif(int domain)
     3.4      net_vif_t *new_vif = NULL;
     3.5      net_ring_t *new_ring = NULL;
     3.6      struct task_struct *p = NULL;
     3.7 -    unsigned long flags;
     3.8 +    unsigned long flags, vmac_hash;
     3.9 +    unsigned char vmac_key[ETH_ALEN + 4 + 2];
    3.10 +    extern int opt_phys_bootmac;
    3.11  
    3.12      if ( !(p = find_domain_by_id(domain)) )
    3.13          return NULL;
    3.14 @@ -104,13 +106,40 @@ net_vif_t *create_net_vif(int domain)
    3.15      spin_lock_init(&new_vif->rx_lock);
    3.16      spin_lock_init(&new_vif->tx_lock);
    3.17  
    3.18 -    /*
    3.19 -     * Virtual MAC is a hash of the real physical MAC. Chosen so that the 
    3.20 -     * first vif of domain 0 gets the physical MAC address.
    3.21 -     */
    3.22 -    memcpy(new_vif->vmac, the_dev->dev_addr, ETH_ALEN);
    3.23 -    ((unsigned short *)new_vif->vmac)[1] ^= htons(p->domain);
    3.24 -    ((unsigned short *)new_vif->vmac)[2] ^= htons(dom_vif_idx);
    3.25 +    if ( opt_phys_bootmac && (p->domain == 0) && (dom_vif_idx == 0) )
    3.26 +    {
    3.27 +        /*
    3.28 +         * DOM0/VIF0 may get the real physical MAC address, so that
    3.29 +         * users can easily get a Xenoserver up and running by using an
    3.30 +         * existing DHCP entry.
    3.31 +         */
    3.32 +        memcpy(new_vif->vmac, the_dev->dev_addr, ETH_ALEN);
    3.33 +    }
    3.34 +    else
    3.35 +    {
    3.36 +        /*
    3.37 +         * Most VIFs get a random MAC address with a "special" vendor id.
    3.38 +         * We try to get MAC addresses to be unique across multiple servers
    3.39 +         * by including the physical MAC address in the hash.
    3.40 +         * However, the same machine with the same dom_id and vif_id should
    3.41 +         * always get the same virtual MAC address.
    3.42 +         * 
    3.43 +         * NB. The vendor is currently an "obsolete" one that used to belong
    3.44 +         * to DEC (AA-00-00). Using it is probably a bit rude :-)
    3.45 +         * 
    3.46 +         * NB2. The first bit of the first random octet is set to zero for
    3.47 +         * all dynamic MAC addresses. This may allow us to manually specify
    3.48 +         * MAC addresses for some VIFs with no fear of clashes.
    3.49 +         */
    3.50 +        memcpy(&vmac_key[0], the_dev->dev_addr, ETH_ALEN);
    3.51 +        *(__u32 *)(&vmac_key[ETH_ALEN+0]) = htonl(p->domain);
    3.52 +        *(__u16 *)(&vmac_key[ETH_ALEN+4]) = htons(dom_vif_idx);
    3.53 +        vmac_hash = hash(vmac_key, ETH_ALEN+4+2);
    3.54 +        memcpy(new_vif->vmac, "\xaa\x00\x00", 3);
    3.55 +        new_vif->vmac[3] = (vmac_hash >> 16) & 0xef; /* First bit is zero. */
    3.56 +        new_vif->vmac[4] = (vmac_hash >>  8) & 0xff;
    3.57 +        new_vif->vmac[5] = (vmac_hash >>  0) & 0xff;
    3.58 +    }
    3.59  
    3.60      p->net_vif_list[dom_vif_idx] = new_vif;
    3.61      
     4.1 --- a/xen/include/xeno/lib.h	Sun May 11 11:06:23 2003 +0000
     4.2 +++ b/xen/include/xeno/lib.h	Tue May 13 11:31:46 2003 +0000
     4.3 @@ -54,4 +54,7 @@ long simple_strtol(const char *cp,char *
     4.4  unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
     4.5  long long simple_strtoll(const char *cp,char **endp,unsigned int base);
     4.6  
     4.7 +/* Produce a 32-bit hash from a key string 'k' of length 'len' bytes. */
     4.8 +unsigned long hash(unsigned char *k, unsigned long len);
     4.9 +
    4.10  #endif /* __LIB_H__ */