static int acc_conn_create(struct teamd_context *ctx, int sock) { struct usock_acc_conn *acc_conn; int err; acc_conn = myzalloc(sizeof(*acc_conn)); if (!acc_conn) { teamd_log_err("usock: No memory to allocate new connection structure."); return -ENOMEM; } acc_conn->sock = sock; err = teamd_loop_callback_fd_add(ctx, USOCK_ACC_CONN_CB_NAME, acc_conn, callback_usock_acc_conn, acc_conn->sock, TEAMD_LOOP_FD_EVENT_READ); if (err) goto free_acc_conn; teamd_loop_callback_enable(ctx, USOCK_ACC_CONN_CB_NAME, acc_conn); list_add(&ctx->usock.acc_conn_list, &acc_conn->list); return 0; free_acc_conn: free(acc_conn); return err; }
static int lw_ethtool_event_watch_port_changed(struct teamd_context *ctx, struct teamd_port *tdport, void *priv) { struct lw_common_port_priv *common_ppriv = priv; struct lw_ethtool_port_priv *ethtool_ppriv = priv; bool link_up; struct timespec *delay; int err; if (common_ppriv->tdport != tdport || !team_is_port_changed(tdport->team_port)) return 0; /* * Link changed for sure, so if there is some delay in progress, * cancel it before proceeding. */ teamd_loop_callback_disable(ctx, LW_ETHTOOL_DELAY_CB_NAME, priv); link_up = team_is_port_link_up(tdport->team_port); if (!teamd_link_watch_link_up_differs(common_ppriv, link_up)) return 0; if (link_up) { if (timespec_is_zero(ðtool_ppriv->delay_up)) goto nodelay; delay = ðtool_ppriv->delay_up; } else { if (timespec_is_zero(ðtool_ppriv->delay_down)) goto nodelay; delay = ðtool_ppriv->delay_down; } err = teamd_loop_callback_timer_set(ctx, LW_ETHTOOL_DELAY_CB_NAME, priv, NULL, delay); if (err) { teamd_log_err("Failed to set delay timer."); return err; } teamd_loop_callback_enable(ctx, LW_ETHTOOL_DELAY_CB_NAME, priv); return 0; nodelay: return teamd_link_watch_check_link_up(ctx, tdport, common_ppriv, link_up); }
int teamd_usock_init(struct teamd_context *ctx) { int err; if (!ctx->usock.enabled) return 0; list_init(&ctx->usock.acc_conn_list); err = teamd_usock_sock_open(ctx); if (err) return err; err = teamd_loop_callback_fd_add(ctx, USOCK_CB_NAME, ctx, callback_usock, ctx->usock.sock, TEAMD_LOOP_FD_EVENT_READ); if (err) goto sock_close; teamd_loop_callback_enable(ctx, USOCK_CB_NAME, ctx); return 0; sock_close: teamd_usock_sock_close(ctx); return err; }
static int lw_psr_port_added(struct teamd_context *ctx, struct teamd_port *tdport, void *priv, void *creator_priv) { struct lw_psr_port_priv *psr_ppriv = priv; int err; err = lw_psr_load_options(ctx, tdport, psr_ppriv); if (err) { teamd_log_err("Failed to load options."); return err; } err = psr_ppriv->ops->load_options(ctx, tdport, psr_ppriv); if (err) { teamd_log_err("Failed to load options."); return err; } err = psr_ppriv->ops->sock_open(psr_ppriv); if (err) { teamd_log_err("Failed to create socket."); return err; } err = teamd_loop_callback_fd_add(ctx, LW_SOCKET_CB_NAME, psr_ppriv, lw_psr_callback_socket, psr_ppriv->sock, TEAMD_LOOP_FD_EVENT_READ); if (err) { teamd_log_err("Failed add socket callback."); goto close_sock; } err = teamd_loop_callback_timer_add_set(ctx, LW_PERIODIC_CB_NAME, psr_ppriv, lw_psr_callback_periodic, &psr_ppriv->interval, &psr_ppriv->init_wait); if (err) { teamd_log_err("Failed add callback timer"); goto socket_callback_del; } err = team_set_port_user_linkup_enabled(ctx->th, tdport->ifindex, true); if (err) { teamd_log_err("%s: Failed to enable user linkup.", tdport->ifname); goto periodic_callback_del; } teamd_loop_callback_enable(ctx, LW_SOCKET_CB_NAME, psr_ppriv); teamd_loop_callback_enable(ctx, LW_PERIODIC_CB_NAME, psr_ppriv); return 0; periodic_callback_del: teamd_loop_callback_del(ctx, LW_PERIODIC_CB_NAME, psr_ppriv); socket_callback_del: teamd_loop_callback_del(ctx, LW_SOCKET_CB_NAME, psr_ppriv); close_sock: psr_ppriv->ops->sock_close(psr_ppriv); return err; }