Implement the netlink support for SMC-Rv2 related attributes that are provided to user space.
Unified · Split
| @@ -84,17 +84,28 @@ enum { · 83 unmodified lines | |||
| 84 | SMC_NLA_SYS_IS_ISM_V2, /* u8 */ | 84 | SMC_NLA_SYS_IS_ISM_V2, /* u8 */ |
| 85 | SMC_NLA_SYS_LOCAL_HOST, /* string */ | 85 | SMC_NLA_SYS_LOCAL_HOST, /* string */ |
| 86 | SMC_NLA_SYS_SEID, /* string */ | 86 | SMC_NLA_SYS_SEID, /* string */ |
| 87 | SMC_NLA_SYS_IS_SMCR_V2, /* u8 */ | ||
| 87 | __SMC_NLA_SYS_MAX, | 88 | __SMC_NLA_SYS_MAX, |
| 88 | SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1 | 89 | SMC_NLA_SYS_MAX = __SMC_NLA_SYS_MAX - 1 |
| 89 | }; | 90 | }; |
| 90 | 91 | ||
| 91 | /* SMC_NLA_LGR_V2 nested attributes */ | 92 | /* SMC_NLA_LGR_D_V2_COMMON and SMC_NLA_LGR_R_V2_COMMON nested attributes */ |
| 92 | enum { | 93 | enum { |
| 93 | SMC_NLA_LGR_V2_VER, /* u8 */ | 94 | SMC_NLA_LGR_V2_VER, /* u8 */ |
| 94 | SMC_NLA_LGR_V2_REL, /* u8 */ | 95 | SMC_NLA_LGR_V2_REL, /* u8 */ |
| 95 | SMC_NLA_LGR_V2_OS, /* u8 */ | 96 | SMC_NLA_LGR_V2_OS, /* u8 */ |
| 96 | SMC_NLA_LGR_V2_NEG_EID, /* string */ | 97 | SMC_NLA_LGR_V2_NEG_EID, /* string */ |
| 97 | SMC_NLA_LGR_V2_PEER_HOST, /* string */ | 98 | SMC_NLA_LGR_V2_PEER_HOST, /* string */ |
| 99 | __SMC_NLA_LGR_V2_MAX, | ||
| 100 | SMC_NLA_LGR_V2_MAX = __SMC_NLA_LGR_V2_MAX - 1 | ||
| 101 | }; | ||
| 102 | |||
| 103 | /* SMC_NLA_LGR_R_V2 nested attributes */ | ||
| 104 | enum { | ||
| 105 | SMC_NLA_LGR_R_V2_UNSPEC, | ||
| 106 | SMC_NLA_LGR_R_V2_DIRECT, /* u8 */ | ||
| 107 | __SMC_NLA_LGR_R_V2_MAX, | ||
| 108 | SMC_NLA_LGR_R_V2_MAX = __SMC_NLA_LGR_R_V2_MAX - 1 | ||
| 98 | }; | 109 | }; |
| 99 | 110 | ||
| 100 | /* SMC_GEN_LGR_SMCR attributes */ | 111 | /* SMC_GEN_LGR_SMCR attributes */ |
| @@ -106,6 +117,8 @@ enum { · 5 unmodified lines | |||
| 106 | SMC_NLA_LGR_R_PNETID, /* string */ | 117 | SMC_NLA_LGR_R_PNETID, /* string */ |
| 107 | SMC_NLA_LGR_R_VLAN_ID, /* u8 */ | 118 | SMC_NLA_LGR_R_VLAN_ID, /* u8 */ |
| 108 | SMC_NLA_LGR_R_CONNS_NUM, /* u32 */ | 119 | SMC_NLA_LGR_R_CONNS_NUM, /* u32 */ |
| 120 | SMC_NLA_LGR_R_V2_COMMON, /* nest */ | ||
| 121 | SMC_NLA_LGR_R_V2, /* nest */ | ||
| 109 | __SMC_NLA_LGR_R_MAX, | 122 | __SMC_NLA_LGR_R_MAX, |
| 110 | SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1 | 123 | SMC_NLA_LGR_R_MAX = __SMC_NLA_LGR_R_MAX - 1 |
| 111 | }; | 124 | }; |
| @@ -138,7 +151,7 @@ enum { · 26 unmodified lines | |||
| 138 | SMC_NLA_LGR_D_PNETID, /* string */ | 151 | SMC_NLA_LGR_D_PNETID, /* string */ |
| 139 | SMC_NLA_LGR_D_CHID, /* u16 */ | 152 | SMC_NLA_LGR_D_CHID, /* u16 */ |
| 140 | SMC_NLA_LGR_D_PAD, /* flag */ | 153 | SMC_NLA_LGR_D_PAD, /* flag */ |
| 141 | SMC_NLA_LGR_V2, /* nest */ | 154 | SMC_NLA_LGR_D_V2_COMMON, /* nest */ |
| 142 | __SMC_NLA_LGR_D_MAX, | 155 | __SMC_NLA_LGR_D_MAX, |
| 143 | SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1 | 156 | SMC_NLA_LGR_D_MAX = __SMC_NLA_LGR_D_MAX - 1 |
| 144 | }; | 157 | }; |
| @@ -244,6 +244,8 @@ int smc_nl_get_sys_info(struct sk_buff *skb, struct netlink_callback *cb) · 243 unmodified lines | |||
| 244 | goto errattr; | 244 | goto errattr; |
| 245 | if (nla_put_u8(skb, SMC_NLA_SYS_IS_ISM_V2, smc_ism_is_v2_capable())) | 245 | if (nla_put_u8(skb, SMC_NLA_SYS_IS_ISM_V2, smc_ism_is_v2_capable())) |
| 246 | goto errattr; | 246 | goto errattr; |
| 247 | if (nla_put_u8(skb, SMC_NLA_SYS_IS_SMCR_V2, true)) | ||
| 248 | goto errattr; | ||
| 247 | smc_clc_get_hostname(&host); | 249 | smc_clc_get_hostname(&host); |
| 248 | if (host) { | 250 | if (host) { |
| 249 | memcpy(hostname, host, SMC_MAX_HOSTNAME_LEN); | 251 | memcpy(hostname, host, SMC_MAX_HOSTNAME_LEN); |
| @@ -271,12 +273,65 @@ errmsg: · 21 unmodified lines | |||
| 271 | return skb->len; | 273 | return skb->len; |
| 272 | } | 274 | } |
| 273 | 275 | ||
| 276 | /* Fill SMC_NLA_LGR_D_V2_COMMON/SMC_NLA_LGR_R_V2_COMMON nested attributes */ | ||
| 277 | static int smc_nl_fill_lgr_v2_common(struct smc_link_group *lgr, | ||
| 278 | struct sk_buff *skb, | ||
| 279 | struct netlink_callback *cb, | ||
| 280 | struct nlattr *v2_attrs) | ||
| 281 | { | ||
| 282 | char smc_host[SMC_MAX_HOSTNAME_LEN + 1]; | ||
| 283 | char smc_eid[SMC_MAX_EID_LEN + 1]; | ||
| 284 | |||
| 285 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_VER, lgr->smc_version)) | ||
| 286 | goto errv2attr; | ||
| 287 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_REL, lgr->peer_smc_release)) | ||
| 288 | goto errv2attr; | ||
| 289 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_OS, lgr->peer_os)) | ||
| 290 | goto errv2attr; | ||
| 291 | memcpy(smc_host, lgr->peer_hostname, SMC_MAX_HOSTNAME_LEN); | ||
| 292 | smc_host[SMC_MAX_HOSTNAME_LEN] = 0; | ||
| 293 | if (nla_put_string(skb, SMC_NLA_LGR_V2_PEER_HOST, smc_host)) | ||
| 294 | goto errv2attr; | ||
| 295 | memcpy(smc_eid, lgr->negotiated_eid, SMC_MAX_EID_LEN); | ||
| 296 | smc_eid[SMC_MAX_EID_LEN] = 0; | ||
| 297 | if (nla_put_string(skb, SMC_NLA_LGR_V2_NEG_EID, smc_eid)) | ||
| 298 | goto errv2attr; | ||
| 299 | |||
| 300 | nla_nest_end(skb, v2_attrs); | ||
| 301 | return 0; | ||
| 302 | |||
| 303 | errv2attr: | ||
| 304 | nla_nest_cancel(skb, v2_attrs); | ||
| 305 | return -EMSGSIZE; | ||
| 306 | } | ||
| 307 | |||
| 308 | static int smc_nl_fill_smcr_lgr_v2(struct smc_link_group *lgr, | ||
| 309 | struct sk_buff *skb, | ||
| 310 | struct netlink_callback *cb) | ||
| 311 | { | ||
| 312 | struct nlattr *v2_attrs; | ||
| 313 | |||
| 314 | v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_R_V2); | ||
| 315 | if (!v2_attrs) | ||
| 316 | goto errattr; | ||
| 317 | if (nla_put_u8(skb, SMC_NLA_LGR_R_V2_DIRECT, !lgr->uses_gateway)) | ||
| 318 | goto errv2attr; | ||
| 319 | |||
| 320 | nla_nest_end(skb, v2_attrs); | ||
| 321 | return 0; | ||
| 322 | |||
| 323 | errv2attr: | ||
| 324 | nla_nest_cancel(skb, v2_attrs); | ||
| 325 | errattr: | ||
| 326 | return -EMSGSIZE; | ||
| 327 | } | ||
| 328 | |||
| 274 | static int smc_nl_fill_lgr(struct smc_link_group *lgr, | 329 | static int smc_nl_fill_lgr(struct smc_link_group *lgr, |
| 275 | struct sk_buff *skb, | 330 | struct sk_buff *skb, |
| 276 | struct netlink_callback *cb) | 331 | struct netlink_callback *cb) |
| 277 | { | 332 | { |
| 278 | char smc_target[SMC_MAX_PNETID_LEN + 1]; | 333 | char smc_target[SMC_MAX_PNETID_LEN + 1]; |
| 279 | struct nlattr *attrs; | 334 | struct nlattr *attrs, *v2_attrs; |
| 280 | 335 | ||
| 281 | attrs = nla_nest_start(skb, SMC_GEN_LGR_SMCR); | 336 | attrs = nla_nest_start(skb, SMC_GEN_LGR_SMCR); |
| 282 | if (!attrs) | 337 | if (!attrs) |
| @@ -296,6 +351,15 @@ static int smc_nl_fill_lgr(struct smc_link_group *lgr, · 13 unmodified lines | |||
| 296 | smc_target[SMC_MAX_PNETID_LEN] = 0; | 351 | smc_target[SMC_MAX_PNETID_LEN] = 0; |
| 297 | if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target)) | 352 | if (nla_put_string(skb, SMC_NLA_LGR_R_PNETID, smc_target)) |
| 298 | goto errattr; | 353 | goto errattr; |
| 354 | if (lgr->smc_version > SMC_V1) { | ||
| 355 | v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_R_V2_COMMON); | ||
| 356 | if (!v2_attrs) | ||
| 357 | goto errattr; | ||
| 358 | if (smc_nl_fill_lgr_v2_common(lgr, skb, cb, v2_attrs)) | ||
| 359 | goto errattr; | ||
| 360 | if (smc_nl_fill_smcr_lgr_v2(lgr, skb, cb)) | ||
| 361 | goto errattr; | ||
| 362 | } | ||
| 299 | 363 | ||
| 300 | nla_nest_end(skb, attrs); | 364 | nla_nest_end(skb, attrs); |
| 301 | return 0; | 365 | return 0; |
| @@ -428,10 +492,7 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr, · 126 unmodified lines | |||
| 428 | struct sk_buff *skb, | 492 | struct sk_buff *skb, |
| 429 | struct netlink_callback *cb) | 493 | struct netlink_callback *cb) |
| 430 | { | 494 | { |
| 431 | char smc_host[SMC_MAX_HOSTNAME_LEN + 1]; | ||
| 432 | char smc_pnet[SMC_MAX_PNETID_LEN + 1]; | 495 | char smc_pnet[SMC_MAX_PNETID_LEN + 1]; |
| 433 | char smc_eid[SMC_MAX_EID_LEN + 1]; | ||
| 434 | struct nlattr *v2_attrs; | ||
| 435 | struct nlattr *attrs; | 496 | struct nlattr *attrs; |
| 436 | void *nlh; | 497 | void *nlh; |
| 437 | 498 | ||
| @@ -463,32 +524,19 @@ static int smc_nl_fill_smcd_lgr(struct smc_link_group *lgr, · 25 unmodified lines | |||
| 463 | smc_pnet[SMC_MAX_PNETID_LEN] = 0; | 524 | smc_pnet[SMC_MAX_PNETID_LEN] = 0; |
| 464 | if (nla_put_string(skb, SMC_NLA_LGR_D_PNETID, smc_pnet)) | 525 | if (nla_put_string(skb, SMC_NLA_LGR_D_PNETID, smc_pnet)) |
| 465 | goto errattr; | 526 | goto errattr; |
| 527 | if (lgr->smc_version > SMC_V1) { | ||
| 528 | struct nlattr *v2_attrs; | ||
| 466 | 529 | ||
| 467 | v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_V2); | 530 | v2_attrs = nla_nest_start(skb, SMC_NLA_LGR_D_V2_COMMON); |
| 468 | if (!v2_attrs) | 531 | if (!v2_attrs) |
| 469 | goto errattr; | 532 | goto errattr; |
| 470 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_VER, lgr->smc_version)) | 533 | if (smc_nl_fill_lgr_v2_common(lgr, skb, cb, v2_attrs)) |
| 471 | goto errv2attr; | 534 | goto errattr; |
| 472 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_REL, lgr->peer_smc_release)) | 535 | } |
| 473 | goto errv2attr; | ||
| 474 | if (nla_put_u8(skb, SMC_NLA_LGR_V2_OS, lgr->peer_os)) | ||
| 475 | goto errv2attr; | ||
| 476 | memcpy(smc_host, lgr->peer_hostname, SMC_MAX_HOSTNAME_LEN); | ||
| 477 | smc_host[SMC_MAX_HOSTNAME_LEN] = 0; | ||
| 478 | if (nla_put_string(skb, SMC_NLA_LGR_V2_PEER_HOST, smc_host)) | ||
| 479 | goto errv2attr; | ||
| 480 | memcpy(smc_eid, lgr->negotiated_eid, SMC_MAX_EID_LEN); | ||
| 481 | smc_eid[SMC_MAX_EID_LEN] = 0; | ||
| 482 | if (nla_put_string(skb, SMC_NLA_LGR_V2_NEG_EID, smc_eid)) | ||
| 483 | goto errv2attr; | ||
| 484 | |||
| 485 | nla_nest_end(skb, v2_attrs); | ||
| 486 | nla_nest_end(skb, attrs); | 536 | nla_nest_end(skb, attrs); |
| 487 | genlmsg_end(skb, nlh); | 537 | genlmsg_end(skb, nlh); |
| 488 | return 0; | 538 | return 0; |
| 489 | 539 | ||
| 490 | errv2attr: | ||
| 491 | nla_nest_cancel(skb, v2_attrs); | ||
| 492 | errattr: | 540 | errattr: |
| 493 | nla_nest_cancel(skb, attrs); | 541 | nla_nest_cancel(skb, attrs); |
| 494 | errout: | 542 | errout: |