X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;ds=sidebyside;f=lib%2Fnetdev.c;h=c7de9064b80d425a475e1b567ac0f26087ba6ab4;hb=c3827f619a38d3d202020838e1f92860046a3dbe;hp=34cb1e9b53fac376644093d5817a90baa74edcd3;hpb=a8f86734614d584ff72ffe34938bb3e9cf05394c;p=sliver-openvswitch.git diff --git a/lib/netdev.c b/lib/netdev.c index 34cb1e9b5..c7de9064b 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -42,6 +42,11 @@ VLOG_DEFINE_THIS_MODULE(netdev); +COVERAGE_DEFINE(netdev_received); +COVERAGE_DEFINE(netdev_sent); +COVERAGE_DEFINE(netdev_add_router); +COVERAGE_DEFINE(netdev_get_stats); + static struct shash netdev_classes = SHASH_INITIALIZER(&netdev_classes); /* All created network devices. */ @@ -70,6 +75,7 @@ netdev_initialize(void) #ifdef HAVE_NETLINK netdev_register_provider(&netdev_linux_class); + netdev_register_provider(&netdev_internal_class); netdev_register_provider(&netdev_tap_class); netdev_vport_register(); #endif @@ -162,6 +168,13 @@ netdev_unregister_provider(const char *type) return 0; } +const struct netdev_class * +netdev_lookup_provider(const char *type) +{ + netdev_initialize(); + return shash_find_data(&netdev_classes, type && type[0] ? type : "system"); +} + /* Clears 'types' and enumerates the types of all currently registered netdev * providers into it. The caller must first initialize the svec. */ void @@ -247,28 +260,6 @@ update_device_args(struct netdev_dev *dev, const struct shash *args) qsort(dev->args, dev->n_args, sizeof *dev->args, compare_args); } -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. */ - options->type = "system"; - } - - netdev_class = shash_find_data(&netdev_classes, options->type); - if (!netdev_class) { - return EAFNOSUPPORT; - } - - 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 * successful, otherwise a positive errno value. On success, sets '*netdevp' * to the new network device, otherwise to null. @@ -297,14 +288,20 @@ netdev_open(struct netdev_options *options, struct netdev **netdevp) netdev_dev = shash_find_data(&netdev_dev_shash, options->name); if (!netdev_dev) { - error = create_device(options, &netdev_dev); + const struct netdev_class *class; + + class = netdev_lookup_provider(options->type); + if (!class) { + VLOG_WARN("could not create netdev %s of unknown type %s", + options->name, options->type); + return EAFNOSUPPORT; + } + error = class->create(class, options->name, options->args, + &netdev_dev); if (error) { - if (error == EAFNOSUPPORT) { - VLOG_WARN("could not create netdev %s of unknown type %s", - options->name, options->type); - } return error; } + assert(netdev_dev->netdev_class == class); update_device_args(netdev_dev, options->args); } else if (!shash_is_empty(options->args) &&