aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jiri@nvidia.com>2022-12-07 10:44:35 +0100
committerJiri Pirko <jiri@nvidia.com>2022-12-07 13:47:22 +0100
commitfd26b370d85d63cca0736d7e666736bb15c395aa (patch)
tree13321e171ff54c0876c945e3a0254a3d2e6b8894
parent5409fb58b0e9909b44a2ff89cf4c49e35ce53ea6 (diff)
downloadlibteam-fd26b370d85d63cca0736d7e666736bb15c395aa.tar.gz
teamd: lacp: set port to disabled state during removal
Currently, the disabled state is set only after port is removed from team master in kernel. Team driver puts the port netdevice down right away. In some cases, there is nice to send LACPDU to the partner with flags set accordingly for the disabled port. Introduce "port_removing" op and call it right before kernel is asked to remove the port. Implement the op in LACP runner to disable the port which leads to proper LACPDU send. Signed-off-by: Jiri Pirko <jiri@nvidia.com>
-rw-r--r--teamd/teamd.h4
-rw-r--r--teamd/teamd_events.c12
-rw-r--r--teamd/teamd_per_port.c1
-rw-r--r--teamd/teamd_runner_lacp.c12
4 files changed, 29 insertions, 0 deletions
diff --git a/teamd/teamd.h b/teamd/teamd.h
index f94c918..541d2a7 100644
--- a/teamd/teamd.h
+++ b/teamd/teamd.h
@@ -180,6 +180,8 @@ struct teamd_event_watch_ops {
int (*admin_state_changed)(struct teamd_context *ctx, void *priv);
int (*port_added)(struct teamd_context *ctx,
struct teamd_port *tdport, void *priv);
+ void (*port_removing)(struct teamd_context *ctx,
+ struct teamd_port *tdport, void *priv);
void (*port_removed)(struct teamd_context *ctx,
struct teamd_port *tdport, void *priv);
int (*port_changed)(struct teamd_context *ctx,
@@ -200,6 +202,8 @@ struct teamd_event_watch_ops {
int teamd_event_port_added(struct teamd_context *ctx,
struct teamd_port *tdport);
+void teamd_event_port_removing(struct teamd_context *ctx,
+ struct teamd_port *tdport);
void teamd_event_port_removed(struct teamd_context *ctx,
struct teamd_port *tdport);
int teamd_event_port_changed(struct teamd_context *ctx,
diff --git a/teamd/teamd_events.c b/teamd/teamd_events.c
index 65aa46a..eac1759 100644
--- a/teamd/teamd_events.c
+++ b/teamd/teamd_events.c
@@ -50,6 +50,18 @@ int teamd_event_port_added(struct teamd_context *ctx,
return 0;
}
+void teamd_event_port_removing(struct teamd_context *ctx,
+ struct teamd_port *tdport)
+{
+ struct event_watch_item *watch;
+
+ list_for_each_node_entry(watch, &ctx->event_watch_list, list) {
+ if (!watch->ops->port_removing)
+ continue;
+ watch->ops->port_removing(ctx, tdport, watch->priv);
+ }
+}
+
void teamd_event_port_removed(struct teamd_context *ctx,
struct teamd_port *tdport)
{
diff --git a/teamd/teamd_per_port.c b/teamd/teamd_per_port.c
index 9689df4..c9c754e 100644
--- a/teamd/teamd_per_port.c
+++ b/teamd/teamd_per_port.c
@@ -351,6 +351,7 @@ static int teamd_port_remove(struct teamd_context *ctx,
teamd_log_dbg(ctx, "%s: Removing port (found ifindex \"%d\").",
tdport->ifname, tdport->ifindex);
+ teamd_event_port_removing(ctx, tdport);
err = team_port_remove(ctx->th, tdport->ifindex);
if (err)
teamd_log_err("%s: Failed to remove port.", tdport->ifname);
diff --git a/teamd/teamd_runner_lacp.c b/teamd/teamd_runner_lacp.c
index d414bb4..51c7714 100644
--- a/teamd/teamd_runner_lacp.c
+++ b/teamd/teamd_runner_lacp.c
@@ -1420,6 +1420,17 @@ static int lacp_event_watch_port_added(struct teamd_context *ctx,
return teamd_balancer_port_added(lacp->tb, tdport);
}
+static void lacp_event_watch_port_removing(struct teamd_context *ctx,
+ struct teamd_port *tdport, void *priv)
+{
+ struct lacp *lacp = priv;
+ struct lacp_port *lacp_port = lacp_port_get(lacp, tdport);
+
+ /* Ensure that no incoming LACPDU is going to be processed. */
+ teamd_loop_callback_disable(ctx, LACP_SOCKET_CB_NAME, lacp_port);
+ lacp_port_set_state(lacp_port, PORT_STATE_DISABLED);
+}
+
static void lacp_event_watch_port_removed(struct teamd_context *ctx,
struct teamd_port *tdport, void *priv)
{
@@ -1441,6 +1452,7 @@ static const struct teamd_event_watch_ops lacp_event_watch_ops = {
.hwaddr_changed = lacp_event_watch_hwaddr_changed,
.port_hwaddr_changed = lacp_event_watch_port_hwaddr_changed,
.port_added = lacp_event_watch_port_added,
+ .port_removing = lacp_event_watch_port_removing,
.port_removed = lacp_event_watch_port_removed,
.port_changed = lacp_event_watch_port_changed,
.admin_state_changed = lacp_event_watch_admin_state_changed,