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.
This commit is contained in:
kaf24@scramble.cl.cam.ac.uk committed 2003-05-13 11:31:46 +00:00
1 parent 4cb5c054fc
commit 08874b8ef4
4 files changed
+115 -17

No files matched your search

+11 -9
View File
@@ -40,21 +40,23 @@ unsigned int opt_ser_baud = 9600; /* default baud for COM1 */
unsigned int opt_dom0_mem = 16000; /* default kbytes for DOM0 */
unsigned int opt_ne_base = 0; /* NE2k NICs cannot be probed */
unsigned char opt_ifname[10] = "eth0";
int opt_noht=0, opt_noacpi=0, opt_nosmp;
int opt_noht=0, opt_noacpi=0, opt_nosmp=0;
int opt_phys_bootmac=0; /* Is DOM0/VIF0 allocated the physical MAC address? */
enum { OPT_IP, OPT_STR, OPT_UINT, OPT_BOOL };
static struct {
unsigned char *name;
int type;
void *var;
} opts[] = {
{ "console", OPT_UINT, &opt_console },
{ "ser_baud", OPT_UINT, &opt_ser_baud },
{ "dom0_mem", OPT_UINT, &opt_dom0_mem },
{ "ne_base", OPT_UINT, &opt_ne_base },
{ "ifname", OPT_STR, &opt_ifname },
{ "noht", OPT_BOOL, &opt_noht },
{ "noacpi", OPT_BOOL, &opt_noacpi },
{ "nosmp", OPT_BOOL, &opt_nosmp },
{ "console", OPT_UINT, &opt_console },
{ "ser_baud", OPT_UINT, &opt_ser_baud },
{ "dom0_mem", OPT_UINT, &opt_dom0_mem },
{ "ne_base", OPT_UINT, &opt_ne_base },
{ "ifname", OPT_STR, &opt_ifname },
{ "noht", OPT_BOOL, &opt_noht },
{ "noacpi", OPT_BOOL, &opt_noacpi },
{ "nosmp", OPT_BOOL, &opt_nosmp },
{ "phys_bootmac", OPT_BOOL, &opt_phys_bootmac },
{ NULL, 0, NULL }
};
+64
View File
@@ -525,3 +525,67 @@ __udivdi3(a, b)
return (__qdivrem(a, b, (u64 *)0));
}
/* HASH/RANDOMISATION FUNCTION
* Based on lookup2.c, by Bob Jenkins, December 1996, Public Domain.
* You can use this free for any purpose. It has no warranty.
* See http://burlteburtle.net/bob/hash/evahash.html
*/
typedef unsigned long ub4;
#define mix(a,b,c) \
do { \
a -= b; a -= c; a ^= (c>>13); \
b -= c; b -= a; b ^= (a<< 8); \
c -= a; c -= b; c ^= ((b&0xffffffff)>>13); \
a -= b; a -= c; a ^= ((c&0xffffffff)>>12); \
b -= c; b -= a; b = (b ^ (a<<16)) & 0xffffffff; \
c -= a; c -= b; c = (c ^ (b>> 5)) & 0xffffffff; \
a -= b; a -= c; a = (a ^ (c>> 3)) & 0xffffffff; \
b -= c; b -= a; b = (b ^ (a<<10)) & 0xffffffff; \
c -= a; c -= b; c = (c ^ (b>>15)) & 0xffffffff; \
} while ( 0 )
unsigned long hash(unsigned char *k, unsigned long len)
{
unsigned long a, b, c, l;
l = len;
a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
c = 0xa5a5a5a5; /* another arbitrary value (KAF, 13/5/03) */
while ( l >= 12 )
{
a += (k[0] + ((ub4)k[1]<<8) + ((ub4)k[2]<<16) + ((ub4)k[3]<<24));
b += (k[4] + ((ub4)k[5]<<8) + ((ub4)k[6]<<16) + ((ub4)k[7]<<24));
c += (k[8] + ((ub4)k[9]<<8) + ((ub4)k[10]<<16) + ((ub4)k[11]<<24));
mix(a,b,c);
k += 12; l -= 12;
}
c += len;
switch ( l )
{
case 11: c+=((ub4)k[10]<<24);
case 10: c+=((ub4)k[9]<<16);
case 9 : c+=((ub4)k[8]<<8);
/* the first byte of c is reserved for the length */
case 8 : b+=((ub4)k[7]<<24);
case 7 : b+=((ub4)k[6]<<16);
case 6 : b+=((ub4)k[5]<<8);
case 5 : b+=k[4];
case 4 : a+=((ub4)k[3]<<24);
case 3 : a+=((ub4)k[2]<<16);
case 2 : a+=((ub4)k[1]<<8);
case 1 : a+=k[0];
/* case 0: nothing left to add */
}
mix(a,b,c);
return c;
}
+37 -8
View File
@@ -69,7 +69,9 @@ net_vif_t *create_net_vif(int domain)
net_vif_t *new_vif = NULL;
net_ring_t *new_ring = NULL;
struct task_struct *p = NULL;
unsigned long flags;
unsigned long flags, vmac_hash;
unsigned char vmac_key[ETH_ALEN + 4 + 2];
extern int opt_phys_bootmac;
if ( !(p = find_domain_by_id(domain)) )
return NULL;
@@ -104,13 +106,40 @@ net_vif_t *create_net_vif(int domain)
spin_lock_init(&new_vif->rx_lock);
spin_lock_init(&new_vif->tx_lock);
/*
* Virtual MAC is a hash of the real physical MAC. Chosen so that the
* first vif of domain 0 gets the physical MAC address.
*/
memcpy(new_vif->vmac, the_dev->dev_addr, ETH_ALEN);
((unsigned short *)new_vif->vmac)[1] ^= htons(p->domain);
((unsigned short *)new_vif->vmac)[2] ^= htons(dom_vif_idx);
if ( opt_phys_bootmac && (p->domain == 0) && (dom_vif_idx == 0) )
{
/*
* DOM0/VIF0 may get the real physical MAC address, so that
* users can easily get a Xenoserver up and running by using an
* existing DHCP entry.
*/
memcpy(new_vif->vmac, the_dev->dev_addr, ETH_ALEN);
}
else
{
/*
* Most VIFs get a random MAC address with a "special" vendor id.
* We try to get MAC addresses to be unique across multiple servers
* by including the physical MAC address in the hash.
* However, the same machine with the same dom_id and vif_id should
* always get the same virtual MAC address.
*
* NB. The vendor is currently an "obsolete" one that used to belong
* to DEC (AA-00-00). Using it is probably a bit rude :-)
*
* NB2. The first bit of the first random octet is set to zero for
* all dynamic MAC addresses. This may allow us to manually specify
* MAC addresses for some VIFs with no fear of clashes.
*/
memcpy(&vmac_key[0], the_dev->dev_addr, ETH_ALEN);
*(__u32 *)(&vmac_key[ETH_ALEN+0]) = htonl(p->domain);
*(__u16 *)(&vmac_key[ETH_ALEN+4]) = htons(dom_vif_idx);
vmac_hash = hash(vmac_key, ETH_ALEN+4+2);
memcpy(new_vif->vmac, "\xaa\x00\x00", 3);
new_vif->vmac[3] = (vmac_hash >> 16) & 0xef; /* First bit is zero. */
new_vif->vmac[4] = (vmac_hash >> 8) & 0xff;
new_vif->vmac[5] = (vmac_hash >> 0) & 0xff;
}
p->net_vif_list[dom_vif_idx] = new_vif;
+3
View File
@@ -54,4 +54,7 @@ long simple_strtol(const char *cp,char **endp,unsigned int base);
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base);
long long simple_strtoll(const char *cp,char **endp,unsigned int base);
/* Produce a 32-bit hash from a key string 'k' of length 'len' bytes. */
unsigned long hash(unsigned char *k, unsigned long len);
#endif /* __LIB_H__ */
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.