netdev_vport_get_etheraddr,
     netdev_vport_get_mtu,
     NULL,                       /* get_ifindex */
-    netdev_vport_get_carrier,
+    NULL,                       /* get_carrier */
     netdev_vport_get_stats,
     netdev_vport_set_stats,
 
 
     int (*get_ifindex)(const struct netdev *netdev);
 
     /* Sets 'carrier' to true if carrier is active (link light is on) on
-     * 'netdev'. */
+     * 'netdev'.
+     *
+     * May be null if device does not provide carrier status (will be always
+     * up as long as device is up).
+     */
     int (*get_carrier)(const struct netdev *netdev, bool *carrier);
 
     /* Retrieves current device stats for 'netdev' into 'stats'.
 
     netdev_vport_get_etheraddr,
     netdev_vport_get_mtu,
     NULL,                       /* get_ifindex */
-    netdev_vport_get_carrier,
+    NULL,                       /* get_carrier */
     netdev_vport_get_stats,
     netdev_vport_set_stats,
 
     netdev_vport_get_etheraddr,
     netdev_vport_get_mtu,
     NULL,                       /* get_ifindex */
-    netdev_vport_get_carrier,
+    NULL,                       /* get_carrier */
     netdev_vport_get_stats,
     netdev_vport_set_stats,
 
 
     return 0;
 }
 
-int
-netdev_vport_get_carrier(const struct netdev *netdev OVS_UNUSED, bool *carrier)
-{
-    *carrier = true;
-    return 0;
-}
-
 int
 netdev_vport_get_stats(const struct netdev *netdev, struct netdev_stats *stats)
 {
 
 int netdev_vport_get_etheraddr(const struct netdev *,
                                uint8_t mac[ETH_ADDR_LEN]);
 int netdev_vport_get_mtu(const struct netdev *, int *mtup);
-int netdev_vport_get_carrier(const struct netdev *, bool *carrier);
 int netdev_vport_get_stats(const struct netdev *, struct netdev_stats *);
 int netdev_vport_set_stats(struct netdev *, const struct netdev_stats *);
 int netdev_vport_update_flags(struct netdev *, enum netdev_flags off,
 
     return error;
 }
 
-/* Sets 'carrier' to true if carrier is active (link light is on) on
- * 'netdev'. */
-int
-netdev_get_carrier(const struct netdev *netdev, bool *carrier)
+/* Returns true if carrier is active (link light is on) on 'netdev'. */
+bool
+netdev_get_carrier(const struct netdev *netdev)
 {
-    int error = (netdev_get_dev(netdev)->netdev_class->get_carrier
-                 ? netdev_get_dev(netdev)->netdev_class->get_carrier(netdev,
-                        carrier)
-                 : EOPNOTSUPP);
+    int error;
+    enum netdev_flags flags;
+    bool carrier;
+
+    netdev_get_flags(netdev, &flags);
+    if (!(flags & NETDEV_UP)) {
+        return false;
+    }
+
+    if (!netdev_get_dev(netdev)->netdev_class->get_carrier) {
+        return true;
+    }
+
+    error = netdev_get_dev(netdev)->netdev_class->get_carrier(netdev,
+                                                              &carrier);
     if (error) {
-        *carrier = false;
+        VLOG_DBG("%s: failed to get network device carrier status, assuming "
+                 "down: %s", netdev_get_name(netdev), strerror(error));
+        carrier = false;
     }
-    return error;
+
+    return carrier;
 }
 
 /* Retrieves current device stats for 'netdev'. */
 
 int netdev_get_etheraddr(const struct netdev *, uint8_t mac[6]);
 
 /* PHY interface. */
-int netdev_get_carrier(const struct netdev *, bool *carrier);
+bool netdev_get_carrier(const struct netdev *);
 int netdev_get_features(struct netdev *,
                         uint32_t *current, uint32_t *advertised,
                         uint32_t *supported, uint32_t *peer);
 
         counters->ifDirection = 0;
     }
     if (!netdev_get_flags(osp->netdev, &flags) && flags & NETDEV_UP) {
-        bool carrier;
-
         counters->ifStatus = 1; /* ifAdminStatus up. */
-        if (!netdev_get_carrier(osp->netdev, &carrier) && carrier) {
+        if (netdev_get_carrier(osp->netdev)) {
             counters->ifStatus |= 2; /* ifOperStatus us. */
         }
     } else {
 
     enum netdev_flags flags;
     struct ofport *ofport;
     struct netdev *netdev;
-    bool carrier;
     int error;
 
     memset(&netdev_options, 0, sizeof netdev_options);
     netdev_get_flags(netdev, &flags);
     ofport->opp.config = flags & NETDEV_UP ? 0 : OFPPC_PORT_DOWN;
 
-    netdev_get_carrier(netdev, &carrier);
-    ofport->opp.state = carrier ? 0 : OFPPS_LINK_DOWN;
+    ofport->opp.state = netdev_get_carrier(netdev) ? 0 : OFPPS_LINK_DOWN;
 
     netdev_get_features(netdev,
                         &ofport->opp.curr, &ofport->opp.advertised,
 
         error = netdev_open(&netdev_options, &iface->netdev);
 
         if (iface->netdev) {
-            netdev_get_carrier(iface->netdev, &iface->enabled);
+            iface->enabled = netdev_get_carrier(iface->netdev);
         }
     } else if (iface->netdev) {
         const char *netdev_type = netdev_get_type(iface->netdev);