netdev_dummy_set_mtu,
     NULL,                       /* get_ifindex */
     NULL,                       /* get_carrier */
+    NULL,                       /* get_carrier_resets */
     NULL,                       /* get_miimon */
     netdev_dummy_get_stats,
     netdev_dummy_set_stats,
 
     struct in6_addr in6;
     int mtu;
     bool carrier;
+    long long int carrier_resets;
     uint32_t kbits_rate;        /* Policing data. */
     uint32_t kbits_burst;
     bool have_vport_stats;
 
                 if (dev->carrier != change->running) {
                     dev->carrier = change->running;
+                    dev->carrier_resets++;
                 }
 
                 netdev_dev_linux_changed(dev);
             get_carrier_via_sysfs(node->name, &carrier);
             if (dev->carrier != carrier) {
                 dev->carrier = carrier;
+                dev->carrier_resets++;
             }
 
             netdev_dev_linux_changed(dev);
     return 0;
 }
 
+static long long int
+netdev_linux_get_carrier_resets(const struct netdev *netdev)
+{
+    return netdev_dev_linux_cast(netdev_get_dev(netdev))->carrier_resets;
+}
+
 static int
 netdev_linux_do_miimon(const char *name, int cmd, const char *cmd_name,
                        struct mii_ioctl_data *data)
     netdev_linux_set_mtu,                                       \
     netdev_linux_get_ifindex,                                   \
     netdev_linux_get_carrier,                                   \
+    netdev_linux_get_carrier_resets,                            \
     netdev_linux_set_miimon_interval,                           \
     GET_STATS,                                                  \
     SET_STATS,                                                  \
 
      */
     int (*get_carrier)(const struct netdev *netdev, bool *carrier);
 
+    /* Returns the number of times 'netdev''s carrier has changed since being
+     * initialized.
+     *
+     * If null, callers will assume the number of carrier resets is zero. */
+    long long int (*get_carrier_resets)(const struct netdev *netdev);
+
     /* Forces ->get_carrier() to poll 'netdev''s MII registers for link status
      * instead of checking 'netdev''s carrier.  'netdev''s MII registers will
      * be polled once ever 'interval' milliseconds.  If 'netdev' does not
 
     NULL,                       /* set_mtu */               \
     NULL,                       /* get_ifindex */           \
     NULL,                       /* get_carrier */           \
+    NULL,                       /* get_carrier_resets */    \
     NULL,                       /* get_miimon */            \
     netdev_vport_get_stats,                                 \
     netdev_vport_set_stats,                                 \
 
     return carrier;
 }
 
+/* Returns the number of times 'netdev''s carrier has changed. */
+long long int
+netdev_get_carrier_resets(const struct netdev *netdev)
+{
+    return (netdev_get_dev(netdev)->netdev_class->get_carrier_resets
+            ? netdev_get_dev(netdev)->netdev_class->get_carrier_resets(netdev)
+            : 0);
+}
+
 /* Attempts to force netdev_get_carrier() to poll 'netdev''s MII registers for
  * link status instead of checking 'netdev''s carrier.  'netdev''s MII
  * registers will be polled once ever 'interval' milliseconds.  If 'netdev'
 
 
 /* PHY interface. */
 bool netdev_get_carrier(const struct netdev *);
+long long int netdev_get_carrier_resets(const struct netdev *);
 int netdev_set_miimon_interval(struct netdev *, long long int interval);
 int netdev_get_features(const struct netdev *,
                         uint32_t *current, uint32_t *advertised,
 
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_duplex);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_speed);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_state);
+    ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_link_resets);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_mtu);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_ofport);
     ovsdb_idl_omit_alert(idl, &ovsrec_interface_col_statistics);
 
             HMAP_FOR_EACH (iface, name_node, &br->iface_by_name) {
                 const char *link_state;
+                int64_t link_resets;
                 int current;
 
                 if (iface_is_synthetic(iface)) {
 
                 link_state = netdev_get_carrier(iface->netdev) ? "up" : "down";
                 ovsrec_interface_set_link_state(iface->cfg, link_state);
+
+                link_resets = netdev_get_carrier_resets(iface->netdev);
+                ovsrec_interface_set_link_resets(iface->cfg, &link_resets, 1);
             }
         }
 
 
 {"name": "Open_vSwitch",
- "version": "6.1.1",
- "cksum": "282564184 14747",
+ "version": "6.2.0",
+ "cksum": "212779557 14885",
  "tables": {
    "Open_vSwitch": {
      "columns": {
                           "enum": ["set", ["up", "down"]]},
                   "min": 0, "max": 1},
          "ephemeral": true},
+       "link_resets": {
+         "type": {"key": {"type": "integer"},
+                  "min": 0, "max": 1},
+         "ephemeral": true},
        "link_speed": {
          "type": {"key": "integer", "min": 0, "max": 1},
          "ephemeral": true},
 
         </p>
       </column>
 
+      <column name="link_resets">
+        <p>
+          The number of times Open vSwitch has observed the
+          <ref column="link_state"/> of this <ref table="Interface"/> change.
+        </p>
+      </column>
+
       <column name="link_speed">
         <p>
           The negotiated speed of the physical network link.