diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-29 10:15:57 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-04-29 10:15:57 +0000 |
commit | 4e45e54f52b94877c954fa96c2e878398ac1118b (patch) | |
tree | bf64ef0332e120003ea4d28fc4ca0a08afa04ece | |
parent | 21da7264398416838c428c5d6ad0d3db74ba661e (diff) | |
download | xen-4e45e54f52b94877c954fa96c2e878398ac1118b.tar.gz xen-4e45e54f52b94877c954fa96c2e878398ac1118b.tar.bz2 xen-4e45e54f52b94877c954fa96c2e878398ac1118b.zip |
bitkeeper revision 1.192 (3eae50ddRBIeCAm0nByE2rOPgLLz3A)
network.c, vif.h, kernel.c:
Removed 'dom0_ip' option from Xen. Console packets are now sent to 169.254.0.1 (DOM0's hardwired link-local address).
-rw-r--r-- | xen/common/kernel.c | 11 | ||||
-rw-r--r-- | xen/common/network.c | 69 | ||||
-rw-r--r-- | xen/include/xeno/vif.h | 1 | ||||
-rw-r--r-- | xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c | 103 |
4 files changed, 135 insertions, 49 deletions
diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 4ba43b24f9..67602c1139 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -32,7 +32,6 @@ void init_serial(void); void start_of_day(void); /* Command line options and variables. */ -unsigned long opt_dom0_ip = 0; 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 */ @@ -45,7 +44,6 @@ static struct { void *var; } opts[] = { { "ser_baud", OPT_UINT, &opt_ser_baud }, - { "dom0_ip", OPT_IP, &opt_dom0_ip }, { "dom0_mem", OPT_UINT, &opt_dom0_mem }, { "ne_base", OPT_UINT, &opt_ne_base }, { "ifname", OPT_STR, &opt_ifname }, @@ -183,11 +181,6 @@ void cmain (unsigned long magic, multiboot_info_t *mbi) dom0_params.num_vifs = 1; dom0_params.memory_kb = opt_dom0_mem; - if ( opt_dom0_ip == 0 ) - panic("Must specify an IP address for domain 0!\n"); - - add_default_net_rule(0, opt_dom0_ip); // add vfr info for dom0 - new_dom = do_newdomain(0, 0); if ( new_dom == NULL ) panic("Error creating domain 0\n"); @@ -506,8 +499,8 @@ int console_export(char *str, int len) iph->id = 0xdead; iph->ttl = 255; iph->protocol= 17; - iph->daddr = htonl(opt_dom0_ip); - iph->saddr = htonl(0xa9fe0001); + iph->daddr = htonl(0xa9fe0001); /* 169.254.0.1 */ + iph->saddr = htonl(0xa9fe0001); /* 169.254.0.1 */ 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 f63f82e4b1..80d27e7bd6 100644 --- a/xen/common/network.c +++ b/xen/common/network.c @@ -251,38 +251,6 @@ int delete_net_rule(net_rule_t *rule) return 0; } -/* add_default_net_rule - Set up default network path (ie for dom0). - * - * this is a utility function to route all traffic with the specified - * ip address to the specified vif. It's used to set up domain zero. - */ - -void add_default_net_rule(unsigned long vif_id, u32 ipaddr) -{ - net_rule_t new_rule; - - //outbound rule. - memset(&new_rule, 0, sizeof(net_rule_t)); - new_rule.src_addr = ipaddr; - new_rule.src_addr_mask = 0xffffffff; - new_rule.src_vif = vif_id; - new_rule.dst_vif = VIF_PHYSICAL_INTERFACE; - new_rule.action = NETWORK_ACTION_ACCEPT; - new_rule.proto = NETWORK_PROTO_ANY; - add_net_rule(&new_rule); - - //inbound rule; - memset(&new_rule, 0, sizeof(net_rule_t)); - new_rule.dst_addr = ipaddr; - new_rule.dst_addr_mask = 0xffffffff; - new_rule.src_vif = VIF_ANY_INTERFACE; - new_rule.dst_vif = vif_id; - new_rule.action = NETWORK_ACTION_ACCEPT; - new_rule.proto = NETWORK_PROTO_ANY; - add_net_rule(&new_rule); - -} - /* print_net_rule - Print a single net rule. */ @@ -371,6 +339,8 @@ static net_vif_t *net_find_rule(u8 nproto, u8 tproto, u32 src_addr, if ( ((ent->r.src_vif == src_vif) || (ent->r.src_vif == VIF_ANY_INTERFACE)) && + (src_vif != ent->r.dst_vif) && + (!((ent->r.src_addr ^ src_addr) & ent->r.src_addr_mask )) && (!((ent->r.dst_addr ^ dst_addr) & ent->r.dst_addr_mask )) && (!((ent->r.src_port ^ src_port) & ent->r.src_port_mask )) && @@ -504,9 +474,10 @@ long do_network_op(network_op_t *u_network_op) case NETWORK_OP_GETRULELIST: { - // This should eventually ship a rule list up to the VM - // to be printed in its procfs. For now, we just print the rules. - + /* + * This should ship a rule list up to the guest OS. For now + * we just dump the rules to our own console. + */ print_net_rule_list(); } break; @@ -525,9 +496,29 @@ 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), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - net_rule_cache = kmem_cache_create("net_rule_cache", sizeof(net_rule_ent_t), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + net_vif_cache = kmem_cache_create("net_vif_cache", + sizeof(net_vif_t), + 0, SLAB_HWCACHE_ALIGN, NULL, NULL); + 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/xeno/vif.h b/xen/include/xeno/vif.h index de83e7e76b..4fb2e275d1 100644 --- a/xen/include/xeno/vif.h +++ b/xen/include/xeno/vif.h @@ -81,7 +81,6 @@ do { \ net_vif_t *create_net_vif(int domain); void destroy_net_vif(net_vif_t *vif); void unlink_net_vif(net_vif_t *vif); -void add_default_net_rule(unsigned long vif_id, u32 ipaddr); net_vif_t *net_get_target_vif(u8 *data, unsigned int len, net_vif_t *src_vif); net_vif_t *find_vif_by_id(unsigned long id); 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 03f9939e4e..7cf0fecbec 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 @@ -58,6 +58,7 @@ struct net_private net_ring_t *net_ring; net_idx_t *net_idx; spinlock_t tx_lock; + unsigned int idx; /* Domain-specific index of this VIF. */ /* * {tx,rx}_skbs store outstanding skbuffs. The first entry in each @@ -412,6 +413,96 @@ static struct net_device_stats *network_get_stats(struct net_device *dev) } +/* + * This notifier is installed for domain 0 only. + * All other domains have VFR rules installed on their behalf by domain 0 + * when they are created. For bootstrap, Xen creates wildcard rules for + * domain 0 -- this notifier is used to detect when we find our proper + * IP address, so we can poke down proper rules and remove the wildcards. + */ +static int inetdev_notify(struct notifier_block *this, + unsigned long event, + void *ptr) +{ + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; + struct net_device *dev = ifa->ifa_dev->dev; + struct list_head *ent; + struct net_private *np; + int idx = -1; + network_op_t op; + static int removed_bootstrap_rules = 0; + + list_for_each ( ent, &dev_list ) + { + np = list_entry(dev_list.next, struct net_private, list); + if ( np->dev == dev ) + idx = np->idx; + } + + if ( idx == -1 ) + goto out; + + memset(&op, 0, sizeof(op)); + op.u.net_rule.proto = NETWORK_PROTO_ANY; + op.u.net_rule.action = NETWORK_ACTION_ACCEPT; + + if ( event == NETDEV_UP ) + op.cmd = NETWORK_OP_ADDRULE; + else if ( event == NETDEV_DOWN ) + op.cmd = NETWORK_OP_DELETERULE; + else + goto out; + + op.u.net_rule.src_vif = idx; + op.u.net_rule.dst_vif = VIF_PHYSICAL_INTERFACE; + op.u.net_rule.src_addr = ntohl(ifa->ifa_address); + op.u.net_rule.src_addr_mask = ~0UL; + op.u.net_rule.dst_addr = 0; + op.u.net_rule.dst_addr_mask = 0; + (void)HYPERVISOR_network_op(&op); + + op.u.net_rule.src_vif = VIF_ANY_INTERFACE; + op.u.net_rule.dst_vif = idx; + op.u.net_rule.src_addr = 0; + op.u.net_rule.src_addr_mask = 0; + op.u.net_rule.dst_addr = ntohl(ifa->ifa_address); + op.u.net_rule.dst_addr_mask = ~0UL; + (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. + */ + if ( (idx == 0) && (event == NETDEV_UP) && !removed_bootstrap_rules ) + { + memset(&op, 0, sizeof(op)); + 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); + + removed_bootstrap_rules = 1; + } + + out: + return NOTIFY_DONE; +} + +static struct notifier_block notifier_inetdev = { + .notifier_call = inetdev_notify, + .next = NULL, + .priority = 0 +}; + + int __init init_module(void) { int i, fixmap_idx=-1, err; @@ -420,6 +511,14 @@ 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 ) + (void)register_inetaddr_notifier(¬ifier_inetdev); + for ( i = 0; i < MAX_DOMAIN_VIFS; i++ ) { if ( start_info.net_rings[i] == 0 ) @@ -441,6 +540,7 @@ int __init init_module(void) np = dev->priv; np->net_ring = (net_ring_t *)fix_to_virt(FIX_NETRING0_BASE+fixmap_idx); np->net_idx = &HYPERVISOR_shared_info->net_idx[i]; + np->idx = i; SET_MODULE_OWNER(dev); dev->open = network_open; @@ -482,6 +582,9 @@ static void cleanup_module(void) unregister_netdev(dev); kfree(dev); } + + if ( start_info.dom_id == 0 ) + (void)unregister_inetaddr_notifier(¬ifier_inetdev); } |