net/smc: add netlink support for SMC-Rv2
Implement the netlink support for SMC-Rv2 related attributes that are provided to user space. Signed-off-by: Karsten Graul <kgraul@linux.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
b4ba4652b3
commit
b0539f5edd
@ -84,17 +84,28 @@ enum {
|
|||||||
SMC_NLA_SYS_IS_ISM_V2, /* u8 */
|
SMC_NLA_SYS_IS_ISM_V2, /* u8 */
|
||||||
SMC_NLA_SYS_LOCAL_HOST, /* string */
|
SMC_NLA_SYS_LOCAL_HOST, /* string */
|
||||||
SMC_NLA_SYS_SEID, /* string */
|
SMC_NLA_SYS_SEID, /* string */
|
||||||
|
SMC_NLA_SYS_IS_SMCR_V2, /* u8 */
|
||||||
__SMC_NLA_SYS_MAX,
|
__SMC_NLA_SYS_MAX,
|
||||||
SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1
|
SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SMC_NLA_LGR_V2 nested attributes */
|
/* SMC_NLA_LGR_D_V2_COMMON and SMC_NLA_LGR_R_V2_COMMON nested attributes */
|
||||||
enum {
|
enum {
|
||||||
SMC_NLA_LGR_V2_VER, /* u8 */
|
SMC_NLA_LGR_V2_VER, /* u8 */
|
||||||
SMC_NLA_LGR_V2_REL, /* u8 */
|
SMC_NLA_LGR_V2_REL, /* u8 */
|
||||||
SMC_NLA_LGR_V2_OS, /* u8 */
|
SMC_NLA_LGR_V2_OS, /* u8 */
|
||||||
SMC_NLA_LGR_V2_NEG_EID, /* string */
|
SMC_NLA_LGR_V2_NEG_EID, /* string */
|
||||||
SMC_NLA_LGR_V2_PEER_HOST, /* string */
|
SMC_NLA_LGR_V2_PEER_HOST, /* string */
|
||||||
|
__SMC_NLA_LGR_V2_MAX,
|
||||||
|
SMC_NLA_LGR_V2_MAX = __SMC_NLA_LGR_V2_MAX - 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/* SMC_NLA_LGR_R_V2 nested attributes */
|
||||||
|
enum {
|
||||||
|
SMC_NLA_LGR_R_V2_UNSPEC,
|
||||||
|
SMC_NLA_LGR_R_V2_DIRECT, /* u8 */
|
||||||
|
__SMC_NLA_LGR_R_V2_MAX,
|
||||||
|
SMC_NLA_LGR_R_V2_MAX = __SMC_NLA_LGR_R_V2_MAX - 1
|
||||||
};
|
};
|
||||||
|
|
||||||
/* SMC_GEN_LGR_SMCR attributes */
|
/* SMC_GEN_LGR_SMCR attributes */
|
||||||
@ -106,6 +117,8 @@ enum {
|
|||||||
SMC_NLA_LGR_R_PNETID, /* string */
|
SMC_NLA_LGR_R_PNETID, /* string */
|
||||||
SMC_NLA_LGR_R_VLAN_ID, /* u8 */
|
SMC_NLA_LGR_R_VLAN_ID, /* u8 */
|
||||||
SMC_NLA_LGR_R_CONNS_NUM, /* u32 */
|
SMC_NLA_LGR_R_CONNS_NUM, /* u32 */
|
||||||
|
SMC_NLA_LGR_R_V2_COMMON, /* nest */
|
||||||
|
SMC_NLA_LGR_R_V2, /* nest */
|
||||||
__SMC_NLA_LGR_R_MAX,
|
__SMC_NLA_LGR_R_MAX,
|
||||||
SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
|
SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1
|
||||||
};
|
};
|
||||||
@ -138,7 +151,7 @@ enum {
|
|||||||
SMC_NLA_LGR_D_PNETID, /* string */
|
SMC_NLA_LGR_D_PNETID, /* string */
|
||||||
SMC_NLA_LGR_D_CHID, /* u16 */
|
SMC_NLA_LGR_D_CHID, /* u16 */
|
||||||
SMC_NLA_LGR_D_PAD, /* flag */
|
SMC_NLA_LGR_D_PAD, /* flag */
|
||||||
SMC_NLA_LGR_V2, /* nest */
|
SMC_NLA_LGR_D_V2_COMMON, /* nest */
|
||||||
__SMC_NLA_LGR_D_MAX,
|
__SMC_NLA_LGR_D_MAX,
|
||||||
SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
|
SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1
|
||||||
};
|
};
|
||||||
|
@ -244,6 +244,8 @@ int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb)
|
|||||||
goto errattr;
|
goto errattr;
|
||||||
if (nla_put_u8(skb, SMC_NLA_SYS_IS_ISM_V2, smc_ism_is_v2_capable()))
|
if (nla_put_u8(skb, SMC_NLA_SYS_IS_ISM_V2, smc_ism_is_v2_capable()))
|
||||||
goto errattr;
|
goto errattr;
|
||||||
|
if (nla_put_u8(skb, SMC_NLA_SYS_IS_SMCR_V2, true))
|
||||||
|
goto errattr;
|
||||||
smc_clc_get_hostname(&host);
|
smc_clc_get_hostname(&host);
|
||||||
if (host) {
|
if (host) {
|
||||||
memcpy(hostname, host, SMC_MAX_HOSTNAME_LEN);
|
memcpy(hostname, host, SMC_MAX_HOSTNAME_LEN);
|
||||||
@ -271,12 +273,65 @@ errmsg:
|
|||||||
return skb->len;
|
return skb->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Fill SMC_NLA_LGR_D_V2_COMMON/SMC_NLA_LGR_R_V2_COMMON nested attributes */
|
||||||
|
static int smc_nl_fill_lgr_v2_common(struct smc_link_group *lgr,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct netlink_callback *cb,
|
||||||
|
struct nlattr *v2_attrs)
|
||||||
|
{
|
||||||
|
char smc_host[SMC_MAX_HOSTNAME_LEN + 1];
|
||||||
|
char smc_eid[SMC_MAX_EID_LEN + 1];
|
||||||
|
|
||||||
|
if (nla_put_u8(skb, SMC_NLA_LGR_V2_VER, lgr->smc_version))
|
||||||
|
goto errv2attr;
|
||||||
|
if (nla_put_u8(skb, SMC_NLA_LGR_V2_REL, lgr->peer_smc_release))
|
||||||
|
goto errv2attr;
|
||||||
|
if (nla_put_u8(skb, SMC_NLA_LGR_V2_OS, lgr->peer_os))
|
||||||
|
goto errv2attr;
|
||||||
|
memcpy(smc_host, lgr->peer_hostname, SMC_MAX_HOSTNAME_LEN);
|
||||||
|
smc_host[SMC_MAX_HOSTNAME_LEN] = 0;
|
||||||
|
if (nla_put_string(skb, SMC_NLA_LGR_V2_PEER_HOST, smc_host))
|
||||||
|
goto errv2attr;
|
||||||
|
memcpy(smc_eid, lgr->negotiated_eid, SMC_MAX_EID_LEN);
|
||||||
|
smc_eid[SMC_MAX_EID_LEN] = 0;
|
||||||
|
if (nla_put_string(skb, SMC_NLA_LGR_V2_NEG_EID, smc_eid))
|
||||||
|
goto errv2attr;
|
||||||
|
|
||||||
|
nla_nest_end(skb, v2_attrs);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
errv2attr:
|
||||||
|
nla_nest_cancel(skb, v2_attrs);
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int smc_nl_fill_smcr_lgr_v2(struct smc_link_group *lgr,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct netlink_callback *cb)
|
||||||
|
{
|
||||||
|
struct nlattr *v2_attrs;
|
||||||
|
|
||||||
|
v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_R_V2);
|
||||||
|
if (!v2_attrs)
|
||||||
|
goto errattr;
|
||||||
|
if (nla_put_u8(skb, SMC_NLA_LGR_R_V2_DIRECT, !lgr->uses_gateway))
|
||||||
|
goto errv2attr;
|
||||||
|
|
||||||
|
nla_nest_end(skb, v2_attrs);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
errv2attr:
|
||||||
|
nla_nest_cancel(skb, v2_attrs);
|
||||||
|
errattr:
|
||||||
|
return -EMSGSIZE;
|
||||||
|
}
|
||||||
|
|
||||||
static int smc_nl_fill_lgr(struct smc_link_group *lgr,
|
static int smc_nl_fill_lgr(struct smc_link_group *lgr,
|
||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct netlink_callback *cb)
|
struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
char smc_target[SMC_MAX_PNETID_LEN + 1];
|
char smc_target[SMC_MAX_PNETID_LEN + 1];
|
||||||
struct nlattr *attrs;
|
struct nlattr *attrs, *v2_attrs;
|
||||||
|
|
||||||
attrs = nla_nest_start(skb, SMC_GEN_LGR_SMCR);
|
attrs = nla_nest_start(skb, SMC_GEN_LGR_SMCR);
|
||||||
if (!attrs)
|
if (!attrs)
|
||||||
@ -296,6 +351,15 @@ static int smc_nl_fill_lgr(struct smc_link_group *lgr,
|
|||||||
smc_target[SMC_MAX_PNETID_LEN] = 0;
|
smc_target[SMC_MAX_PNETID_LEN] = 0;
|
||||||
if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target))
|
if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target))
|
||||||
goto errattr;
|
goto errattr;
|
||||||
|
if (lgr->smc_version > SMC_V1) {
|
||||||
|
v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_R_V2_COMMON);
|
||||||
|
if (!v2_attrs)
|
||||||
|
goto errattr;
|
||||||
|
if (smc_nl_fill_lgr_v2_common(lgr, skb, cb, v2_attrs))
|
||||||
|
goto errattr;
|
||||||
|
if (smc_nl_fill_smcr_lgr_v2(lgr, skb, cb))
|
||||||
|
goto errattr;
|
||||||
|
}
|
||||||
|
|
||||||
nla_nest_end(skb, attrs);
|
nla_nest_end(skb, attrs);
|
||||||
return 0;
|
return 0;
|
||||||
@ -428,10 +492,7 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
|
|||||||
struct sk_buff *skb,
|
struct sk_buff *skb,
|
||||||
struct netlink_callback *cb)
|
struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
char smc_host[SMC_MAX_HOSTNAME_LEN + 1];
|
|
||||||
char smc_pnet[SMC_MAX_PNETID_LEN + 1];
|
char smc_pnet[SMC_MAX_PNETID_LEN + 1];
|
||||||
char smc_eid[SMC_MAX_EID_LEN + 1];
|
|
||||||
struct nlattr *v2_attrs;
|
|
||||||
struct nlattr *attrs;
|
struct nlattr *attrs;
|
||||||
void *nlh;
|
void *nlh;
|
||||||
|
|
||||||
@ -463,32 +524,19 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr,
|
|||||||
smc_pnet[SMC_MAX_PNETID_LEN] = 0;
|
smc_pnet[SMC_MAX_PNETID_LEN] = 0;
|
||||||
if (nla_put_string(skb, SMC_NLA_LGR_D_PNETID, smc_pnet))
|
if (nla_put_string(skb, SMC_NLA_LGR_D_PNETID, smc_pnet))
|
||||||
goto errattr;
|
goto errattr;
|
||||||
|
if (lgr->smc_version > SMC_V1) {
|
||||||
|
struct nlattr *v2_attrs;
|
||||||
|
|
||||||
v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_V2);
|
v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_D_V2_COMMON);
|
||||||
if (!v2_attrs)
|
if (!v2_attrs)
|
||||||
goto errattr;
|
goto errattr;
|
||||||
if (nla_put_u8(skb, SMC_NLA_LGR_V2_VER, lgr->smc_version))
|
if (smc_nl_fill_lgr_v2_common(lgr, skb, cb, v2_attrs))
|
||||||
goto errv2attr;
|
goto errattr;
|
||||||
if (nla_put_u8(skb, SMC_NLA_LGR_V2_REL, lgr->peer_smc_release))
|
}
|
||||||
goto errv2attr;
|
|
||||||
if (nla_put_u8(skb, SMC_NLA_LGR_V2_OS, lgr->peer_os))
|
|
||||||
goto errv2attr;
|
|
||||||
memcpy(smc_host, lgr->peer_hostname, SMC_MAX_HOSTNAME_LEN);
|
|
||||||
smc_host[SMC_MAX_HOSTNAME_LEN] = 0;
|
|
||||||
if (nla_put_string(skb, SMC_NLA_LGR_V2_PEER_HOST, smc_host))
|
|
||||||
goto errv2attr;
|
|
||||||
memcpy(smc_eid, lgr->negotiated_eid, SMC_MAX_EID_LEN);
|
|
||||||
smc_eid[SMC_MAX_EID_LEN] = 0;
|
|
||||||
if (nla_put_string(skb, SMC_NLA_LGR_V2_NEG_EID, smc_eid))
|
|
||||||
goto errv2attr;
|
|
||||||
|
|
||||||
nla_nest_end(skb, v2_attrs);
|
|
||||||
nla_nest_end(skb, attrs);
|
nla_nest_end(skb, attrs);
|
||||||
genlmsg_end(skb, nlh);
|
genlmsg_end(skb, nlh);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
errv2attr:
|
|
||||||
nla_nest_cancel(skb, v2_attrs);
|
|
||||||
errattr:
|
errattr:
|
||||||
nla_nest_cancel(skb, attrs);
|
nla_nest_cancel(skb, attrs);
|
||||||
errout:
|
errout:
|
||||||
|
Loading…
Reference in New Issue
Block a user