2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-03 15:55:19 +00:00

bridge: Tolerate missing Port and Interface records for local port.

Until now, ovs-vswitchd has been unable to configure IP addresses and
routes for bridges whose Bridge records lack a Port and an Interface
record for the bridge's local port (e.g. OFPP_LOCAL, the port with the
same name as the bridge itself).  When such a bridge was reconfigured,
ovs-vswitchd would output a log message that worried people.

This commit fixes the internal limitation that led to the message being
printed.

Bug #5385.
This commit is contained in:
Ben Pfaff
2011-04-13 11:10:44 -07:00
parent b33951b80f
commit cfea354b81
3 changed files with 56 additions and 16 deletions

View File

@@ -1108,6 +1108,15 @@ ovsdb_idl_get(const struct ovsdb_idl_row *row,
return ovsdb_idl_read(row, column); return ovsdb_idl_read(row, column);
} }
/* Returns false if 'row' was obtained from the IDL, true if it was initialized
* to all-zero-bits by some other entity. If 'row' was set up some other way
* then the return value is indeterminate. */
bool
ovsdb_idl_row_is_synthetic(const struct ovsdb_idl_row *row)
{
return row->table == NULL;
}
/* Transactions. */ /* Transactions. */

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2009, 2010 Nicira Networks. /* Copyright (c) 2009, 2010, 2011 Nicira Networks.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -105,6 +105,8 @@ const struct ovsdb_datum *ovsdb_idl_get(const struct ovsdb_idl_row *,
const struct ovsdb_idl_column *, const struct ovsdb_idl_column *,
enum ovsdb_atomic_type key_type, enum ovsdb_atomic_type key_type,
enum ovsdb_atomic_type value_type); enum ovsdb_atomic_type value_type);
bool ovsdb_idl_row_is_synthetic(const struct ovsdb_idl_row *);
/* Transactions. */ /* Transactions. */

View File

@@ -185,6 +185,11 @@ struct bridge {
/* Port mirroring. */ /* Port mirroring. */
struct mirror *mirrors[MAX_MIRRORS]; struct mirror *mirrors[MAX_MIRRORS];
/* Synthetic local port if necessary. */
struct ovsrec_port synth_local_port;
struct ovsrec_interface synth_local_iface;
struct ovsrec_interface *synth_local_ifacep;
}; };
/* List of all bridges. */ /* List of all bridges. */
@@ -264,6 +269,7 @@ static void iface_update_qos(struct iface *, const struct ovsrec_qos *);
static void iface_update_cfm(struct iface *); static void iface_update_cfm(struct iface *);
static bool iface_refresh_cfm_stats(struct iface *iface); static bool iface_refresh_cfm_stats(struct iface *iface);
static bool iface_get_carrier(const struct iface *); static bool iface_get_carrier(const struct iface *);
static bool iface_is_synthetic(const struct iface *);
static void shash_from_ovs_idl_map(char **keys, char **values, size_t n, static void shash_from_ovs_idl_map(char **keys, char **values, size_t n,
struct shash *); struct shash *);
@@ -1140,6 +1146,10 @@ iface_refresh_status(struct iface *iface)
int64_t mtu_64; int64_t mtu_64;
int error; int error;
if (iface_is_synthetic(iface)) {
return;
}
shash_init(&sh); shash_init(&sh);
if (!netdev_get_status(iface->netdev, &sh)) { if (!netdev_get_status(iface->netdev, &sh)) {
@@ -1282,6 +1292,10 @@ iface_refresh_stats(struct iface *iface)
struct netdev_stats stats; struct netdev_stats stats;
if (iface_is_synthetic(iface)) {
return;
}
/* Intentionally ignore return value, since errors will set 'stats' to /* Intentionally ignore return value, since errors will set 'stats' to
* all-1s, and we will deal with that correctly below. */ * all-1s, and we will deal with that correctly below. */
netdev_get_stats(iface->netdev, &stats); netdev_get_stats(iface->netdev, &stats);
@@ -1716,6 +1730,7 @@ bridge_destroy(struct bridge *br)
hmap_destroy(&br->ifaces); hmap_destroy(&br->ifaces);
hmap_destroy(&br->ports); hmap_destroy(&br->ports);
shash_destroy(&br->iface_by_name); shash_destroy(&br->iface_by_name);
free(br->synth_local_iface.type);
free(br->name); free(br->name);
free(br); free(br);
} }
@@ -1841,22 +1856,28 @@ bridge_reconfigure_one(struct bridge *br)
br->name, name); br->name, name);
} }
} }
if (!shash_find(&new_ports, br->name)) {
struct dpif_port dpif_port;
char *type;
/* If we have a controller, then we need a local port. Complain if the VLOG_WARN("bridge %s: no port named %s, synthesizing one",
* user didn't specify one. br->name, br->name);
*
* XXX perhaps we should synthesize a port ourselves in this case. */
if (bridge_get_controllers(br, NULL)) {
char local_name[IF_NAMESIZE];
int error;
error = dpif_port_get_name(br->dpif, ODPP_LOCAL, dpif_port_query_by_number(br->dpif, ODPP_LOCAL, &dpif_port);
local_name, sizeof local_name); type = xstrdup(dpif_port.type ? dpif_port.type : "internal");
if (!error && !shash_find(&new_ports, local_name)) { dpif_port_destroy(&dpif_port);
VLOG_WARN("bridge %s: controller specified but no local port "
"(port named %s) defined", br->synth_local_port.interfaces = &br->synth_local_ifacep;
br->name, local_name); br->synth_local_port.n_interfaces = 1;
} br->synth_local_port.name = br->name;
br->synth_local_iface.name = br->name;
free(br->synth_local_iface.type);
br->synth_local_iface.type = type;
br->synth_local_ifacep = &br->synth_local_iface;
shash_add(&new_ports, br->name, &br->synth_local_port);
} }
/* Get rid of deleted ports. /* Get rid of deleted ports.
@@ -3405,7 +3426,7 @@ iface_set_mac(struct iface *iface)
static void static void
iface_set_ofport(const struct ovsrec_interface *if_cfg, int64_t ofport) iface_set_ofport(const struct ovsrec_interface *if_cfg, int64_t ofport)
{ {
if (if_cfg) { if (if_cfg && !ovsdb_idl_row_is_synthetic(&if_cfg->header_)) {
ovsrec_interface_set_ofport(if_cfg, &ofport, 1); ovsrec_interface_set_ofport(if_cfg, &ofport, 1);
} }
} }
@@ -3565,6 +3586,14 @@ iface_get_carrier(const struct iface *iface)
/* XXX */ /* XXX */
return netdev_get_carrier(iface->netdev); return netdev_get_carrier(iface->netdev);
} }
/* Returns true if 'iface' is synthetic, that is, if we constructed it locally
* instead of obtaining it from the database. */
static bool
iface_is_synthetic(const struct iface *iface)
{
return ovsdb_idl_row_is_synthetic(&iface->cfg->header_);
}
/* Port mirroring. */ /* Port mirroring. */