Skip to content

Commit

Permalink
libteam, teamd: Track admin state of team device and add handlers to …
Browse files Browse the repository at this point in the history
…watch for changes.

Signed-off-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
  • Loading branch information
ssamudrala authored and jpirko committed Sep 3, 2015
1 parent 336eb7b commit 2a0f604
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 5 deletions.
45 changes: 44 additions & 1 deletion libteam/ifinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ struct team_ifinfo {
size_t orig_hwaddr_len;
char ifname[IFNAMSIZ];
uint32_t master_ifindex;
bool admin_state;
#define MAX_PHYS_PORT_ID_LEN 32
char phys_port_id[MAX_PHYS_PORT_ID_LEN];
size_t phys_port_id_len;
Expand All @@ -70,10 +71,11 @@ struct team_ifinfo {
#define CHANGED_MASTER_IFINDEX (1 << 4)
#define CHANGED_PHYS_PORT_ID (1 << 5)
#define CHANGED_PHYS_PORT_ID_LEN (1 << 6)
#define CHANGED_ADMIN_STATE (1 << 7)
#define CHANGED_ANY (CHANGED_REMOVED | CHANGED_HWADDR | \
CHANGED_HWADDR_LEN | CHANGED_IFNAME | \
CHANGED_MASTER_IFINDEX | CHANGED_PHYS_PORT_ID | \
CHANGED_PHYS_PORT_ID_LEN)
CHANGED_PHYS_PORT_ID_LEN | CHANGED_ADMIN_STATE)

static void set_changed(struct team_ifinfo *ifinfo, int bit)
{
Expand Down Expand Up @@ -127,6 +129,20 @@ static void update_ifname(struct team_ifinfo *ifinfo, struct rtnl_link *link)
}
}

static void update_admin_state(struct team_ifinfo *ifinfo, struct rtnl_link *link)
{
unsigned int flags;
bool admin_state;

flags = rtnl_link_get_flags(link);
admin_state = ((flags & IFF_UP) == IFF_UP);

if (admin_state != ifinfo->admin_state) {
ifinfo->admin_state = admin_state;
set_changed(ifinfo, CHANGED_ADMIN_STATE);
}
}

static void update_master(struct team_ifinfo *ifinfo, struct rtnl_link *link)
{
uint32_t master_ifindex;
Expand Down Expand Up @@ -172,6 +188,7 @@ static void ifinfo_update(struct team_ifinfo *ifinfo, struct rtnl_link *link)
update_master(ifinfo, link);
update_hwaddr(ifinfo, link);
update_phys_port_id(ifinfo, link);
update_admin_state(ifinfo, link);
}

static struct team_ifinfo *ifinfo_find(struct team_handle *th, uint32_t ifindex)
Expand Down Expand Up @@ -472,6 +489,19 @@ uint32_t team_get_ifinfo_ifindex(struct team_ifinfo *ifinfo)
return ifinfo->ifindex;
}

/**
* @param ifinfo ifinfo structure
*
* @details Get ifinfo admin state.
*
* @return Ifinfo interface index as idenfified by in kernel.
**/
TEAM_EXPORT
bool team_get_ifinfo_admin_state(struct team_ifinfo *ifinfo)
{
return ifinfo->admin_state;
}

/**
* @param ifinfo ifinfo structure
*
Expand Down Expand Up @@ -616,6 +646,19 @@ bool team_is_ifinfo_master_ifindex_changed(struct team_ifinfo *ifinfo)
return is_changed(ifinfo, CHANGED_MASTER_IFINDEX);
}

/**
* @param ifinfo ifinfo structure
*
* @details See if admin state of interface got changed.
*
* @return True if admin state of interface got changed.
**/
TEAM_EXPORT
bool team_is_ifinfo_admin_state_changed(struct team_ifinfo *ifinfo)
{
return is_changed(ifinfo, CHANGED_ADMIN_STATE);
}

/**
* @param ifinfo ifinfo structure
*
Expand Down
3 changes: 3 additions & 0 deletions teamd/teamd.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ struct teamd_runner {
struct teamd_event_watch_ops {
int (*hwaddr_changed)(struct teamd_context *ctx, void *priv);
int (*ifname_changed)(struct teamd_context *ctx, void *priv);
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_removed)(struct teamd_context *ctx,
Expand Down Expand Up @@ -205,6 +206,8 @@ int teamd_event_ifinfo_hwaddr_changed(struct teamd_context *ctx,
struct team_ifinfo *ifinfo);
int teamd_event_ifinfo_ifname_changed(struct teamd_context *ctx,
struct team_ifinfo *ifinfo);
int teamd_event_ifinfo_admin_state_changed(struct teamd_context *ctx,
struct team_ifinfo *ifinfo);
int teamd_events_init(struct teamd_context *ctx);
void teamd_events_fini(struct teamd_context *ctx);
int teamd_event_watch_register(struct teamd_context *ctx,
Expand Down
17 changes: 17 additions & 0 deletions teamd/teamd_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,23 @@ int teamd_event_ifinfo_ifname_changed(struct teamd_context *ctx,
return 0;
}

int teamd_event_ifinfo_admin_state_changed(struct teamd_context *ctx,
struct team_ifinfo *ifinfo)
{
struct event_watch_item *watch;
uint32_t ifindex = team_get_ifinfo_ifindex(ifinfo);
int err;

list_for_each_node_entry(watch, &ctx->event_watch_list, list) {
if (watch->ops->admin_state_changed && ctx->ifindex == ifindex) {
err = watch->ops->admin_state_changed(ctx, watch->priv);
if (err)
return err;
}
}
return 0;
}

int teamd_events_init(struct teamd_context *ctx)
{
list_init(&ctx->event_watch_list);
Expand Down
14 changes: 10 additions & 4 deletions teamd/teamd_ifinfo_watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,16 @@ static int ifinfo_change_handler_func(struct team_handle *th, void *priv,
int err;

team_for_each_ifinfo(ifinfo, th) {
if (ctx->ifinfo == ifinfo &&
team_is_ifinfo_removed(ifinfo)) {
teamd_log_warn("Team device removal detected.");
teamd_run_loop_quit(ctx, 0);
if (ctx->ifinfo == ifinfo) {
if (team_is_ifinfo_removed(ifinfo)) {
teamd_log_warn("Team device removal detected.");
teamd_run_loop_quit(ctx, 0);
}
if (team_is_ifinfo_admin_state_changed(ifinfo)) {
err = teamd_event_ifinfo_admin_state_changed(ctx, ifinfo);
if (err)
return err;
}
}

if (team_is_ifinfo_hwaddr_changed(ifinfo) ||
Expand Down

0 comments on commit 2a0f604

Please sign in to comment.