[ovs-dev] [PATCH] bond: New bond-hash-basis setting.
Ethan Jackson
ethan at nicira.com
Mon Apr 25 22:00:46 UTC 2011
---
lib/bond.c | 40 ++++++++++++++++++++++++++++++----------
lib/bond.h | 1 +
vswitchd/bridge.c | 2 ++
vswitchd/ovs-vswitchd.8.in | 4 ++--
vswitchd/vswitch.xml | 4 ++++
5 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/lib/bond.c b/lib/bond.c
index 4d7d05a..30d50c8 100644
--- a/lib/bond.c
+++ b/lib/bond.c
@@ -93,6 +93,7 @@ struct bond {
int updelay, downdelay; /* Delay before slave goes up/down, in ms. */
bool lacp_negotiated; /* LACP negotiations were successful. */
bool bond_revalidate; /* True if flows need revalidation. */
+ uint32_t basis; /* Basis for flow hash function. */
/* SLB specific bonding info. */
struct bond_entry *hash; /* An array of (BOND_MASK + 1) elements. */
@@ -129,8 +130,9 @@ static void bond_link_status_update(struct bond_slave *, struct tag_set *);
static void bond_choose_active_slave(struct bond *, struct tag_set *);
static bool bond_is_tcp_hash(const struct bond *);
static unsigned int bond_hash_src(const uint8_t mac[ETH_ADDR_LEN],
- uint16_t vlan);
-static unsigned int bond_hash_tcp(const struct flow *, uint16_t vlan);
+ uint16_t vlan, uint32_t basis);
+static unsigned int bond_hash_tcp(const struct flow *, uint16_t vlan,
+ uint32_t basis);
static struct bond_entry *lookup_bond_entry(const struct bond *,
const struct flow *,
uint16_t vlan);
@@ -291,6 +293,11 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s)
revalidate = true;
}
+ if (bond->basis != s->basis) {
+ bond->basis = s->basis;
+ revalidate = true;
+ }
+
if (bond->detect == BLSM_CARRIER) {
struct bond_slave *slave;
@@ -965,6 +972,8 @@ bond_unixctl_show(struct unixctl_conn *conn,
bond_is_tcp_hash(bond) ? "balance-tcp" : "balance-slb");
}
+ ds_put_format(&ds, "bond-hash-basis: %"PRIu32"\n", bond->basis);
+
ds_put_format(&ds, "bond-detect-mode: %s\n",
bond->monitor ? "carrier" : "miimon");
@@ -1193,11 +1202,13 @@ bond_unixctl_hash(struct unixctl_conn *conn, const char *args_,
uint8_t hash;
char *hash_cstr;
unsigned int vlan;
- char *mac_s, *vlan_s;
+ uint32_t basis;
+ char *mac_s, *vlan_s, *basis_s;
char *save_ptr = NULL;
mac_s = strtok_r(args, " ", &save_ptr);
vlan_s = strtok_r(NULL, " ", &save_ptr);
+ basis_s = strtok_r(NULL, " ", &save_ptr);
if (vlan_s) {
if (sscanf(vlan_s, "%u", &vlan) != 1) {
@@ -1208,9 +1219,18 @@ bond_unixctl_hash(struct unixctl_conn *conn, const char *args_,
vlan = OFP_VLAN_NONE;
}
+ if (basis_s) {
+ if (sscanf(basis_s, "%"PRIu32, &basis) != 1) {
+ unixctl_command_reply(conn, 501, "invalid basis");
+ return;
+ }
+ } else {
+ basis = 0;
+ }
+
if (sscanf(mac_s, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(mac))
== ETH_ADDR_SCAN_COUNT) {
- hash = bond_hash_src(mac, vlan) & BOND_MASK;
+ hash = bond_hash_src(mac, vlan, basis) & BOND_MASK;
hash_cstr = xasprintf("%u", hash);
unixctl_command_reply(conn, 200, hash_cstr);
@@ -1342,13 +1362,13 @@ bond_is_tcp_hash(const struct bond *bond)
}
static unsigned int
-bond_hash_src(const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan)
+bond_hash_src(const uint8_t mac[ETH_ADDR_LEN], uint16_t vlan, uint32_t basis)
{
- return hash_bytes(mac, ETH_ADDR_LEN, vlan);
+ return hash_3words(hash_bytes(mac, ETH_ADDR_LEN, 0), vlan, basis);
}
static unsigned int
-bond_hash_tcp(const struct flow *flow, uint16_t vlan)
+bond_hash_tcp(const struct flow *flow, uint16_t vlan, uint32_t basis)
{
struct flow hash_flow = *flow;
hash_flow.vlan_tci = vlan;
@@ -1356,7 +1376,7 @@ bond_hash_tcp(const struct flow *flow, uint16_t vlan)
/* The symmetric quality of this hash function is not required, but
* flow_hash_symmetric_l4 already exists, and is sufficient for our
* purposes, so we use it out of convenience. */
- return flow_hash_symmetric_l4(&hash_flow, 0);
+ return flow_hash_symmetric_l4(&hash_flow, basis);
}
static unsigned int
@@ -1365,8 +1385,8 @@ bond_hash(const struct bond *bond, const struct flow *flow, uint16_t vlan)
assert(bond->balance != BM_AB);
return (bond_is_tcp_hash(bond)
- ? bond_hash_tcp(flow, vlan)
- : bond_hash_src(flow->dl_src, vlan));
+ ? bond_hash_tcp(flow, vlan, bond->basis)
+ : bond_hash_src(flow->dl_src, vlan, bond->basis));
}
static struct bond_entry *
diff --git a/lib/bond.h b/lib/bond.h
index b2ab89c..5847abc 100644
--- a/lib/bond.h
+++ b/lib/bond.h
@@ -50,6 +50,7 @@ const char *bond_detect_mode_to_string(enum bond_detect_mode);
/* Configuration for a bond as a whole. */
struct bond_settings {
char *name; /* Bond's name, for log messages. */
+ uint32_t basis; /* Flow hashing basis. */
/* Balancing configuration. */
enum bond_mode balance;
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index 2b8b248..a64ac34 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -3225,6 +3225,8 @@ port_reconfigure_bond(struct port *port)
s.up_delay = MAX(0, port->cfg->bond_updelay);
s.down_delay = MAX(0, port->cfg->bond_downdelay);
+ s.basis = atoi(get_port_other_config(port->cfg, "bond-hash-basis", "0"));
+
s.rebalance_interval = atoi(
get_port_other_config(port->cfg, "bond-rebalance-interval", "10000"));
if (s.rebalance_interval < 1000) {
diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
index 4c02f8a..4882574 100644
--- a/vswitchd/ovs-vswitchd.8.in
+++ b/vswitchd/ovs-vswitchd.8.in
@@ -182,9 +182,9 @@ updelay (or downdelay).
.IP
This setting is not permanent: it persists only until the carrier
status of \fIslave\fR changes.
-.IP "\fBbond/hash\fR \fImac\fR [\fIvlan\fR]"
+.IP "\fBbond/hash\fR \fImac\fR [\fIvlan\fR] [\fIbasis\fR]"
Returns the hash value which would be used for \fImac\fR with \fIvlan\fR
-if specified.
+and \fIbasis\fR if specified.
.
.IP "\fBlacp/show\fR \fIport\fR"
Lists all of the LACP related information about the given \fIport\fR:
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index 4cdc1b1..2f0ed3b 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -647,6 +647,10 @@
<dd> The number of milliseconds between successive attempts to
poll each interface's MII. Only relevant on ports which use
<code>miimon</code> to detect failures. </dd>
+ <dt><code>bond-hash-basis</code></dt>
+ <dd> An integer hashed along with flows when choosing output slaves.
+ When changed, all flows will be assigned different hash values
+ possibly causing slave selection decisions to change.</dd>
<dt><code>lacp-system-id</code></dt>
<dd> The LACP system ID of this <ref table="Port"/>. The system ID
of a LACP bond is used to identify itself to its partners. Must
--
1.7.4.2
More information about the dev
mailing list