projects
/
openvswitch
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
xenserver: Set fail_mode on internal bridges.
[openvswitch]
/
vswitchd
/
bridge.c
diff --git
a/vswitchd/bridge.c
b/vswitchd/bridge.c
index f786108cf19af16a4834fcabfb2b85b0978f12c9..9c614fb343d39e40b8a1ef96a8e27e6fbab5f64a 100644
(file)
--- a/
vswitchd/bridge.c
+++ b/
vswitchd/bridge.c
@@
-35,6
+35,7
@@
#include "cfm.h"
#include "classifier.h"
#include "coverage.h"
#include "cfm.h"
#include "classifier.h"
#include "coverage.h"
+#include "daemon.h"
#include "dirs.h"
#include "dpif.h"
#include "dynamic-string.h"
#include "dirs.h"
#include "dpif.h"
#include "dynamic-string.h"
@@
-75,13
+76,10
@@
VLOG_DEFINE_THIS_MODULE(bridge);
COVERAGE_DEFINE(bridge_flush);
COVERAGE_DEFINE(bridge_process_flow);
COVERAGE_DEFINE(bridge_flush);
COVERAGE_DEFINE(bridge_process_flow);
+COVERAGE_DEFINE(bridge_process_cfm);
+COVERAGE_DEFINE(bridge_process_lacp);
COVERAGE_DEFINE(bridge_reconfigure);
COVERAGE_DEFINE(bridge_reconfigure);
-
-enum lacp_status {
- LACP_STATUS_CURRENT, /* Partner is up to date. */
- LACP_STATUS_EXPIRED, /* Partner is out of date. Attempt to re-sync. */
- LACP_STATUS_DEFAULTED /* Partner information is unknown. */
-};
+COVERAGE_DEFINE(bridge_lacp_update);
struct dst {
uint16_t vlan;
struct dst {
uint16_t vlan;
@@
-98,6
+96,13
@@
static void dst_set_init(struct dst_set *);
static void dst_set_add(struct dst_set *, const struct dst *);
static void dst_set_free(struct dst_set *);
static void dst_set_add(struct dst_set *, const struct dst *);
static void dst_set_free(struct dst_set *);
+enum lacp_status {
+ LACP_CURRENT = 0x01, /* Current State. */
+ LACP_EXPIRED = 0x02, /* Expired State. */
+ LACP_DEFAULTED = 0x04, /* Partner is defaulted. */
+ LACP_ATTACHED = 0x08, /* Attached. Interface may be choosen for flows. */
+};
+
struct iface {
/* These members are always valid. */
struct port *port; /* Containing port. */
struct iface {
/* These members are always valid. */
struct port *port; /* Containing port. */
@@
-118,14
+123,12
@@
struct iface {
const struct ovsrec_interface *cfg;
/* LACP information. */
const struct ovsrec_interface *cfg;
/* LACP information. */
- enum lacp_status lacp_status; /* LACP stat
e machine stat
us. */
+ enum lacp_status lacp_status; /* LACP status. */
uint16_t lacp_priority; /* LACP port priority. */
struct lacp_info lacp_actor; /* LACP actor information. */
struct lacp_info lacp_partner; /* LACP partner information. */
long long int lacp_tx; /* Next LACP message transmission time. */
long long int lacp_rx; /* Next LACP message receive time. */
uint16_t lacp_priority; /* LACP port priority. */
struct lacp_info lacp_actor; /* LACP actor information. */
struct lacp_info lacp_partner; /* LACP partner information. */
long long int lacp_tx; /* Next LACP message transmission time. */
long long int lacp_rx; /* Next LACP message receive time. */
- bool lacp_attached; /* Attached to its aggregator? LACP allows
- this link to be chosen for flows. */
};
#define BOND_MASK 0xff
};
#define BOND_MASK 0xff
@@
-933,6
+936,10
@@
bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg)
}
free(managers);
}
free(managers);
+
+ /* ovs-vswitchd has completed initialization, so allow the process that
+ * forked us to exit successfully. */
+ daemonize_complete();
}
static const char *
}
static const char *
@@
-2157,7
+2164,7
@@
bond_choose_iface(const struct port *port)
if (iface->enabled) {
return i;
} else if (iface->delay_expires < next_delay_expiration
if (iface->enabled) {
return i;
} else if (iface->delay_expires < next_delay_expiration
- && (iface->lacp_
attached
+ && (iface->lacp_
status & LACP_ATTACHED
|| !(port->lacp & LACP_NEGOTIATED))) {
best_down_slave = i;
next_delay_expiration = iface->delay_expires;
|| !(port->lacp & LACP_NEGOTIATED))) {
best_down_slave = i;
next_delay_expiration = iface->delay_expires;
@@
-2235,9
+2242,9
@@
bond_link_status_update(struct iface *iface)
* They are not required to have synchronized partners because they
* have no partners at all. However, they will only be attached if
* negotiations failed on all interfaces in the bond. */
* They are not required to have synchronized partners because they
* have no partners at all. However, they will only be attached if
* negotiations failed on all interfaces in the bond. */
- up = iface->lacp_
attached
+ up = iface->lacp_
status & LACP_ATTACHED
&& (iface->lacp_partner.state & LACP_STATE_SYNC
&& (iface->lacp_partner.state & LACP_STATE_SYNC
- || iface->lacp_status
== LACP_STATUS
_DEFAULTED);
+ || iface->lacp_status
& LACP
_DEFAULTED);
}
}
@@
-2380,7
+2387,7
@@
bond_link_carrier_update(struct iface *iface, bool carrier)
return;
}
return;
}
- if (iface->lacp_status
== LACP_STATUS
_CURRENT) {
+ if (iface->lacp_status
& LACP
_CURRENT) {
iface_set_lacp_expired(iface);
}
iface_set_lacp_expired(iface);
}
@@
-3000,26
+3007,38
@@
bridge_normal_ofhook_cb(const struct flow *flow, const struct ofpbuf *packet,
struct ofpbuf *actions, tag_type *tags,
uint16_t *nf_output_iface, void *br_)
{
struct ofpbuf *actions, tag_type *tags,
uint16_t *nf_output_iface, void *br_)
{
- struct iface *iface;
struct bridge *br = br_;
COVERAGE_INC(bridge_process_flow);
struct bridge *br = br_;
COVERAGE_INC(bridge_process_flow);
+ return process_flow(br, flow, packet, actions, tags, nf_output_iface);
+}
+
+static bool
+bridge_special_ofhook_cb(const struct flow *flow,
+ const struct ofpbuf *packet, void *br_)
+{
+ struct iface *iface;
+ struct bridge *br = br_;
iface = iface_from_dp_ifidx(br, flow->in_port);
if (cfm_should_process_flow(flow)) {
iface = iface_from_dp_ifidx(br, flow->in_port);
if (cfm_should_process_flow(flow)) {
- if (packet && iface->cfm) {
+
+ if (iface && packet && iface->cfm) {
+ COVERAGE_INC(bridge_process_cfm);
cfm_process_heartbeat(iface->cfm, packet);
}
return false;
} else if (flow->dl_type == htons(ETH_TYPE_LACP)) {
cfm_process_heartbeat(iface->cfm, packet);
}
return false;
} else if (flow->dl_type == htons(ETH_TYPE_LACP)) {
- if (packet) {
+
+ if (iface && packet) {
+ COVERAGE_INC(bridge_process_lacp);
lacp_process_packet(packet, iface);
}
return false;
}
lacp_process_packet(packet, iface);
}
return false;
}
- return
process_flow(br, flow, packet, actions, tags, nf_output_iface)
;
+ return
true
;
}
static void
}
static void
@@
-3089,6
+3108,7
@@
bridge_account_checkpoint_ofhook_cb(void *br_)
static struct ofhooks bridge_ofhooks = {
bridge_normal_ofhook_cb,
static struct ofhooks bridge_ofhooks = {
bridge_normal_ofhook_cb,
+ bridge_special_ofhook_cb,
bridge_account_flow_ofhook_cb,
bridge_account_checkpoint_ofhook_cb,
};
bridge_account_flow_ofhook_cb,
bridge_account_checkpoint_ofhook_cb,
};
@@
-3109,7
+3129,8
@@
lacp_process_packet(const struct ofpbuf *packet, struct iface *iface)
return;
}
return;
}
- iface->lacp_status = LACP_STATUS_CURRENT;
+ iface->lacp_status |= LACP_CURRENT;
+ iface->lacp_status &= ~(LACP_EXPIRED | LACP_DEFAULTED);
iface->lacp_rx = time_msec() + LACP_SLOW_TIME_RX;
iface->lacp_actor.state = iface_get_lacp_state(iface);
iface->lacp_rx = time_msec() + LACP_SLOW_TIME_RX;
iface->lacp_actor.state = iface_get_lacp_state(iface);
@@
-3129,32
+3150,35
@@
lacp_update_ifaces(struct port *port)
size_t i;
struct iface *lead;
struct lacp_info lead_pri;
size_t i;
struct iface *lead;
struct lacp_info lead_pri;
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 10);
port->lacp_need_update = false;
port->lacp_need_update = false;
+ COVERAGE_INC(bridge_lacp_update);
if (!port->lacp) {
return;
}
if (!port->lacp) {
return;
}
+ VLOG_DBG_RL(&rl, "port %s: re-evaluating LACP link status", port->name);
+
lead = NULL;
for (i = 0; i < port->n_ifaces; i++) {
struct iface *iface = port->ifaces[i];
struct lacp_info pri;
lead = NULL;
for (i = 0; i < port->n_ifaces; i++) {
struct iface *iface = port->ifaces[i];
struct lacp_info pri;
- iface->lacp_
attached = true
;
+ iface->lacp_
status |= LACP_ATTACHED
;
ofproto_revalidate(port->bridge->ofproto, iface->tag);
/* Don't allow loopback interfaces to send traffic or lead. */
if (eth_addr_equals(iface->lacp_partner.sysid,
iface->lacp_actor.sysid)) {
ofproto_revalidate(port->bridge->ofproto, iface->tag);
/* Don't allow loopback interfaces to send traffic or lead. */
if (eth_addr_equals(iface->lacp_partner.sysid,
iface->lacp_actor.sysid)) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 10);
VLOG_WARN_RL(&rl, "iface %s: Loopback detected. Interface is "
"connected to its own bridge", iface->name);
VLOG_WARN_RL(&rl, "iface %s: Loopback detected. Interface is "
"connected to its own bridge", iface->name);
- iface->lacp_
attached = false
;
+ iface->lacp_
status &= ~LACP_ATTACHED
;
continue;
}
continue;
}
- if (iface->lacp_status
== LACP_STATUS
_DEFAULTED) {
+ if (iface->lacp_status
& LACP
_DEFAULTED) {
continue;
}
continue;
}
@@
-3176,11
+3200,11
@@
lacp_update_ifaces(struct port *port)
for (i = 0; i < port->n_ifaces; i++) {
struct iface *iface = port->ifaces[i];
for (i = 0; i < port->n_ifaces; i++) {
struct iface *iface = port->ifaces[i];
- if (iface->lacp_status
== LACP_STATUS
_DEFAULTED
+ if (iface->lacp_status
& LACP
_DEFAULTED
|| lead->lacp_partner.key != iface->lacp_partner.key
|| !eth_addr_equals(lead->lacp_partner.sysid,
iface->lacp_partner.sysid)) {
|| lead->lacp_partner.key != iface->lacp_partner.key
|| !eth_addr_equals(lead->lacp_partner.sysid,
iface->lacp_partner.sysid)) {
- iface->lacp_
attached = false
;
+ iface->lacp_
status &= ~LACP_ATTACHED
;
}
}
}
}
}
}
@@
-3189,7
+3213,7
@@
static bool
lacp_iface_may_tx(const struct iface *iface)
{
return iface->port->lacp & LACP_ACTIVE
lacp_iface_may_tx(const struct iface *iface)
{
return iface->port->lacp & LACP_ACTIVE
- || iface->lacp_status
!= LACP_STATUS_DEFAULTED
;
+ || iface->lacp_status
& (LACP_CURRENT | LACP_EXPIRED)
;
}
static void
}
static void
@@
-3211,9
+3235,9
@@
lacp_run(struct bridge *br)
struct iface *iface = port->ifaces[j];
if (time_msec() > iface->lacp_rx) {
struct iface *iface = port->ifaces[j];
if (time_msec() > iface->lacp_rx) {
- if (iface->lacp_status
== LACP_STATUS
_CURRENT) {
+ if (iface->lacp_status
& LACP
_CURRENT) {
iface_set_lacp_expired(iface);
iface_set_lacp_expired(iface);
- } else if (iface->lacp_status
== LACP_STATUS
_EXPIRED) {
+ } else if (iface->lacp_status
& LACP
_EXPIRED) {
iface_set_lacp_defaulted(iface);
}
}
iface_set_lacp_defaulted(iface);
}
}
@@
-3272,7
+3296,7
@@
lacp_wait(struct bridge *br)
poll_timer_wait_until(iface->lacp_tx);
}
poll_timer_wait_until(iface->lacp_tx);
}
- if (iface->lacp_status
!= LACP_STATUS_DEFAULTED
) {
+ if (iface->lacp_status
& (LACP_CURRENT | LACP_EXPIRED)
) {
poll_timer_wait_until(iface->lacp_rx);
}
}
poll_timer_wait_until(iface->lacp_rx);
}
}
@@
-3778,10
+3802,10
@@
bond_unixctl_show(struct unixctl_conn *conn,
bond_mode_to_string(port->bond_mode));
if (port->lacp) {
bond_mode_to_string(port->bond_mode));
if (port->lacp) {
- ds_put_format(&ds, "
\t
lacp: %s\n",
+ ds_put_format(&ds, "lacp: %s\n",
port->lacp & LACP_ACTIVE ? "active" : "passive");
} else {
port->lacp & LACP_ACTIVE ? "active" : "passive");
} else {
- ds_put_cstr(&ds, "
\t
lacp: off\n");
+ ds_put_cstr(&ds, "lacp: off\n");
}
if (port->bond_mode != BM_AB) {
}
if (port->bond_mode != BM_AB) {
@@
-3812,7
+3836,7
@@
bond_unixctl_show(struct unixctl_conn *conn,
struct flow flow;
/* Basic info. */
struct flow flow;
/* Basic info. */
- ds_put_format(&ds, "slave %s: %s\n",
+ ds_put_format(&ds, "
\n
slave %s: %s\n",
iface->name, iface->enabled ? "enabled" : "disabled");
if (j == port->active_iface) {
ds_put_cstr(&ds, "\tactive slave\n");
iface->name, iface->enabled ? "enabled" : "disabled");
if (j == port->active_iface) {
ds_put_cstr(&ds, "\tactive slave\n");
@@
-3826,15
+3850,19
@@
bond_unixctl_show(struct unixctl_conn *conn,
if (port->lacp) {
ds_put_cstr(&ds, "\tstatus: ");
if (port->lacp) {
ds_put_cstr(&ds, "\tstatus: ");
- if (iface->lacp_status
== LACP_STATUS
_CURRENT) {
+ if (iface->lacp_status
& LACP
_CURRENT) {
ds_put_cstr(&ds, "current ");
ds_put_cstr(&ds, "current ");
- } else if (iface->lacp_status == LACP_STATUS_EXPIRED) {
+ }
+
+ if (iface->lacp_status & LACP_EXPIRED) {
ds_put_cstr(&ds, "expired ");
ds_put_cstr(&ds, "expired ");
- } else {
+ }
+
+ if (iface->lacp_status & LACP_DEFAULTED) {
ds_put_cstr(&ds, "defaulted ");
}
ds_put_cstr(&ds, "defaulted ");
}
- if (iface->lacp_
attached
) {
+ if (iface->lacp_
status & LACP_ATTACHED
) {
ds_put_cstr(&ds, "attached ");
}
ds_put_cstr(&ds, "attached ");
}
@@
-3880,7
+3908,7
@@
bond_unixctl_show(struct unixctl_conn *conn,
ds_put_cstr(&ds, "\tpartner state: ");
ds_put_lacp_state(&ds, iface->lacp_partner.state);
ds_put_cstr(&ds, "\tpartner state: ");
ds_put_lacp_state(&ds, iface->lacp_partner.state);
- ds_put_cstr(&ds, "\n
\n
");
+ ds_put_cstr(&ds, "\n");
}
if (port->bond_mode == BM_AB) {
}
if (port->bond_mode == BM_AB) {
@@
-4469,6
+4497,9
@@
port_update_lacp(struct port *port)
bool key_changed;
if (!port->lacp || port->n_ifaces < 1) {
bool key_changed;
if (!port->lacp || port->n_ifaces < 1) {
+ for (i = 0; i < port->n_ifaces; i++) {
+ iface_set_lacp_defaulted(port->ifaces[i]);
+ }
return;
}
return;
}
@@
-4670,10
+4701,10
@@
port_update_vlan_compat(struct port *port)
static void
iface_set_lacp_defaulted(struct iface *iface)
{
static void
iface_set_lacp_defaulted(struct iface *iface)
{
- memset(&iface->lacp_partner, 0xff, sizeof iface->lacp_partner);
- iface->lacp_partner.state = 0;
+ memset(&iface->lacp_partner, 0, sizeof iface->lacp_partner);
- iface->lacp_status = LACP_STATUS_DEFAULTED;
+ iface->lacp_status |= LACP_DEFAULTED;
+ iface->lacp_status &= ~(LACP_CURRENT | LACP_EXPIRED);
iface->lacp_tx = 0;
iface->port->lacp_need_update = true;
}
iface->lacp_tx = 0;
iface->port->lacp_need_update = true;
}
@@
-4681,7
+4712,8
@@
iface_set_lacp_defaulted(struct iface *iface)
static void
iface_set_lacp_expired(struct iface *iface)
{
static void
iface_set_lacp_expired(struct iface *iface)
{
- iface->lacp_status = LACP_STATUS_EXPIRED;
+ iface->lacp_status &= ~LACP_CURRENT;
+ iface->lacp_status |= LACP_EXPIRED;
iface->lacp_partner.state |= LACP_STATE_TIME;
iface->lacp_partner.state &= ~LACP_STATE_SYNC;
iface->lacp_partner.state |= LACP_STATE_TIME;
iface->lacp_partner.state &= ~LACP_STATE_SYNC;
@@
-4698,13
+4730,15
@@
iface_get_lacp_state(const struct iface *iface)
state |= LACP_STATE_ACT;
}
state |= LACP_STATE_ACT;
}
- if (iface->lacp_status == LACP_STATUS_DEFAULTED) {
- state |= LACP_STATE_DEF;
- } else if (iface->lacp_attached) {
+ if (iface->lacp_status & LACP_ATTACHED) {
state |= LACP_STATE_SYNC;
}
state |= LACP_STATE_SYNC;
}
- if (iface->lacp_status == LACP_STATUS_EXPIRED) {
+ if (iface->lacp_status & LACP_DEFAULTED) {
+ state |= LACP_STATE_DEF;
+ }
+
+ if (iface->lacp_status & LACP_EXPIRED) {
state |= LACP_STATE_EXP;
}
state |= LACP_STATE_EXP;
}