From c9fbfcbc41aed4a1fd31bfd2a66df69f86ef48e8 Mon Sep 17 00:00:00 2001 From: Olaf Weber Date: Mon, 27 Mar 2017 12:22:55 +0200 Subject: [PATCH] LU-9480 lnet: add sanity checks on ping-related constants Add sanity checks for LNet ping related data structures and constants to wirecheck.c, and update the generated code in lnet_assert_wire_constants(). In order for the structures and macros to be visible to wirecheck.c, which is a userspace program, they were moved from kernel-only lnet/lib-types.h to lnet/types.h Test-Parameters: trivial Signed-off-by: Olaf Weber Change-Id: I2949d27445b29ec69cf8c17b7769291f270a5923 Reviewed-on: https://review.whamcloud.com/25776 Reviewed-by: Amir Shehata Tested-by: Amir Shehata --- lnet/include/lnet/lib-types.h | 42 -------------------------- lnet/include/uapi/linux/lnet/lnet-types.h | 44 +++++++++++++++++++++++++++ lnet/lnet/api-ni.c | 37 +++++++++++++++++++++++ lnet/utils/wirecheck.c | 49 ++++++++++++++++++++++++++++--- 4 files changed, 126 insertions(+), 46 deletions(-) diff --git a/lnet/include/lnet/lib-types.h b/lnet/include/lnet/lib-types.h index 77e57af..fbd4bc9 100644 --- a/lnet/include/lnet/lib-types.h +++ b/lnet/include/lnet/lib-types.h @@ -256,12 +256,6 @@ typedef struct lnet_lnd { int (*lnd_accept)(struct lnet_ni *ni, struct socket *sock); } lnd_t; -typedef struct lnet_ni_status { - lnet_nid_t ns_nid; - __u32 ns_status; - __u32 ns_unused; -} WIRE_ATTR lnet_ni_status_t; - struct lnet_tx_queue { int tq_credits; /* # tx credits free */ int tq_credits_min; /* lowest it's been */ @@ -410,42 +404,6 @@ typedef struct lnet_ni { #define LNET_PROTO_PING_MATCHBITS 0x8000000000000000LL -/* NB: value of these features equal to LNET_PROTO_PING_VERSION_x - * of old LNet, so there shouldn't be any compatibility issue */ -#define LNET_PING_FEAT_INVAL (0) /* no feature */ -#define LNET_PING_FEAT_BASE (1 << 0) /* just a ping */ -#define LNET_PING_FEAT_NI_STATUS (1 << 1) /* return NI status */ -#define LNET_PING_FEAT_RTE_DISABLED (1 << 2) /* Routing enabled */ -#define LNET_PING_FEAT_MULTI_RAIL (1 << 3) /* Multi-Rail aware */ -#define LNET_PING_FEAT_DISCOVERY (1 << 4) /* Supports Discovery */ - -/* - * All ping feature bits fit to hit the wire. - * In lnet_assert_wire_constants() this is compared against its open-coded - * value, and in lnet_ping_target_update() it is used to verify that no - * unknown bits have been set. - * New feature bits can be added, just be aware that this does change the - * over-the-wire protocol. - */ -#define LNET_PING_FEAT_BITS (LNET_PING_FEAT_BASE | \ - LNET_PING_FEAT_NI_STATUS | \ - LNET_PING_FEAT_RTE_DISABLED | \ - LNET_PING_FEAT_MULTI_RAIL | \ - LNET_PING_FEAT_DISCOVERY) - -typedef struct lnet_ping_info { - __u32 pi_magic; - __u32 pi_features; - lnet_pid_t pi_pid; - __u32 pi_nnis; - struct lnet_ni_status pi_ni[0]; -} WIRE_ATTR lnet_ping_info_t; - -#define LNET_PING_INFO_SIZE(NNIDS) \ - offsetof(struct lnet_ping_info, pi_ni[NNIDS]) -#define LNET_PING_INFO_LONI(PINFO) ((PINFO)->pi_ni[0].ns_nid) -#define LNET_PING_INFO_SEQNO(PINFO) ((PINFO)->pi_ni[0].ns_status) - /* * Descriptor of a ping info buffer: keep a separate indicator of the * size and a reference count. The type is used both as a source and diff --git a/lnet/include/uapi/linux/lnet/lnet-types.h b/lnet/include/uapi/linux/lnet/lnet-types.h index 520f8ff..a80cc73 100644 --- a/lnet/include/uapi/linux/lnet/lnet-types.h +++ b/lnet/include/uapi/linux/lnet/lnet-types.h @@ -241,6 +241,50 @@ typedef struct lnet_counters { #define LNET_NI_STATUS_DOWN 0xdeadface #define LNET_NI_STATUS_INVALID 0x00000000 +struct lnet_ni_status { + lnet_nid_t ns_nid; + __u32 ns_status; + __u32 ns_unused; +} WIRE_ATTR; + +/* + * NB: value of these features equal to LNET_PROTO_PING_VERSION_x + * of old LNet, so there shouldn't be any compatibility issue + */ +#define LNET_PING_FEAT_INVAL (0) /* no feature */ +#define LNET_PING_FEAT_BASE (1 << 0) /* just a ping */ +#define LNET_PING_FEAT_NI_STATUS (1 << 1) /* return NI status */ +#define LNET_PING_FEAT_RTE_DISABLED (1 << 2) /* Routing enabled */ +#define LNET_PING_FEAT_MULTI_RAIL (1 << 3) /* Multi-Rail aware */ +#define LNET_PING_FEAT_DISCOVERY (1 << 4) /* Supports Discovery */ + +/* + * All ping feature bits fit to hit the wire. + * In lnet_assert_wire_constants() this is compared against its open-coded + * value, and in lnet_ping_target_update() it is used to verify that no + * unknown bits have been set. + * New feature bits can be added, just be aware that this does change the + * over-the-wire protocol. + */ +#define LNET_PING_FEAT_BITS (LNET_PING_FEAT_BASE | \ + LNET_PING_FEAT_NI_STATUS | \ + LNET_PING_FEAT_RTE_DISABLED | \ + LNET_PING_FEAT_MULTI_RAIL | \ + LNET_PING_FEAT_DISCOVERY) + +struct lnet_ping_info { + __u32 pi_magic; + __u32 pi_features; + lnet_pid_t pi_pid; + __u32 pi_nnis; + struct lnet_ni_status pi_ni[0]; +} WIRE_ATTR; + +#define LNET_PING_INFO_SIZE(NNIDS) \ + offsetof(struct lnet_ping_info, pi_ni[NNIDS]) +#define LNET_PING_INFO_LONI(PINFO) ((PINFO)->pi_ni[0].ns_nid) +#define LNET_PING_INFO_SEQNO(PINFO) ((PINFO)->pi_ni[0].ns_status) + /* * This is a hard-coded limit on the number of interfaces supported by * the interface bonding implemented by the ksocknal LND. It must be diff --git a/lnet/lnet/api-ni.c b/lnet/lnet/api-ni.c index 25bac83..edff400 100644 --- a/lnet/lnet/api-ni.c +++ b/lnet/lnet/api-ni.c @@ -356,6 +356,43 @@ static void lnet_assert_wire_constants(void) CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.hello.incarnation) == 8); CLASSERT((int)offsetof(struct lnet_hdr, msg.hello.type) == 40); CLASSERT((int)sizeof(((struct lnet_hdr *)0)->msg.hello.type) == 4); + + /* Checks for struct lnet_ni_status and related constants */ + CLASSERT(LNET_NI_STATUS_INVALID == 0x00000000); + CLASSERT(LNET_NI_STATUS_UP == 0x15aac0de); + CLASSERT(LNET_NI_STATUS_DOWN == 0xdeadface); + + /* Checks for struct lnet_ni_status */ + CLASSERT((int)sizeof(struct lnet_ni_status) == 16); + CLASSERT((int)offsetof(struct lnet_ni_status, ns_nid) == 0); + CLASSERT((int)sizeof(((struct lnet_ni_status *)0)->ns_nid) == 8); + CLASSERT((int)offsetof(struct lnet_ni_status, ns_status) == 8); + CLASSERT((int)sizeof(((struct lnet_ni_status *)0)->ns_status) == 4); + CLASSERT((int)offsetof(struct lnet_ni_status, ns_unused) == 12); + CLASSERT((int)sizeof(((struct lnet_ni_status *)0)->ns_unused) == 4); + + /* Checks for struct lnet_ping_info and related constants */ + CLASSERT(LNET_PROTO_PING_MAGIC == 0x70696E67); + CLASSERT(LNET_PING_FEAT_INVAL == 0); + CLASSERT(LNET_PING_FEAT_BASE == 1); + CLASSERT(LNET_PING_FEAT_NI_STATUS == 2); + CLASSERT(LNET_PING_FEAT_RTE_DISABLED == 4); + CLASSERT(LNET_PING_FEAT_MULTI_RAIL == 8); + CLASSERT(LNET_PING_FEAT_DISCOVERY == 16); + CLASSERT(LNET_PING_FEAT_BITS == 31); + + /* Checks for struct lnet_ping_info */ + CLASSERT((int)sizeof(struct lnet_ping_info) == 16); + CLASSERT((int)offsetof(struct lnet_ping_info, pi_magic) == 0); + CLASSERT((int)sizeof(((struct lnet_ping_info *)0)->pi_magic) == 4); + CLASSERT((int)offsetof(struct lnet_ping_info, pi_features) == 4); + CLASSERT((int)sizeof(((struct lnet_ping_info *)0)->pi_features) == 4); + CLASSERT((int)offsetof(struct lnet_ping_info, pi_pid) == 8); + CLASSERT((int)sizeof(((struct lnet_ping_info *)0)->pi_pid) == 4); + CLASSERT((int)offsetof(struct lnet_ping_info, pi_nnis) == 12); + CLASSERT((int)sizeof(((struct lnet_ping_info *)0)->pi_nnis) == 4); + CLASSERT((int)offsetof(struct lnet_ping_info, pi_ni) == 16); + CLASSERT((int)sizeof(((struct lnet_ping_info *)0)->pi_ni) == 0); } static struct lnet_lnd *lnet_find_lnd_by_type(__u32 type) diff --git a/lnet/utils/wirecheck.c b/lnet/utils/wirecheck.c index a607ded..41d8073 100644 --- a/lnet/utils/wirecheck.c +++ b/lnet/utils/wirecheck.c @@ -154,7 +154,46 @@ check_lnet_hdr (void) } void -system_string (char *cmdline, char *str, int len) +check_lnet_ni_status(void) +{ + BLANK_LINE(); + COMMENT("Checks for struct lnet_ni_status and related constants"); + + CHECK_DEFINE(LNET_NI_STATUS_INVALID); + CHECK_DEFINE(LNET_NI_STATUS_UP); + CHECK_DEFINE(LNET_NI_STATUS_DOWN); + + CHECK_STRUCT(struct lnet_ni_status); + CHECK_MEMBER(struct lnet_ni_status, ns_nid); + CHECK_MEMBER(struct lnet_ni_status, ns_status); + CHECK_MEMBER(struct lnet_ni_status, ns_unused); +} + +void +check_lnet_ping_info(void) +{ + BLANK_LINE(); + COMMENT("Checks for struct lnet_ping_info and related constants"); + + CHECK_DEFINE(LNET_PROTO_PING_MAGIC); + CHECK_VALUE(LNET_PING_FEAT_INVAL); + CHECK_VALUE(LNET_PING_FEAT_BASE); + CHECK_VALUE(LNET_PING_FEAT_NI_STATUS); + CHECK_VALUE(LNET_PING_FEAT_RTE_DISABLED); + CHECK_VALUE(LNET_PING_FEAT_MULTI_RAIL); + CHECK_VALUE(LNET_PING_FEAT_DISCOVERY); + CHECK_VALUE(LNET_PING_FEAT_BITS); + + CHECK_STRUCT(struct lnet_ping_info); + CHECK_MEMBER(struct lnet_ping_info, pi_magic); + CHECK_MEMBER(struct lnet_ping_info, pi_features); + CHECK_MEMBER(struct lnet_ping_info, pi_pid); + CHECK_MEMBER(struct lnet_ping_info, pi_nnis); + CHECK_MEMBER(struct lnet_ping_info, pi_ni); +} + +void +system_string(char *cmdline, char *str, int len) { int fds[2]; int rc; @@ -237,9 +276,11 @@ main (int argc, char **argv) CHECK_VALUE (LNET_MSG_REPLY); CHECK_VALUE (LNET_MSG_HELLO); - check_lnet_handle_wire (); - check_lnet_magicversion (); - check_lnet_hdr (); + check_lnet_handle_wire(); + check_lnet_magicversion(); + check_lnet_hdr(); + check_lnet_ni_status(); + check_lnet_ping_info(); printf ("}\n\n"); -- 1.8.3.1