proper handling of change_seq
authorGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Thu, 17 May 2012 08:03:16 +0000 (10:03 +0200)
committerGiuseppe Lettieri <g.lettieri@iet.unipi.it>
Thu, 17 May 2012 08:03:16 +0000 (10:03 +0200)
lib/netdev-bsd.c

index 1b78a0b..db844be 100644 (file)
@@ -208,6 +208,15 @@ netdev_bsd_wait(void)
     rtbsd_notifier_wait();
 }
 
+static void
+netdev_dev_bsd_changed(struct netdev_dev_bsd *dev)
+{
+    dev->change_seq++;
+    if (!dev->change_seq) {
+        dev->change_seq++;
+    }
+}
+
 /* Invalidate cache in case of interface status change. */
 static void
 netdev_bsd_cache_cb(const struct rtbsd_change *change,
@@ -225,6 +234,7 @@ netdev_bsd_cache_cb(const struct rtbsd_change *change,
             if (is_netdev_bsd_class(netdev_class)) {
                 dev = netdev_dev_bsd_cast(base_dev);
                 dev->cache_valid = 0;
+                netdev_dev_bsd_changed(dev);
             }
         }
     } else {
@@ -240,6 +250,7 @@ netdev_bsd_cache_cb(const struct rtbsd_change *change,
         SHASH_FOR_EACH (node, &device_shash) {
             dev = node->data;
             dev->cache_valid = 0;
+            netdev_dev_bsd_changed(dev);
         }
         shash_destroy(&device_shash);
     }
@@ -316,6 +327,7 @@ netdev_bsd_create_tap(const struct netdev_class *class, const char *name,
     /* Create a tap device by opening /dev/tap.  The TAPGIFNAME ioctl is used
      * to retrieve the name of the tap device. */
     netdev_dev->tap_fd = open("/dev/tap", O_RDWR);
+    netdev_dev->change_seq = 1;
     if (netdev_dev->tap_fd < 0) {
         error = errno;
         VLOG_WARN("opening \"/dev/tap\" failed: %s", strerror(error));
@@ -456,6 +468,8 @@ netdev_bsd_listen(struct netdev *netdev_)
         goto error;
     }
     
+    netdev_dev_bsd_changed(netdev_dev_bsd_cast(netdev_get_dev(netdev_)));
+    
     /* initialize netdev->netdev_fd */
     fd = pcap_get_selectable_fd(netdev->pcap_handle);
     if (fd == -1) {
@@ -749,6 +763,7 @@ netdev_bsd_set_etheraddr(struct netdev *netdev_,
         if (!error) {
             netdev_dev->cache_valid |= VALID_ETHERADDR;
             memcpy(netdev_dev->etheraddr, mac, ETH_ADDR_LEN);
+            netdev_dev_bsd_changed(netdev_dev);
         }
     } else {
         error = 0;
@@ -1114,6 +1129,7 @@ netdev_bsd_set_in4(struct netdev *netdev_, struct in_addr addr,
             error = do_set_addr(netdev_, SIOCSIFNETMASK,
                                 "SIOCSIFNETMASK", mask);
         }
+        netdev_dev_bsd_changed(netdev_dev);
     }
     return error;
 }
@@ -1215,6 +1231,7 @@ netdev_bsd_update_flags(struct netdev *netdev, enum netdev_flags off,
         new_flags = (old_flags & ~nd_to_iff_flags(off)) | nd_to_iff_flags(on);
         if (new_flags != old_flags) {
             error = set_flags(netdev, new_flags);
+            netdev_dev_bsd_changed(netdev_dev_bsd_cast(netdev_get_dev(netdev)));
         }
     }
     return error;