direct-io.hg
changeset 3447:d1c129322f63
bitkeeper revision 1.1159.170.100 (41ebbee2RjlL1wu1Hj5Chq-Ma_yd4Q)
Send a fake ARP reply when bringing up an IP address on a VIF.
Should flush stale switch/router state.
Send a fake ARP reply when bringing up an IP address on a VIF.
Should flush stale switch/router state.
author | kaf24@scramble.cl.cam.ac.uk |
---|---|
date | Mon Jan 17 13:34:26 2005 +0000 (2005-01-17) |
parents | 515888a1b568 |
children | 4abfb7f9fa7a f8e1f285e41f ed68fb045306 |
files | linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c |
line diff
1.1 --- a/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c Mon Jan 17 08:11:17 2005 +0000 1.2 +++ b/linux-2.6.10-xen-sparse/drivers/xen/netfront/netfront.c Mon Jan 17 13:34:26 2005 +0000 1.3 @@ -257,7 +257,7 @@ static int netctrl_connected_count(void) 1.4 * @param dev device 1.5 * @return 0 on success, error code otherwise 1.6 */ 1.7 -static int vif_wake(struct net_device *dev) 1.8 +static int send_fake_arp(struct net_device *dev) 1.9 { 1.10 struct sk_buff *skb; 1.11 u32 src_ip, dst_ip; 1.12 @@ -265,10 +265,15 @@ static int vif_wake(struct net_device *d 1.13 dst_ip = INADDR_BROADCAST; 1.14 src_ip = inet_select_addr(dev, dst_ip, RT_SCOPE_LINK); 1.15 1.16 + /* No IP? Then nothing to do. */ 1.17 + if ( src_ip == 0 ) 1.18 + return 0; 1.19 + 1.20 skb = arp_create(ARPOP_REPLY, ETH_P_ARP, 1.21 dst_ip, dev, src_ip, 1.22 /*dst_hw*/ NULL, /*src_hw*/ NULL, 1.23 /*target_hw*/ dev->dev_addr); 1.24 + printk(KERN_ALERT "ARP sent on %08x %08x %p\n", dst_ip, src_ip, skb); 1.25 if ( skb == NULL ) 1.26 return -ENOMEM; 1.27 1.28 @@ -822,13 +827,11 @@ static void send_interface_connect(struc 1.29 }; 1.30 netif_fe_interface_connect_t *msg = (void*)cmsg.msg; 1.31 1.32 - DPRINTK(">\n"); vif_show(np); 1.33 msg->handle = np->handle; 1.34 msg->tx_shmem_frame = (virt_to_machine(np->tx) >> PAGE_SHIFT); 1.35 msg->rx_shmem_frame = (virt_to_machine(np->rx) >> PAGE_SHIFT); 1.36 1.37 ctrl_if_send_message_block(&cmsg, NULL, 0, TASK_UNINTERRUPTIBLE); 1.38 - DPRINTK("<\n"); 1.39 } 1.40 1.41 /* Send a driver status notification to the domain controller. */ 1.42 @@ -876,13 +879,12 @@ static void vif_release(struct net_priva 1.43 */ 1.44 static void vif_close(struct net_private *np) 1.45 { 1.46 - DPRINTK(">\n"); vif_show(np); 1.47 WPRINTK("Unexpected netif-CLOSED message in state %s\n", 1.48 be_state_name[np->backend_state]); 1.49 vif_release(np); 1.50 np->backend_state = BEST_CLOSED; 1.51 /* todo: take dev down and free. */ 1.52 - vif_show(np); DPRINTK("<\n"); 1.53 + vif_show(np); 1.54 } 1.55 1.56 /* Move the vif into disconnected state. 1.57 @@ -891,7 +893,6 @@ static void vif_close(struct net_private 1.58 */ 1.59 static void vif_disconnect(struct net_private *np) 1.60 { 1.61 - DPRINTK(">\n"); 1.62 if(np->tx) free_page((unsigned long)np->tx); 1.63 if(np->rx) free_page((unsigned long)np->rx); 1.64 // Before this np->tx and np->rx had better be null. 1.65 @@ -901,7 +902,7 @@ static void vif_disconnect(struct net_pr 1.66 memset(np->rx, 0, PAGE_SIZE); 1.67 np->backend_state = BEST_DISCONNECTED; 1.68 send_interface_connect(np); 1.69 - vif_show(np); DPRINTK("<\n"); 1.70 + vif_show(np); 1.71 } 1.72 1.73 /* Begin interface recovery. 1.74 @@ -921,12 +922,11 @@ static void 1.75 vif_reset( 1.76 struct net_private *np) 1.77 { 1.78 - DPRINTK(">\n"); 1.79 IPRINTK("Attempting to reconnect network interface: handle=%u\n", 1.80 np->handle); 1.81 vif_release(np); 1.82 vif_disconnect(np); 1.83 - vif_show(np); DPRINTK("<\n"); 1.84 + vif_show(np); 1.85 } 1.86 1.87 /* Move the vif into connected state. 1.88 @@ -938,15 +938,14 @@ vif_connect( 1.89 struct net_private *np, netif_fe_interface_status_t *status) 1.90 { 1.91 struct net_device *dev = np->dev; 1.92 - DPRINTK(">\n"); 1.93 memcpy(dev->dev_addr, status->mac, ETH_ALEN); 1.94 network_connect(dev, status); 1.95 np->evtchn = status->evtchn; 1.96 np->irq = bind_evtchn_to_irq(np->evtchn); 1.97 (void)request_irq(np->irq, netif_int, SA_SAMPLE_RANDOM, dev->name, dev); 1.98 netctrl_connected_count(); 1.99 - vif_wake(dev); 1.100 - vif_show(np); DPRINTK("<\n"); 1.101 + (void)send_fake_arp(dev); 1.102 + vif_show(np); 1.103 } 1.104 1.105 1.106 @@ -1058,7 +1057,6 @@ static void netif_interface_status(netif 1.107 int err = 0; 1.108 struct net_private *np = NULL; 1.109 1.110 - DPRINTK(">\n"); 1.111 DPRINTK("> status=%s handle=%d\n", 1.112 status_name[status->status], status->handle); 1.113 1.114 @@ -1074,8 +1072,6 @@ static void netif_interface_status(netif 1.115 return; 1.116 } 1.117 1.118 - DPRINTK(">\n"); vif_show(np); 1.119 - 1.120 switch ( status->status ) 1.121 { 1.122 case NETIF_INTERFACE_STATUS_CLOSED: 1.123 @@ -1129,8 +1125,8 @@ static void netif_interface_status(netif 1.124 WPRINTK("Invalid netif status code %d\n", status->status); 1.125 break; 1.126 } 1.127 + 1.128 vif_show(np); 1.129 - DPRINTK("<\n"); 1.130 } 1.131 1.132 /* 1.133 @@ -1138,10 +1134,7 @@ static void netif_interface_status(netif 1.134 */ 1.135 static void netif_driver_status(netif_fe_driver_status_t *status) 1.136 { 1.137 - DPRINTK("> status=%d\n", status->status); 1.138 netctrl.up = status->status; 1.139 - //netctrl.interface_n = status->max_handle; 1.140 - //netctrl.connected_n = 0; 1.141 netctrl_connected_count(); 1.142 } 1.143 1.144 @@ -1266,6 +1259,39 @@ static int probe_interfaces(void) 1.145 1.146 #endif 1.147 1.148 +/* 1.149 + * We use this notifier to send out a fake ARP reply to reset switches and 1.150 + * router ARP caches when an IP interface is brought up on a VIF. 1.151 + */ 1.152 +static int inetdev_notify(struct notifier_block *this, 1.153 + unsigned long event, 1.154 + void *ptr) 1.155 +{ 1.156 + struct in_ifaddr *ifa = (struct in_ifaddr *)ptr; 1.157 + struct net_device *dev = ifa->ifa_dev->dev; 1.158 + struct list_head *ent; 1.159 + struct net_private *np; 1.160 + 1.161 + if ( event != NETDEV_UP ) 1.162 + goto out; 1.163 + 1.164 + list_for_each ( ent, &dev_list ) 1.165 + { 1.166 + np = list_entry(ent, struct net_private, list); 1.167 + if ( np->dev == dev ) 1.168 + (void)send_fake_arp(dev); 1.169 + } 1.170 + 1.171 + out: 1.172 + return NOTIFY_DONE; 1.173 +} 1.174 + 1.175 +static struct notifier_block notifier_inetdev = { 1.176 + .notifier_call = inetdev_notify, 1.177 + .next = NULL, 1.178 + .priority = 0 1.179 +}; 1.180 + 1.181 static int __init netif_init(void) 1.182 { 1.183 int err = 0; 1.184 @@ -1276,6 +1302,7 @@ static int __init netif_init(void) 1.185 1.186 IPRINTK("Initialising virtual ethernet driver.\n"); 1.187 INIT_LIST_HEAD(&dev_list); 1.188 + (void)register_inetaddr_notifier(¬ifier_inetdev); 1.189 netctrl_init(); 1.190 (void)ctrl_if_register_receiver(CMSG_NETIF_FE, netif_ctrlif_rx, 1.191 CALLBACK_IN_BLOCKING_CONTEXT); 1.192 @@ -1290,56 +1317,46 @@ static int __init netif_init(void) 1.193 1.194 static void vif_suspend(struct net_private *np) 1.195 { 1.196 - // Avoid having tx/rx stuff happen until we're ready. 1.197 - DPRINTK(">\n"); 1.198 + /* Avoid having tx/rx stuff happen until we're ready. */ 1.199 free_irq(np->irq, np->dev); 1.200 unbind_evtchn_from_irq(np->evtchn); 1.201 - DPRINTK("<\n"); 1.202 } 1.203 1.204 static void vif_resume(struct net_private *np) 1.205 { 1.206 - // Connect regardless of whether IFF_UP flag set. 1.207 - // Stop bad things from happening until we're back up. 1.208 - DPRINTK(">\n"); 1.209 + /* 1.210 + * Connect regardless of whether IFF_UP flag set. 1.211 + * Stop bad things from happening until we're back up. 1.212 + */ 1.213 np->backend_state = BEST_DISCONNECTED; 1.214 memset(np->tx, 0, PAGE_SIZE); 1.215 memset(np->rx, 0, PAGE_SIZE); 1.216 1.217 send_interface_connect(np); 1.218 - DPRINTK("<\n"); 1.219 } 1.220 1.221 void netif_suspend(void) 1.222 { 1.223 -#if 1 /* XXX THIS IS TEMPORARY */ 1.224 struct list_head *ent; 1.225 struct net_private *np; 1.226 1.227 - DPRINTK(">\n"); 1.228 - list_for_each(ent, &dev_list){ 1.229 + list_for_each ( ent, &dev_list ) 1.230 + { 1.231 np = list_entry(ent, struct net_private, list); 1.232 vif_suspend(np); 1.233 } 1.234 - DPRINTK("<\n"); 1.235 -#endif 1.236 } 1.237 1.238 void netif_resume(void) 1.239 { 1.240 -#if 1 1.241 - /* XXX THIS IS TEMPORARY */ 1.242 struct list_head *ent; 1.243 struct net_private *np; 1.244 1.245 - DPRINTK(">\n"); 1.246 list_for_each ( ent, &dev_list ) 1.247 { 1.248 np = list_entry(ent, struct net_private, list); 1.249 vif_resume(np); 1.250 } 1.251 - DPRINTK("<\n"); 1.252 -#endif 1.253 } 1.254 1.255