#include "timeval.h"
#include "util.h"
#include "vconn.h"
-#include "vlog.h"
+#include "openvswitch/vlog.h"
VLOG_DEFINE_THIS_MODULE(vsctl);
static struct ovsdb_idl *the_idl;
static struct ovsdb_idl_txn *the_idl_txn;
-NO_RETURN static void vsctl_exit(int status);
-NO_RETURN static void vsctl_fatal(const char *, ...) PRINTF_FORMAT(1, 2);
+OVS_NO_RETURN static void vsctl_exit(int status);
+OVS_NO_RETURN static void vsctl_fatal(const char *, ...) OVS_PRINTF_FORMAT(1, 2);
static char *default_db(void);
-NO_RETURN static void usage(void);
+OVS_NO_RETURN static void usage(void);
static void parse_options(int argc, char *argv[], struct shash *local_options);
static bool might_write_to_db(char **argv);
struct vsctl_bridge {
struct ovsrec_bridge *br_cfg;
char *name;
- struct list ports; /* Contains "struct vsctl_port"s. */
+ struct ovs_list ports; /* Contains "struct vsctl_port"s. */
/* VLAN ("fake") bridge support.
*
};
struct vsctl_port {
- struct list ports_node; /* In struct vsctl_bridge's 'ports' list. */
- struct list ifaces; /* Contains "struct vsctl_iface"s. */
+ struct ovs_list ports_node; /* In struct vsctl_bridge's 'ports' list. */
+ struct ovs_list ifaces; /* Contains "struct vsctl_iface"s. */
struct ovsrec_port *port_cfg;
struct vsctl_bridge *bridge;
};
struct vsctl_iface {
- struct list ifaces_node; /* In struct vsctl_port's 'ifaces' list. */
+ struct ovs_list ifaces_node; /* In struct vsctl_port's 'ifaces' list. */
struct ovsrec_interface *iface_cfg;
struct vsctl_port *port;
};
+static struct vsctl_bridge *find_vlan_bridge(struct vsctl_bridge *parent,
+ int vlan);
+
static char *
vsctl_context_to_string(const struct vsctl_context *ctx)
{
br->vlan = vlan;
hmap_init(&br->children);
if (parent) {
- hmap_insert(&parent->children, &br->children_node, hash_int(vlan, 0));
+ struct vsctl_bridge *conflict = find_vlan_bridge(parent, vlan);
+ if (conflict) {
+ VLOG_WARN("%s: bridge has multiple VLAN bridges (%s and %s) "
+ "for VLAN %d, but only one is allowed",
+ parent->name, name, conflict->name, vlan);
+ } else {
+ hmap_insert(&parent->children, &br->children_node,
+ hash_int(vlan, 0));
+ }
}
shash_add(&ctx->bridges, br->name, br);
return br;
ovs_insert_bridge(ctx->ovs, br);
} else {
+ struct vsctl_bridge *conflict;
struct vsctl_bridge *parent;
struct ovsrec_port *port;
struct ovsrec_bridge *br;
if (!parent) {
vsctl_fatal("parent bridge %s does not exist", parent_name);
}
+ conflict = find_vlan_bridge(parent, vlan);
+ if (conflict) {
+ vsctl_fatal("bridge %s already has a child VLAN bridge %s "
+ "on VLAN %d", parent_name, conflict->name, vlan);
+ }
br = parent->br_cfg;
iface = ovsrec_interface_insert(ctx->txn);
*
* On success, returns NULL. On failure, returned a malloc()'d string error
* message and stores NULL into all of the nonnull output arguments. */
-static char * WARN_UNUSED_RESULT
+static char * OVS_WARN_UNUSED_RESULT
parse_column_key_value(const char *arg,
const struct vsctl_table_class *table,
const struct ovsdb_idl_column **columnp, char **keyp,