X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev.c;h=34cb1e9b53fac376644093d5817a90baa74edcd3;hb=c0a56d9fe1fdb57220b9c1e2f709ea2db5d6489d;hp=993f27a8860496bec78256d05a6f549f9057295a;hpb=2b9d65898426b2e15d05dc6a9ffdbcb92933398f;p=openvswitch diff --git a/lib/netdev.c b/lib/netdev.c index 993f27a8..34cb1e9b 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -40,7 +40,7 @@ #include "svec.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(netdev) +VLOG_DEFINE_THIS_MODULE(netdev); static struct shash netdev_classes = SHASH_INITIALIZER(&netdev_classes); @@ -251,6 +251,7 @@ static int create_device(struct netdev_options *options, struct netdev_dev **netdev_devp) { struct netdev_class *netdev_class; + int error; if (!options->type || strlen(options->type) == 0) { /* Default to system. */ @@ -262,8 +263,10 @@ create_device(struct netdev_options *options, struct netdev_dev **netdev_devp) return EAFNOSUPPORT; } - return netdev_class->create(netdev_class, options->name, options->args, - netdev_devp); + error = netdev_class->create(netdev_class, options->name, options->args, + netdev_devp); + assert(error || (*netdev_devp)->netdev_class == netdev_class); + return error; } /* Opens the network device named 'name' (e.g. "eth0") and returns zero if @@ -892,19 +895,32 @@ netdev_arp_lookup(const struct netdev *netdev, 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'. */