aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-29 15:47:27 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-29 15:47:27 +0000
commit455321c2002fc070889c89f935ec851baa85c60a (patch)
tree66590ae4047cf11fa4f4d5922a21d8530d6ea9b7
parent4e45e54f52b94877c954fa96c2e878398ac1118b (diff)
downloadxen-455321c2002fc070889c89f935ec851baa85c60a.tar.gz
xen-455321c2002fc070889c89f935ec851baa85c60a.tar.bz2
xen-455321c2002fc070889c89f935ec851baa85c60a.zip
bitkeeper revision 1.193 (3eae9e8fDbEyBEL7yKPAlkULZMIM4g)
network.c, dev.c, vif.h, hypervisor-if.h, kernel.c, domain.c: Allow DHCP from domain-0 Xenolinux. Link-local IP addresses are now allocated consecutively from 169.254.1.0.
-rw-r--r--xen/common/domain.c4
-rw-r--r--xen/common/kernel.c5
-rw-r--r--xen/common/network.c26
-rw-r--r--xen/include/hypervisor-ifs/hypervisor-if.h1
-rw-r--r--xen/include/xeno/vif.h5
-rw-r--r--xen/net/dev.c10
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c40
7 files changed, 53 insertions, 38 deletions
diff --git a/xen/common/domain.c b/xen/common/domain.c
index 349acc5b57..0542743341 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -377,6 +377,8 @@ int final_setup_guestos(struct task_struct * p, dom_meminfo_t * meminfo)
if ( p->net_vif_list[i] == NULL ) continue;
virt_startinfo_addr->net_rings[i] =
virt_to_phys(p->net_vif_list[i]->shared_rings);
+ memcpy(virt_startinfo_addr->net_vmac[i],
+ p->net_vif_list[i]->vmac, ETH_ALEN);
}
/* Add block io interface */
@@ -645,6 +647,8 @@ int setup_guestos(struct task_struct *p, dom0_newdomain_t *params,
if ( p->net_vif_list[i] == NULL ) continue;
virt_startinfo_address->net_rings[i] =
virt_to_phys(p->net_vif_list[i]->shared_rings);
+ memcpy(virt_startinfo_address->net_vmac[i],
+ p->net_vif_list[i]->vmac, ETH_ALEN);
}
/* Add block io interface */
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 67602c1139..6e92cfefc7 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -424,7 +424,6 @@ unsigned short compute_cksum(unsigned short *buf, int count)
/* XXX SMH: below is rather vile; pulled in to allow network console */
extern int netif_rx(struct sk_buff *);
-extern struct net_device *the_dev;
typedef struct my_udphdr {
__u16 source;
@@ -499,8 +498,8 @@ int console_export(char *str, int len)
iph->id = 0xdead;
iph->ttl = 255;
iph->protocol= 17;
- iph->daddr = htonl(0xa9fe0001); /* 169.254.0.1 */
- iph->saddr = htonl(0xa9fe0001); /* 169.254.0.1 */
+ iph->daddr = htonl(0xa9fe0100); /* 169.254.1.0 */
+ iph->saddr = htonl(0xa9fe0100); /* 169.254.1.0 */
iph->tot_len = htons(hdr_size + len);
iph->check = 0;
iph->check = compute_cksum((__u16 *)iph, sizeof(struct my_iphdr)/2);
diff --git a/xen/common/network.c b/xen/common/network.c
index 80d27e7bd6..f7c5f3b7c2 100644
--- a/xen/common/network.c
+++ b/xen/common/network.c
@@ -104,6 +104,14 @@ 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);
+
p->net_vif_list[dom_vif_idx] = new_vif;
write_unlock_irqrestore(&tasklist_lock, flags);
@@ -496,8 +504,6 @@ long do_network_op(network_op_t *u_network_op)
void __init net_init (void)
{
- net_rule_t new_rule;
-
net_rule_list = NULL;
net_vif_cache = kmem_cache_create("net_vif_cache",
sizeof(net_vif_t),
@@ -505,20 +511,4 @@ void __init net_init (void)
net_rule_cache = kmem_cache_create("net_rule_cache",
sizeof(net_rule_ent_t),
0, SLAB_HWCACHE_ALIGN, NULL, NULL);
-
- /* Bootstrap outbound rule. */
- memset(&new_rule, 0, sizeof(net_rule_t));
- new_rule.src_vif = 0;
- new_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
- new_rule.action = NETWORK_ACTION_ACCEPT;
- new_rule.proto = NETWORK_PROTO_ANY;
- add_net_rule(&new_rule);
-
- /* Bootstrap inbound rule. */
- memset(&new_rule, 0, sizeof(net_rule_t));
- new_rule.src_vif = VIF_ANY_INTERFACE;
- new_rule.dst_vif = 0;
- new_rule.action = NETWORK_ACTION_ACCEPT;
- new_rule.proto = NETWORK_PROTO_ANY;
- add_net_rule(&new_rule);
}
diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h
index 6b74f92b66..6a4c6b817c 100644
--- a/xen/include/hypervisor-ifs/hypervisor-if.h
+++ b/xen/include/hypervisor-ifs/hypervisor-if.h
@@ -241,6 +241,7 @@ typedef struct start_info_st {
unsigned long mod_len; /* size (bytes) of pre-loaded module */
/* Machine address of net rings for each VIF. Will be page aligned. */
unsigned long net_rings[MAX_DOMAIN_VIFS];
+ unsigned char net_vmac[MAX_DOMAIN_VIFS][6];
/* Machine address of block-device ring. Will be page aligned. */
unsigned long blk_ring;
unsigned int dom_id;
diff --git a/xen/include/xeno/vif.h b/xen/include/xeno/vif.h
index 4fb2e275d1..6cc339cbd9 100644
--- a/xen/include/xeno/vif.h
+++ b/xen/include/xeno/vif.h
@@ -20,6 +20,10 @@
#include <hypervisor-ifs/network.h>
+#include <xeno/if_ether.h>
+
+extern struct net_device *the_dev;
+
/*
* shadow ring structures are used to protect the descriptors from
* tampering after they have been passed to the hypervisor.
@@ -69,6 +73,7 @@ typedef struct net_vif_st {
struct list_head list; /* scheduling list */
atomic_t refcnt;
spinlock_t rx_lock, tx_lock;
+ unsigned char vmac[ETH_ALEN];
} net_vif_t;
#define get_vif(_v) (atomic_inc(&(_v)->refcnt))
diff --git a/xen/net/dev.c b/xen/net/dev.c
index 87144aa162..0f36344e74 100644
--- a/xen/net/dev.c
+++ b/xen/net/dev.c
@@ -500,9 +500,9 @@ void deliver_packet(struct sk_buff *skb, net_vif_t *vif)
unsigned short size;
unsigned char offset, status = RING_STATUS_OK;
- memset(skb->mac.ethernet->h_dest, 0, ETH_ALEN);
+ memcpy(skb->mac.ethernet->h_dest, vif->vmac, ETH_ALEN);
if ( ntohs(skb->mac.ethernet->h_proto) == ETH_P_ARP )
- memset(skb->nh.raw + 18, 0, ETH_ALEN);
+ memcpy(skb->nh.raw + 18, vif->vmac, ETH_ALEN);
if ( (i = vif->rx_cons) == vif->rx_prod )
return;
@@ -741,7 +741,7 @@ static void net_tx_action(unsigned long unused)
add_to_net_schedule_list_tail(vif);
skb->destructor = tx_skb_release;
-
+
skb->head = skb->data = tx->header;
skb->end = skb->tail = skb->head + PKT_PROT_LEN;
@@ -1728,7 +1728,7 @@ inline int init_tx_header(u8 *data, unsigned int len, struct net_device *dev)
{
case ETH_P_ARP:
if ( len < 42 ) break;
- memcpy(data + 22, dev->dev_addr, 6);
+ memcpy(data + 22, dev->dev_addr, ETH_ALEN);
return ETH_P_ARP;
case ETH_P_IP:
return ETH_P_IP;
@@ -1939,7 +1939,7 @@ long do_net_update(void)
(PGT_writeable_page | current->domain)) ||
(buf_page->tot_count != 1) )
{
- DPRINTK("Need a mapped-once writeable page (%d/%d/%08x)\n",
+ DPRINTK("Need a mapped-once writeable page (%ld/%ld/%08lx)\n",
buf_page->type_count, buf_page->tot_count, buf_page->flags);
make_rx_response(vif, rx.id, 0, RING_STATUS_BAD_PAGE, 0);
goto rx_unmap_and_continue;
diff --git a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
index 7cf0fecbec..a125695e54 100644
--- a/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
+++ b/xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c
@@ -470,9 +470,9 @@ static int inetdev_notify(struct notifier_block *this,
(void)HYPERVISOR_network_op(&op);
/*
- * Xen creates a pair of bootstrap rules which allows domain 0 to
- * send and receive any packet. These rules can be removed once we
- * have configured an IP address.
+ * When the first real interface is brought up we delete the start-of-day
+ * bootstrap rules -- they were only installed to allow an initial DHCP
+ * request and response.
*/
if ( (idx == 0) && (event == NETDEV_UP) && !removed_bootstrap_rules )
{
@@ -480,11 +480,9 @@ static int inetdev_notify(struct notifier_block *this,
op.cmd = NETWORK_OP_DELETERULE;
op.u.net_rule.proto = NETWORK_PROTO_ANY;
op.u.net_rule.action = NETWORK_ACTION_ACCEPT;
-
op.u.net_rule.src_vif = 0;
op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
(void)HYPERVISOR_network_op(&op);
-
op.u.net_rule.src_vif = VIF_ANY_INTERFACE;
op.u.net_rule.dst_vif = 0;
(void)HYPERVISOR_network_op(&op);
@@ -511,13 +509,32 @@ int __init init_module(void)
INIT_LIST_HEAD(&dev_list);
- /*
- * Domain 0 must poke its own network rules as it discovers its IP
- * addresses. All other domains have a privileged "parent" to do this
- * for them at start of day.
- */
if ( start_info.dom_id == 0 )
+ {
+ /*
+ * Domain 0 creates wildcard rules to allow DHCP to find its first IP
+ * address. These wildcard rules are deleted when the first inet
+ * interface is brought up.
+ */
+ network_op_t op;
+ memset(&op, 0, sizeof(op));
+ op.cmd = NETWORK_OP_ADDRULE;
+ op.u.net_rule.proto = NETWORK_PROTO_ANY;
+ op.u.net_rule.action = NETWORK_ACTION_ACCEPT;
+ op.u.net_rule.src_vif = 0;
+ op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE;
+ (void)HYPERVISOR_network_op(&op);
+ op.u.net_rule.src_vif = VIF_ANY_INTERFACE;
+ op.u.net_rule.dst_vif = 0;
+ (void)HYPERVISOR_network_op(&op);
+
+ /*
+ * Domain 0 must poke its own network rules as it discovers its IP
+ * addresses. All other domains have a privileged "parent" to do this
+ * for them at start of day.
+ */
(void)register_inetaddr_notifier(&notifier_inetdev);
+ }
for ( i = 0; i < MAX_DOMAIN_VIFS; i++ )
{
@@ -548,8 +565,7 @@ int __init init_module(void)
dev->stop = network_close;
dev->get_stats = network_get_stats;
- memset(dev->dev_addr, 0, ETH_ALEN);
- *(unsigned int *)(dev->dev_addr + 1) = i;
+ memcpy(dev->dev_addr, start_info.net_vmac[i], ETH_ALEN);
if ( (err = register_netdev(dev)) != 0 )
{