ia64/xen-unstable

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.
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(&notifier_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