From 672d18b29644302efa9fbc42a88cde80237d6dd8 Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Thu, 21 Apr 2011 13:55:45 -0700 Subject: [PATCH] bond: New bond-hash-basis setting. --- 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 ed6ed89b..d7242fae 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; @@ -978,6 +985,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"); @@ -1206,11 +1215,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) { @@ -1221,9 +1232,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); @@ -1355,13 +1375,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; @@ -1369,7 +1389,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 @@ -1378,8 +1398,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 b2ab89cd..5847abc1 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 84ed03e8..dee19a9b 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -3258,6 +3258,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 4c02f8a4..48825740 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 ce00cbd7..99f4fc40 100644 --- a/vswitchd/vswitch.xml +++ b/vswitchd/vswitch.xml @@ -647,6 +647,10 @@
The number of milliseconds between successive attempts to poll each interface's MII. Only relevant on ports which use miimon to detect failures.
+
bond-hash-basis
+
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.
lacp-system-id
The LACP system ID of this . The system ID of a LACP bond is used to identify itself to its partners. Must -- 2.30.2