diff options
author | Jiri Pirko <jiri@nvidia.com> | 2022-12-07 10:44:35 +0100 |
---|---|---|
committer | Jiri Pirko <jiri@nvidia.com> | 2022-12-07 13:47:22 +0100 |
commit | fd26b370d85d63cca0736d7e666736bb15c395aa (patch) | |
tree | 13321e171ff54c0876c945e3a0254a3d2e6b8894 | |
parent | 5409fb58b0e9909b44a2ff89cf4c49e35ce53ea6 (diff) | |
download | libteam-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.h | 4 | ||||
-rw-r--r-- | teamd/teamd_events.c | 12 | ||||
-rw-r--r-- | teamd/teamd_per_port.c | 1 | ||||
-rw-r--r-- | teamd/teamd_runner_lacp.c | 12 |
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, |