X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fnetdev.c;h=c7de9064b80d425a475e1b567ac0f26087ba6ab4;hb=1452b28ca636521b6e16f76787524f83205ec7a3;hp=a74d5d4826eab2a284bf9b677ed4eb83d543a411;hpb=85da620e9788b473797b95212b916327974e6942;p=openvswitch diff --git a/lib/netdev.c b/lib/netdev.c index a74d5d48..c7de9064 100644 --- a/lib/netdev.c +++ b/lib/netdev.c @@ -40,7 +40,12 @@ #include "svec.h" #include "vlog.h" -VLOG_DEFINE_THIS_MODULE(netdev) +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); @@ -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,25 +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; - - 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; - } - - return netdev_class->create(netdev_class, options->name, options->args, - netdev_devp); -} - /* 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. @@ -294,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) &&