aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-29 10:15:57 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-04-29 10:15:57 +0000
commit4e45e54f52b94877c954fa96c2e878398ac1118b (patch)
treebf64ef0332e120003ea4d28fc4ca0a08afa04ece
parent21da7264398416838c428c5d6ad0d3db74ba661e (diff)
downloadxen-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.c11
-rw-r--r--xen/common/network.c69
-rw-r--r--xen/include/xeno/vif.h1
-rw-r--r--xenolinux-2.4.21-pre4-sparse/arch/xeno/drivers/network/network.c103
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(&notifier_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(&notifier_inetdev);
}