[libteam] Add fallback support for single-member-port LAG (#1118)
* [libteam] Add fallback support for single-member-port LAG * Allow the port to be selected if the LAG is configured with fallback and port is in defaulted state due to missing LACP PDUs from remote end * Only enable port if LAG is admin up and the member port is link up * [team] Add lacp fallback config to teamd.j2 template * [teamd] Resolve config conflict between fallback and minlink * Remove min_link config if fallback is configured * Add support for fallback config in minigraph * [teamd] Only enable fallback if it is single-member-port LAG Signed-off-by: Haiyang Zheng <haiyang.z@alibaba-inc.com> * [teamd] Removing the admin status check in lacp_port_link_update Will submit another pull request to fix this issue. Signed-off-by: Haiyang Zheng <haiyang.z@alibaba-inc.com>
This commit is contained in:
parent
46a653485c
commit
2abdf8dc58
@ -4,8 +4,12 @@
|
||||
"runner": {
|
||||
"name": "lacp",
|
||||
"active": true,
|
||||
{% if PORTCHANNEL[pc]['fallback'] and ((PORTCHANNEL[pc]['members'] | length) == 1) %}
|
||||
"fallback": {{ PORTCHANNEL[pc]['fallback'] }},
|
||||
{% else %}
|
||||
{# Use 75% links upperbound as min-links #}
|
||||
"min_ports": {{ (PORTCHANNEL[pc]['members'] | length * 0.75) | round(0, 'ceil') | int }},
|
||||
{% endif %}
|
||||
"tx_hash": ["eth", "ipv4", "ipv6"]
|
||||
},
|
||||
"link_watch": {
|
||||
|
@ -0,0 +1,104 @@
|
||||
From ec966f9a0229bd7226e3abe15b56659b36af9d66 Mon Sep 17 00:00:00 2001
|
||||
From: Haiyang Zheng <haiyang.z@alibaba-inc.com>
|
||||
Date: Fri, 15 Dec 2017 21:07:53 -0800
|
||||
Subject: [patch libteam] [libteam] Add fallback support for single-member-port
|
||||
LAG
|
||||
|
||||
Signed-off-by: Haiyang Zheng <haiyang.z@alibaba-inc.com>
|
||||
---
|
||||
teamd/teamd_runner_lacp.c | 42 ++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 40 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
|
||||
index 9c77fae..a3646a6 100644
|
||||
--- a/teamd/teamd_runner_lacp.c
|
||||
+++ b/teamd/teamd_runner_lacp.c
|
||||
@@ -138,6 +138,8 @@ struct lacp {
|
||||
#define LACP_CFG_DFLT_SYS_PRIO 0xffff
|
||||
bool fast_rate;
|
||||
#define LACP_CFG_DFLT_FAST_RATE false
|
||||
+ bool fallback;
|
||||
+#define LACP_CFG_DFLT_FALLBACK false
|
||||
int min_ports;
|
||||
#define LACP_CFG_DFLT_MIN_PORTS 1
|
||||
enum lacp_agg_select_policy agg_select_policy;
|
||||
@@ -272,6 +274,11 @@ static int lacp_load_config(struct teamd_context *ctx, struct lacp *lacp)
|
||||
lacp->cfg.fast_rate = LACP_CFG_DFLT_FAST_RATE;
|
||||
teamd_log_dbg("Using fast_rate \"%d\".", lacp->cfg.fast_rate);
|
||||
|
||||
+ err = teamd_config_bool_get(ctx, &lacp->cfg.fallback, "$.runner.fallback");
|
||||
+ if (err)
|
||||
+ lacp->cfg.fallback = LACP_CFG_DFLT_FALLBACK;
|
||||
+ teamd_log_dbg("Using fallback \"%d\".", lacp->cfg.fallback);
|
||||
+
|
||||
err = teamd_config_int_get(ctx, &tmp, "$.runner.min_ports");
|
||||
if (err) {
|
||||
lacp->cfg.min_ports = LACP_CFG_DFLT_MIN_PORTS;
|
||||
@@ -308,9 +315,24 @@ static bool lacp_port_loopback_free(struct lacp_port *lacp_port)
|
||||
return true;
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * is_lacp_fallback_eligible - is lacp_port eligible to go into lacp fallback mode
|
||||
+ *
|
||||
+ * Return true if it is, false otherwise
|
||||
+ */
|
||||
+static bool is_lacp_fallback_eligible(struct lacp_port *lacp_port)
|
||||
+{
|
||||
+ teamd_log_dbg("%s fallback eligible state \"%d \" cfg \"%d\".",
|
||||
+ lacp_port->tdport->ifname, lacp_port->state,
|
||||
+ lacp_port->lacp->cfg.fallback);
|
||||
+ return lacp_port->state == PORT_STATE_DEFAULTED &&
|
||||
+ lacp_port->lacp->cfg.fallback;
|
||||
+}
|
||||
+
|
||||
static bool lacp_port_selectable_state(struct lacp_port *lacp_port)
|
||||
{
|
||||
- if (lacp_port->state == PORT_STATE_CURRENT)
|
||||
+ if (lacp_port->state == PORT_STATE_CURRENT ||
|
||||
+ is_lacp_fallback_eligible(lacp_port))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -318,7 +340,8 @@ static bool lacp_port_selectable_state(struct lacp_port *lacp_port)
|
||||
static bool lacp_port_unselectable_state(struct lacp_port *lacp_port)
|
||||
{
|
||||
if (lacp_port->state == PORT_STATE_CURRENT ||
|
||||
- lacp_port->state == PORT_STATE_EXPIRED)
|
||||
+ lacp_port->state == PORT_STATE_EXPIRED ||
|
||||
+ is_lacp_fallback_eligible(lacp_port))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
@@ -1452,6 +1475,16 @@ static int lacp_state_fast_rate_get(struct teamd_context *ctx,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int lacp_state_fallback_get(struct teamd_context *ctx,
|
||||
+ struct team_state_gsc *gsc,
|
||||
+ void *priv)
|
||||
+{
|
||||
+ struct lacp *lacp = priv;
|
||||
+
|
||||
+ gsc->data.bool_val = lacp->cfg.fallback;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int lacp_state_select_policy_get(struct teamd_context *ctx,
|
||||
struct team_state_gsc *gsc,
|
||||
void *priv)
|
||||
@@ -1479,6 +1512,11 @@ static const struct teamd_state_val lacp_state_vals[] = {
|
||||
.getter = lacp_state_fast_rate_get,
|
||||
},
|
||||
{
|
||||
+ .subpath = "fallback",
|
||||
+ .type = TEAMD_STATE_ITEM_TYPE_BOOL,
|
||||
+ .getter = lacp_state_fallback_get,
|
||||
+ },
|
||||
+ {
|
||||
.subpath = "select_policy",
|
||||
.type = TEAMD_STATE_ITEM_TYPE_STRING,
|
||||
.getter = lacp_state_select_policy_get,
|
||||
--
|
||||
2.7.4
|
||||
|
@ -18,6 +18,7 @@ $(addprefix $(DEST)/, $(MAIN_TARGET)): $(DEST)/% :
|
||||
git apply ../0001-libteam-Add-team_get_port_enabled-function.patch
|
||||
git apply ../0002-libteam-Temporarily-remove-redundant-debug-mes.patch
|
||||
git apply ../0003-teamd-lacp-runner-will-send-lacp-update-right-after-.patch
|
||||
git apply ../0004-libteam-Add-lacp-fallback-support-for-single-member-.patch
|
||||
popd
|
||||
|
||||
# Obtain debian packaging
|
||||
|
@ -148,7 +148,10 @@ def parse_dpg(dpg, hname):
|
||||
pcmbr_list = pcintfmbr.split(';')
|
||||
for i, member in enumerate(pcmbr_list):
|
||||
pcmbr_list[i] = port_alias_map.get(member, member)
|
||||
pcs[pcintfname] = {'members': pcmbr_list}
|
||||
if pcintf.find(str(QName(ns, "Fallback"))) != None:
|
||||
pcs[pcintfname] = {'members': pcmbr_list, 'fallback': pcintf.find(str(QName(ns, "Fallback"))).text}
|
||||
else:
|
||||
pcs[pcintfname] = {'members': pcmbr_list}
|
||||
|
||||
vlanintfs = child.find(str(QName(ns, "VlanInterfaces")))
|
||||
vlan_intfs = []
|
||||
|
Reference in New Issue
Block a user