#include "async-append.h"
#include "bfd.h"
#include "bitmap.h"
-#include "bond.h"
#include "cfm.h"
#include "coverage.h"
#include "daemon.h"
#include "ofp-print.h"
#include "ofp-util.h"
#include "ofpbuf.h"
+#include "ofproto/bond.h"
#include "ofproto/ofproto.h"
#include "poll-loop.h"
#include "sha1.h"
sset_destroy(&oso.targets);
}
+/* Returns whether a IPFIX row is valid. */
+static bool
+ovsrec_ipfix_is_valid(const struct ovsrec_ipfix *ipfix)
+{
+ return ipfix && ipfix->n_targets > 0;
+}
+
+/* Returns whether a Flow_Sample_Collector_Set row is valid. */
+static bool
+ovsrec_fscs_is_valid(const struct ovsrec_flow_sample_collector_set *fscs,
+ const struct bridge *br)
+{
+ return ovsrec_ipfix_is_valid(fscs->ipfix) && fscs->bridge == br->cfg;
+}
+
/* Set IPFIX configuration on 'br'. */
static void
bridge_configure_ipfix(struct bridge *br)
{
const struct ovsrec_ipfix *be_cfg = br->cfg->ipfix;
+ bool valid_be_cfg = ovsrec_ipfix_is_valid(be_cfg);
const struct ovsrec_flow_sample_collector_set *fe_cfg;
struct ofproto_ipfix_bridge_exporter_options be_opts;
struct ofproto_ipfix_flow_exporter_options *fe_opts = NULL;
size_t n_fe_opts = 0;
OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
- if (fe_cfg->bridge == br->cfg) {
+ if (ovsrec_fscs_is_valid(fe_cfg, br)) {
n_fe_opts++;
}
}
- if (!be_cfg && n_fe_opts == 0) {
+ if (!valid_be_cfg && n_fe_opts == 0) {
ofproto_set_ipfix(br->ofproto, NULL, NULL, 0);
return;
}
- if (be_cfg) {
+ if (valid_be_cfg) {
memset(&be_opts, 0, sizeof be_opts);
sset_init(&be_opts.targets);
fe_opts = xcalloc(n_fe_opts, sizeof *fe_opts);
opts = fe_opts;
OVSREC_FLOW_SAMPLE_COLLECTOR_SET_FOR_EACH(fe_cfg, idl) {
- if (fe_cfg->bridge == br->cfg) {
+ if (ovsrec_fscs_is_valid(fe_cfg, br)) {
opts->collector_set_id = fe_cfg->id;
sset_init(&opts->targets);
sset_add_array(&opts->targets, fe_cfg->ipfix->targets,
}
}
- ofproto_set_ipfix(br->ofproto, be_cfg ? &be_opts : NULL, fe_opts,
+ ofproto_set_ipfix(br->ofproto, valid_be_cfg ? &be_opts : NULL, fe_opts,
n_fe_opts);
- if (be_cfg) {
+ if (valid_be_cfg) {
sset_destroy(&be_opts.targets);
}
iface_set_netdev_config(const struct ovsrec_interface *iface_cfg,
struct netdev *netdev)
{
- int error;
-
- error = netdev_set_config(netdev, &iface_cfg->options);
- if (error) {
- VLOG_WARN("could not configure network device %s (%s)",
- iface_cfg->name, ovs_strerror(error));
- }
- return error;
+ return netdev_set_config(netdev, &iface_cfg->options);
}
/* This function determines whether 'ofproto_port', which is attached to
struct ofproto *ofproto = port->bridge->ofproto;
struct iface *iface;
struct ofproto_port_stp_status status;
- char *keys[3];
- int64_t int_values[3];
struct smap smap;
if (port_is_synthetic(port)) {
}
iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
-
if (ofproto_port_get_stp_status(ofproto, iface->ofp_port, &status)) {
return;
}
if (!status.enabled) {
ovsrec_port_set_status(port->cfg, NULL);
- ovsrec_port_set_statistics(port->cfg, NULL, NULL, 0);
return;
}
smap_add(&smap, "stp_role", stp_role_name(status.role));
ovsrec_port_set_status(port->cfg, &smap);
smap_destroy(&smap);
+}
+
+static void
+port_refresh_stp_stats(struct port *port)
+{
+ struct ofproto *ofproto = port->bridge->ofproto;
+ struct iface *iface;
+ struct ofproto_port_stp_stats stats;
+ char *keys[3];
+ int64_t int_values[3];
+
+ if (port_is_synthetic(port)) {
+ return;
+ }
+
+ /* STP doesn't currently support bonds. */
+ if (!list_is_singleton(&port->ifaces)) {
+ return;
+ }
+
+ iface = CONTAINER_OF(list_front(&port->ifaces), struct iface, port_elem);
+ if (ofproto_port_get_stp_stats(ofproto, iface->ofp_port, &stats)) {
+ return;
+ }
+
+ if (!stats.enabled) {
+ ovsrec_port_set_statistics(port->cfg, NULL, NULL, 0);
+ return;
+ }
/* Set Statistics column. */
keys[0] = "stp_tx_count";
- int_values[0] = status.tx_count;
+ int_values[0] = stats.tx_count;
keys[1] = "stp_rx_count";
- int_values[1] = status.rx_count;
+ int_values[1] = stats.rx_count;
keys[2] = "stp_error_count";
- int_values[2] = status.error_count;
+ int_values[2] = stats.error_count;
ovsrec_port_set_statistics(port->cfg, keys, int_values,
ARRAY_SIZE(int_values));
iface_refresh_stats(iface);
iface_refresh_status(iface);
}
+
+ port_refresh_stp_stats(port);
}
HMAP_FOR_EACH (m, hmap_node, &br->mirrors) {
{
static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
int n_tables;
- int i, j;
+ int i, j, k;
n_tables = ofproto_get_n_tables(br->ofproto);
j = 0;
s.max_flows = UINT_MAX;
s.groups = NULL;
s.n_groups = 0;
+ s.n_prefix_fields = 0;
+ memset(s.prefix_fields, ~0, sizeof(s.prefix_fields));
if (j < br->cfg->n_flow_tables && i == br->cfg->key_flow_tables[j]) {
struct ovsrec_flow_table *cfg = br->cfg->value_flow_tables[j++];
}
if (cfg->overflow_policy
&& !strcmp(cfg->overflow_policy, "evict")) {
- size_t k;
s.groups = xmalloc(cfg->n_groups * sizeof *s.groups);
for (k = 0; k < cfg->n_groups; k++) {
}
}
}
+ /* Prefix lookup fields. */
+ s.n_prefix_fields = 0;
+ for (k = 0; k < cfg->n_prefixes; k++) {
+ const char *name = cfg->prefixes[k];
+ const struct mf_field *mf = mf_from_name(name);
+ if (!mf) {
+ VLOG_WARN("bridge %s: 'prefixes' with unknown field: %s",
+ br->name, name);
+ continue;
+ }
+ if (mf->flow_be32ofs < 0 || mf->n_bits % 32) {
+ VLOG_WARN("bridge %s: 'prefixes' with incompatible field: "
+ "%s", br->name, name);
+ continue;
+ }
+ if (s.n_prefix_fields >= ARRAY_SIZE(s.prefix_fields)) {
+ VLOG_WARN("bridge %s: 'prefixes' with too many fields, "
+ "field not used: %s", br->name, name);
+ continue;
+ }
+ s.prefix_fields[s.n_prefix_fields++] = mf->id;
+ }
+ if (s.n_prefix_fields > 0) {
+ int k;
+ struct ds ds = DS_EMPTY_INITIALIZER;
+ for (k = 0; k < s.n_prefix_fields; k++) {
+ if (k) {
+ ds_put_char(&ds, ',');
+ }
+ ds_put_cstr(&ds, mf_from_id(s.prefix_fields[k])->name);
+ }
+ VLOG_INFO("bridge %s table %d: Prefix lookup with: %s.",
+ br->name, i, ds_cstr(&ds));
+ ds_destroy(&ds);
+ }
}
ofproto_configure_table(br->ofproto, i, &s);
static void
iface_set_ofport(const struct ovsrec_interface *if_cfg, ofp_port_t ofport)
{
- int64_t port_;
- port_ = (ofport == OFPP_NONE) ? -1 : ofp_to_u16(ofport);
if (if_cfg && !ovsdb_idl_row_is_synthetic(&if_cfg->header_)) {
- ovsrec_interface_set_ofport(if_cfg, &port_, 1);
+ int64_t port = ofport == OFPP_NONE ? -1 : ofp_to_u16(ofport);
+ ovsrec_interface_set_ofport(if_cfg, &port, 1);
}
}