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:
@@ -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. */
|
||||||
|
|
||||||
|
@@ -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. */
|
||||||
|
|
||||||
|
@@ -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. */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user