Skip to content

Commit

Permalink
[libteam] Add fallback support for single-member-port LAG (#1118)
Browse files Browse the repository at this point in the history
* [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>
  • Loading branch information
hzheng5 authored and lguohan committed Dec 16, 2017
1 parent 46a6534 commit 2abdf8d
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 1 deletion.
4 changes: 4 additions & 0 deletions dockers/docker-teamd/teamd.j2
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
Original file line number Diff line number Diff line change
@@ -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

1 change: 1 addition & 0 deletions src/libteam/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
5 changes: 4 additions & 1 deletion src/sonic-config-engine/minigraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down

0 comments on commit 2abdf8d

Please sign in to comment.