From 4e45e54f52b94877c954fa96c2e878398ac1118b Mon Sep 17 00:00:00 2001 From: "kaf24@scramble.cl.cam.ac.uk" Date: Tue, 29 Apr 2003 10:15:57 +0000 Subject: 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). --- .../arch/xeno/drivers/network/network.c | 103 +++++++++++++++++++++ 1 file changed, 103 insertions(+) (limited to 'xenolinux-2.4.21-pre4-sparse') 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); } -- cgit v1.2.3