[ovs-dev] [stable 3/3] bond: New bonding mode "stable".
Ethan Jackson
ethan at nicira.com
Thu Apr 14 17:58:35 UTC 2011
Here is an incremental on the previous version. Compile tested only.
---
lib/bond.c | 48 +++++++++++++++++++++++++++---------------------
lib/bond.h | 2 +-
vswitchd/vswitch.xml | 24 ++++++++++++++++--------
3 files changed, 44 insertions(+), 30 deletions(-)
diff --git a/lib/bond.c b/lib/bond.c
index cfb0ff9..f1a8a34 100644
--- a/lib/bond.c
+++ b/lib/bond.c
@@ -75,8 +75,10 @@ struct bond_slave {
struct list entries; /* 'struct bond_entry's assigned here. */
uint64_t tx_bytes; /* Sum across 'tx_bytes' of entries. */
- /* BM_STB specific bonding info. */
- size_t stb_idx;
+ /* BM_STABLE specific bonding info. */
+ size_t stb_idx; /* Index in 'bond''s 'stb_slaves' array.
+ Undefined value if participating in a
+ BTM_STABLE bond or not enabled. */
};
/* A bond, that is, a set of network devices grouped to improve performance or
@@ -100,7 +102,7 @@ struct bond {
long long int next_rebalance; /* Next rebalancing time. */
bool send_learning_packets;
- /* BM_STB specific bonding info. */
+ /* BM_STABLE specific bonding info. */
struct bond_slave **stb_slaves; /* Ordered list of enabled slaves. */
size_t n_stb_slaves; /* Number of slaves in 'stb_slaves'. */
size_t len_stb_slaves; /* Slaves allocated in 'stb_slaves'. */
@@ -158,8 +160,8 @@ bond_mode_from_string(enum bond_mode *balance, const char *s)
*balance = BM_TCP;
} else if (!strcmp(s, bond_mode_to_string(BM_SLB))) {
*balance = BM_SLB;
- } else if (!strcmp(s, bond_mode_to_string(BM_STB))) {
- *balance = BM_STB;
+ } else if (!strcmp(s, bond_mode_to_string(BM_STABLE))) {
+ *balance = BM_STABLE;
} else if (!strcmp(s, bond_mode_to_string(BM_AB))) {
*balance = BM_AB;
} else {
@@ -176,7 +178,7 @@ bond_mode_to_string(enum bond_mode balance) {
return "balance-tcp";
case BM_SLB:
return "balance-slb";
- case BM_STB:
+ case BM_STABLE:
return "stable";
case BM_AB:
return "active-backup";
@@ -339,16 +341,15 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s)
bond->next_fake_iface_update = LLONG_MAX;
}
- if (bond->balance != BM_STB) {
+ if (bond->balance != BM_STABLE) {
free(bond->stb_slaves);
bond->stb_slaves = NULL;
} else if (!bond->stb_slaves) {
struct bond_slave *slave;
bond->n_stb_slaves = 0;
- bond->len_stb_slaves = (hmap_count(&bond->slaves) + 1) * 2;
- bond->stb_slaves = xmalloc(bond->len_stb_slaves
- * sizeof *bond->stb_slaves);
+ bond->len_stb_slaves = 0;
+ bond->stb_slaves = NULL;
HMAP_FOR_EACH (slave, hmap_node, &bond->slaves) {
if (slave->enabled) {
@@ -1349,8 +1350,10 @@ bond_is_link_up(struct bond *bond, struct netdev *netdev)
static int
bond_stb_sort_cmp__(const void *a_, const void *b_)
{
- const struct bond_slave *a = *(struct bond_slave **)a_;
- const struct bond_slave *b = *(struct bond_slave **)b_;
+ const struct bond_slave *const *ap = a_;
+ const struct bond_slave *const *bp = b_;
+ const struct bond_slave *a = *ap;
+ const struct bond_slave *b = *bp;
struct lacp *lacp = a->bond->lacp;
int a_id, b_id;
@@ -1362,7 +1365,7 @@ bond_stb_sort_cmp__(const void *a_, const void *b_)
b_id = netdev_get_ifindex(b->netdev);
}
- return a_id - b_id;
+ return (a_id == b_id ? 0 : (a_id < b_id ? -1 : 1));
}
static bool
@@ -1398,10 +1401,9 @@ bond_stb_enable_slave(struct bond_slave *slave)
if (slave->enabled) {
if (bond->len_stb_slaves <= bond->n_stb_slaves) {
- bond->len_stb_slaves *= 2;
- bond->stb_slaves = xrealloc(bond->stb_slaves,
- bond->len_stb_slaves
- * sizeof *bond->stb_slaves);
+ bond->stb_slaves = x2nrealloc(bond->stb_slaves,
+ &bond->len_stb_slaves,
+ sizeof *bond->stb_slaves);
}
slave->stb_idx = bond->n_stb_slaves++;
@@ -1470,7 +1472,7 @@ bond_link_status_update(struct bond_slave *slave, struct tag_set *tags)
static bool
bond_is_tcp_hash(const struct bond *bond)
{
- return (bond->balance == BM_TCP || bond->balance == BM_STB)
+ return (bond->balance == BM_TCP || bond->balance == BM_STABLE)
&& lacp_negotiated(bond->lacp);
}
@@ -1518,9 +1520,13 @@ choose_output_slave(const struct bond *bond, const struct flow *flow,
switch (bond->balance) {
case BM_AB:
return bond->active_slave;
- case BM_STB:
- return bond->stb_slaves[bond_hash(bond, flow, vlan)
- % bond->n_stb_slaves];
+ case BM_STABLE:
+ if (bond->n_stb_slaves) {
+ return bond->stb_slaves[bond_hash(bond, flow, vlan)
+ % bond->n_stb_slaves];
+ } else {
+ return bond->active_slave;
+ }
case BM_SLB:
case BM_TCP:
e = lookup_bond_entry(bond, flow, vlan);
diff --git a/lib/bond.h b/lib/bond.h
index 9a7eb7e..1e8ea7e 100644
--- a/lib/bond.h
+++ b/lib/bond.h
@@ -32,7 +32,7 @@ struct ofpbuf;
enum bond_mode {
BM_TCP, /* Transport Layer Load Balance. */
BM_SLB, /* Source Load Balance. */
- BM_STB, /* Stable. */
+ BM_STABLE, /* Stable. */
BM_AB /* Active Backup. */
};
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 492affa..f2c07a5 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -515,25 +515,33 @@
</dd>
</dl>
+ <p>
+ The following modes require the upstream switch to support 802.3ad with
+ successful LACP negotiation. If LACP negotiation fails then
+ <code>balance-slb</code> style flow hashing is used as a fallback:
+ </p>
+
<dl>
<dt><code>balance-tcp</code></dt>
<dd>
Balances flows among slaves based on L2, L3, and L4 protocol
information such as destination MAC address, IP address, and TCP
- port. Requires successful negotiations with an upstream switch that
- supports 802.3ad LACP. If negotiations are unsuccessful, falls back
- to <code>balance-slb</code>.
+ port.
</dd>
</dl>
<dl>
<dt><code>stable</code></dt>
<dd>
- Attempts to always assign a given flow to the same slave
- consistently. In an effort to maintain stability, no load balancing
- is done. Uses a similar hashing strategy to
- <code>balance-tcp</code>, falling back to <code>balance-slb</code>
- style hashing when LACP negotiations are unsuccessful.
+ <p>Attempts to always assign a given flow to the same slave
+ consistently. In an effort to maintain stability, no load
+ balancing is done. Uses a similar hashing strategy to
+ <code>balance-tcp</code>, falling back to <code>balance-slb</code>
+ style hashing when LACP negotiations are unsuccessful.</p>
+ <p>Slave selection decisions are made based on LACP port ID when LACP
+ negotiations are successful, falling back to openflow port number
+ when unsuccessful. Thus, decisions are consistent across all
+ ovs-vswitchd instances with equivalent port IDs.</p>
</dd>
</dl>
--
1.7.4.2
More information about the dev
mailing list