Skip to content

Commit

Permalink
dummy: Make --enable-dummy=override replace all dpifs, netdevs by dum…
Browse files Browse the repository at this point in the history
…mies.

Plain "--enable-dummy" just creates new dummy dpif and netdev classes.
This commit makes "--enable-dummy=override" go a step farther and actually
delete and replace all the existing dpif and netdev classes by copies of
the dummy class.

This is useful for testing in an environment where changing the classes in
Bridge or Interface records is challenging.

Requested-by: Andrew Lambeth <[email protected]>
Tested-by: Andrew Lambeth <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
blp committed Jan 19, 2012
1 parent a647150 commit 0cbfe35
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 43 deletions.
68 changes: 38 additions & 30 deletions lib/dpif-netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
#include "poll-loop.h"
#include "random.h"
#include "shash.h"
#include "sset.h"
#include "timeval.h"
#include "util.h"
#include "vlog.h"
Expand Down Expand Up @@ -100,7 +101,7 @@ struct dp_netdev_port {
int port_no; /* Index into dp_netdev's 'ports'. */
struct list node; /* Element in dp_netdev's 'port_list'. */
struct netdev *netdev;
bool internal; /* Internal port? */
char *type; /* Port type as requested by user. */
};

/* A flow in dp_netdev's 'flow_table'. */
Expand Down Expand Up @@ -151,8 +152,6 @@ static void dp_netdev_execute_actions(struct dp_netdev *,
const struct nlattr *actions,
size_t actions_len);

static struct dpif_class dpif_dummy_class;

static struct dpif_netdev *
dpif_netdev_cast(const struct dpif *dpif)
{
Expand Down Expand Up @@ -309,28 +308,17 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
{
struct dp_netdev_port *port;
struct netdev *netdev;
bool internal;
const char *open_type;
int mtu;
int error;

/* XXX reject devices already in some dp_netdev. */
if (type[0] == '\0' || !strcmp(type, "system") || !strcmp(type, "dummy")) {
internal = false;
} else if (!strcmp(type, "internal")) {
internal = true;
} else {
VLOG_WARN("%s: unsupported port type %s", devname, type);
return EINVAL;
}

/* Open and validate network device. */
if (dp->class == &dpif_dummy_class) {
type = "dummy";
} else if (internal) {
type = "tap";
}

error = netdev_open(devname, type, &netdev);
open_type = (strcmp(type, "internal") ? type
: dp->class != &dpif_netdev_class ? "dummy"
: "tap");
error = netdev_open(devname, open_type, &netdev);
if (error) {
return error;
}
Expand All @@ -354,7 +342,7 @@ do_add_port(struct dp_netdev *dp, const char *devname, const char *type,
port = xmalloc(sizeof *port);
port->port_no = port_no;
port->netdev = netdev;
port->internal = internal;
port->type = xstrdup(type);

error = netdev_get_mtu(netdev, &mtu);
if (!error) {
Expand All @@ -374,7 +362,7 @@ choose_port(struct dpif *dpif, struct netdev *netdev)
struct dp_netdev *dp = get_dp_netdev(dpif);
int port_no;

if (dpif->dpif_class == &dpif_dummy_class) {
if (dpif->dpif_class != &dpif_netdev_class) {
/* If the port name contains a number, try to assign that port number.
* This can make writing unit tests easier because port numbers are
* predictable. */
Expand Down Expand Up @@ -476,6 +464,7 @@ do_del_port(struct dp_netdev *dp, uint16_t port_no)

name = xstrdup(netdev_get_name(port->netdev));
netdev_close(port->netdev);
free(port->type);

free(name);
free(port);
Expand All @@ -488,8 +477,7 @@ answer_port_query(const struct dp_netdev_port *port,
struct dpif_port *dpif_port)
{
dpif_port->name = xstrdup(netdev_get_name(port->netdev));
dpif_port->type = xstrdup(port->internal ? "internal"
: netdev_get_type(port->netdev));
dpif_port->type = xstrdup(port->type);
dpif_port->port_no = port->port_no;
}

Expand Down Expand Up @@ -581,8 +569,7 @@ dpif_netdev_port_dump_next(const struct dpif *dpif, void *state_,
free(state->name);
state->name = xstrdup(netdev_get_name(port->netdev));
dpif_port->name = state->name;
dpif_port->type = (char *) (port->internal ? "internal"
: netdev_get_type(port->netdev));
dpif_port->type = port->type;
dpif_port->port_no = port->port_no;
state->port_no = port_no + 1;
return 0;
Expand Down Expand Up @@ -1289,12 +1276,33 @@ const struct dpif_class dpif_netdev_class = {
dpif_netdev_recv_purge,
};

static void
dpif_dummy_register__(const char *type)
{
struct dpif_class *class;

class = xmalloc(sizeof *class);
*class = dpif_netdev_class;
class->type = xstrdup(type);
dp_register_provider(class);
}

void
dpif_dummy_register(void)
dpif_dummy_register(bool override)
{
if (!dpif_dummy_class.type) {
dpif_dummy_class = dpif_netdev_class;
dpif_dummy_class.type = "dummy";
dp_register_provider(&dpif_dummy_class);
if (override) {
struct sset types;
const char *type;

sset_init(&types);
dp_enumerate_types(&types);
SSET_FOR_EACH (type, &types) {
if (!dp_unregister_provider(type)) {
dpif_dummy_register__(type);
}
}
sset_destroy(&types);
}

dpif_dummy_register__("dummy");
}
13 changes: 9 additions & 4 deletions lib/dummy.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011 Nicira Networks.
* Copyright (c) 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -22,11 +22,16 @@
* testing. A client program might call this function if it is designed
* specifically for testing or the user enables it on the command line.
*
* If 'override' is false, then "dummy" dpif and netdev classes will be
* created. If 'override' is true, then in addition all existing dpif and
* netdev classes will be deleted and replaced by dummy classes.
*
* There is no strong reason why dummy devices shouldn't always be enabled. */
void
dummy_enable(void)
dummy_enable(bool override)
{
netdev_dummy_register();
dpif_dummy_register();
netdev_dummy_register(override);
dpif_dummy_register(override);
timeval_dummy_register();
}

10 changes: 6 additions & 4 deletions lib/dummy.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2011 Nicira Networks.
* Copyright (c) 2010, 2011, 2012 Nicira Networks.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,12 +17,14 @@
#ifndef DUMMY_H
#define DUMMY_H 1

#include <stdbool.h>

/* For client programs to call directly to enable dummy support. */
void dummy_enable(void);
void dummy_enable(bool override);

/* Implementation details. */
void dpif_dummy_register(void);
void netdev_dummy_register(void);
void dpif_dummy_register(bool override);
void netdev_dummy_register(bool override);
void timeval_dummy_register(void);

#endif /* dummy.h */
24 changes: 22 additions & 2 deletions lib/netdev-dummy.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "packets.h"
#include "poll-loop.h"
#include "shash.h"
#include "sset.h"
#include "unixctl.h"
#include "vlog.h"

Expand Down Expand Up @@ -443,9 +444,28 @@ netdev_dummy_receive(struct unixctl_conn *conn,
}

void
netdev_dummy_register(void)
netdev_dummy_register(bool override)
{
netdev_register_provider(&dummy_class);
unixctl_command_register("netdev-dummy/receive", "NAME PACKET|FLOW...",
2, INT_MAX, netdev_dummy_receive, NULL);

if (override) {
struct sset types;
const char *type;

sset_init(&types);
netdev_enumerate_types(&types);
SSET_FOR_EACH (type, &types) {
if (!netdev_unregister_provider(type)) {
struct netdev_class *class;

class = xmalloc(sizeof *class);
*class = dummy_class;
class->type = xstrdup(type);
netdev_register_provider(class);
}
}
sset_destroy(&types);
}
netdev_register_provider(&dummy_class);
}
6 changes: 3 additions & 3 deletions vswitchd/ovs-vswitchd.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks
/* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -137,7 +137,7 @@ parse_options(int argc, char *argv[])
STREAM_SSL_LONG_OPTIONS,
{"peer-ca-cert", required_argument, NULL, OPT_PEER_CA_CERT},
{"bootstrap-ca-cert", required_argument, NULL, OPT_BOOTSTRAP_CA_CERT},
{"enable-dummy", no_argument, NULL, OPT_ENABLE_DUMMY},
{"enable-dummy", optional_argument, NULL, OPT_ENABLE_DUMMY},
{"disable-system", no_argument, NULL, OPT_DISABLE_SYSTEM},
{NULL, 0, NULL, 0},
};
Expand Down Expand Up @@ -183,7 +183,7 @@ parse_options(int argc, char *argv[])
break;

case OPT_ENABLE_DUMMY:
dummy_enable();
dummy_enable(optarg && !strcmp(optarg, "override"));
break;

case OPT_DISABLE_SYSTEM:
Expand Down

0 comments on commit 0cbfe35

Please sign in to comment.