Skip to content

Commit

Permalink
net/smc: Introduce SMCR get linkgroup command
Browse files Browse the repository at this point in the history
Introduce get linkgroup command which loops through
all available SMCR linkgroups. It uses the SMC-R linkgroup
list as entry point, not the socket list, which makes
linkgroup diagnosis possible, in case linkgroup does not
contain active connections anymore.

Signed-off-by: Guvenc Gulce <guvenc@linux.ibm.com>
Signed-off-by: Karsten Graul <kgraul@linux.ibm.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Guvenc Gulce authored and Jakub Kicinski committed Dec 2, 2020
1 parent 099b990 commit e9b8c84
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/uapi/linux/smc.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ enum { /* SMC PNET Table commands */
/* SMC_GENL_FAMILY commands */
enum {
SMC_NETLINK_GET_SYS_INFO = 1,
SMC_NETLINK_GET_LGR_SMCR,
};

/* SMC_GENL_FAMILY top level attributes */
enum {
SMC_GEN_UNSPEC,
SMC_GEN_SYS_INFO, /* nest */
SMC_GEN_LGR_SMCR, /* nest */
__SMC_GEN_MAX,
SMC_GEN_MAX = __SMC_GEN_MAX - 1
};
Expand All @@ -62,4 +64,17 @@ enum {
SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1
};

/* SMC_GEN_LGR_SMCR attributes */
enum {
SMC_NLA_LGR_R_UNSPEC,
SMC_NLA_LGR_R_ID, /* u32 */
SMC_NLA_LGR_R_ROLE, /* u8 */
SMC_NLA_LGR_R_TYPE, /* u8 */
SMC_NLA_LGR_R_PNETID, /* string */
SMC_NLA_LGR_R_VLAN_ID, /* u8 */
SMC_NLA_LGR_R_CONNS_NUM, /* u32 */
__SMC_NLA_LGR_R_MAX,
SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
};

#endif /* _UAPI_LINUX_SMC_H */
85 changes: 85 additions & 0 deletions net/smc/smc_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,91 @@ int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb)
return skb->len;
}

static int smc_nl_fill_lgr(struct smc_link_group *lgr,
struct sk_buff *skb,
struct netlink_callback *cb)
{
char smc_target[SMC_MAX_PNETID_LEN + 1];
struct nlattr *attrs;

attrs = nla_nest_start(skb, SMC_GEN_LGR_SMCR);
if (!attrs)
goto errout;

if (nla_put_u32(skb, SMC_NLA_LGR_R_ID, *((u32 *)&lgr->id)))
goto errattr;
if (nla_put_u32(skb, SMC_NLA_LGR_R_CONNS_NUM, lgr->conns_num))
goto errattr;
if (nla_put_u8(skb, SMC_NLA_LGR_R_ROLE, lgr->role))
goto errattr;
if (nla_put_u8(skb, SMC_NLA_LGR_R_TYPE, lgr->type))
goto errattr;
if (nla_put_u8(skb, SMC_NLA_LGR_R_VLAN_ID, lgr->vlan_id))
goto errattr;
snprintf(smc_target, sizeof(smc_target), "%s", lgr->pnet_id);
if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target))
goto errattr;

nla_nest_end(skb, attrs);
return 0;
errattr:
nla_nest_cancel(skb, attrs);
errout:
return -EMSGSIZE;
}

static int smc_nl_handle_lgr(struct smc_link_group *lgr,
struct sk_buff *skb,
struct netlink_callback *cb)
{
void *nlh;

nlh = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
&smc_gen_nl_family, NLM_F_MULTI,
SMC_NETLINK_GET_LGR_SMCR);
if (!nlh)
goto errmsg;
if (smc_nl_fill_lgr(lgr, skb, cb))
goto errout;

genlmsg_end(skb, nlh);
return 0;

errout:
genlmsg_cancel(skb, nlh);
errmsg:
return -EMSGSIZE;
}

static void smc_nl_fill_lgr_list(struct smc_lgr_list *smc_lgr,
struct sk_buff *skb,
struct netlink_callback *cb)
{
struct smc_nl_dmp_ctx *cb_ctx = smc_nl_dmp_ctx(cb);
struct smc_link_group *lgr;
int snum = cb_ctx->pos[0];
int num = 0;

spin_lock_bh(&smc_lgr->lock);
list_for_each_entry(lgr, &smc_lgr->list, list) {
if (num < snum)
goto next;
if (smc_nl_handle_lgr(lgr, skb, cb))
goto errout;
next:
num++;
}
errout:
spin_unlock_bh(&smc_lgr->lock);
cb_ctx->pos[0] = num;
}

int smcr_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb)
{
smc_nl_fill_lgr_list(&smc_lgr_list, skb, cb);
return skb->len;
}

void smc_lgr_cleanup_early(struct smc_connection *conn)
{
struct smc_link_group *lgr = conn->lgr;
Expand Down
1 change: 1 addition & 0 deletions net/smc/smc_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ struct smc_link *smc_switch_conns(struct smc_link_group *lgr,
void smcr_link_down_cond(struct smc_link *lnk);
void smcr_link_down_cond_sched(struct smc_link *lnk);
int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb);
int smcr_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb);

static inline struct smc_link_group *smc_get_lgr(struct smc_link *link)
{
Expand Down
5 changes: 5 additions & 0 deletions net/smc/smc_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ static const struct genl_ops smc_gen_nl_ops[] = {
/* can be retrieved by unprivileged users */
.dumpit = smc_nl_get_sys_info,
},
{
.cmd = SMC_NETLINK_GET_LGR_SMCR,
/* can be retrieved by unprivileged users */
.dumpit = smcr_nl_get_lgr,
},
};

static const struct nla_policy smc_gen_nl_policy[2] = {
Expand Down

0 comments on commit e9b8c84

Please sign in to comment.