diff options
-rw-r--r-- | xen/common/domain.c | 4 | ||||
-rw-r--r-- | xen/common/kernel.c | 5 | ||||
-rw-r--r-- | xen/common/network.c | 26 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/hypervisor-if.h | 1 | ||||
-rw-r--r-- | xen/include/xeno/vif.h | 5 | ||||
-rw-r--r-- | xen/net/dev.c | 10 | ||||
-rw-r--r-- | xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c | 40 |
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(¬ifier_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 ) { |