#include <stdint.h>
#include <endian.h>
#include "librpmem.h"
#define PACKED __attribute__((packed))
#define RPMEM_PROTO "tcp"
#define RPMEM_PROTO_MAJOR 0
#define RPMEM_PROTO_MINOR 1
#define RPMEM_SIG_SIZE 8
#define RPMEM_UUID_SIZE 16
#define RPMEM_PROV_SIZE 32
#define RPMEM_USER_SIZE 16
enum rpmem_msg_type {
RPMEM_MSG_TYPE_CREATE = 1,
RPMEM_MSG_TYPE_CREATE_RESP = 2,
RPMEM_MSG_TYPE_OPEN = 3,
RPMEM_MSG_TYPE_OPEN_RESP = 4,
RPMEM_MSG_TYPE_CLOSE = 5,
RPMEM_MSG_TYPE_CLOSE_RESP = 6,
RPMEM_MSG_TYPE_SET_ATTR = 7,
RPMEM_MSG_TYPE_SET_ATTR_RESP = 8,
MAX_RPMEM_MSG_TYPE,
};
struct rpmem_pool_attr_packed {
char signature[RPMEM_POOL_HDR_SIG_LEN];
uint32_t major;
uint32_t compat_features;
uint32_t incompat_features;
uint32_t ro_compat_features;
unsigned char poolset_uuid[RPMEM_POOL_HDR_UUID_LEN];
unsigned char uuid[RPMEM_POOL_HDR_UUID_LEN];
unsigned char next_uuid[RPMEM_POOL_HDR_UUID_LEN];
unsigned char prev_uuid[RPMEM_POOL_HDR_UUID_LEN];
unsigned char user_flags[RPMEM_POOL_USER_FLAGS_LEN];
} PACKED;
struct rpmem_msg_ibc_attr {
uint32_t port;
uint32_t persist_method;
uint64_t rkey;
uint64_t raddr;
uint32_t nlanes;
} PACKED;
struct rpmem_msg_pool_desc {
uint32_t size;
uint8_t desc[0];
} PACKED;
struct rpmem_msg_hdr {
uint32_t type;
uint64_t size;
uint8_t body[0];
} PACKED;
struct rpmem_msg_hdr_resp {
uint32_t status;
uint32_t type;
uint64_t size;
} PACKED;
struct rpmem_msg_create {
struct rpmem_msg_hdr hdr;
uint16_t major;
uint16_t minor;
uint64_t pool_size;
uint32_t nlanes;
uint32_t provider;
struct rpmem_pool_attr_packed pool_attr;
struct rpmem_msg_pool_desc pool_desc;
} PACKED;
struct rpmem_msg_create_resp {
struct rpmem_msg_hdr_resp hdr;
struct rpmem_msg_ibc_attr ibc;
} PACKED;
struct rpmem_msg_open {
struct rpmem_msg_hdr hdr;
uint16_t major;
uint16_t minor;
uint64_t pool_size;
uint32_t nlanes;
uint32_t provider;
struct rpmem_msg_pool_desc pool_desc;
} PACKED;
struct rpmem_msg_open_resp {
struct rpmem_msg_hdr_resp hdr;
struct rpmem_msg_ibc_attr ibc;
struct rpmem_pool_attr_packed pool_attr;
} PACKED;
struct rpmem_msg_close {
struct rpmem_msg_hdr hdr;
} PACKED;
struct rpmem_msg_close_resp {
struct rpmem_msg_hdr_resp hdr;
} PACKED;
struct rpmem_msg_persist {
uint64_t lane;
uint64_t addr;
uint64_t size;
};
struct rpmem_msg_persist_resp {
uint64_t lane;
};
struct rpmem_msg_set_attr {
struct rpmem_msg_hdr hdr;
struct rpmem_pool_attr_packed pool_attr;
} PACKED;
struct rpmem_msg_set_attr_resp {
struct rpmem_msg_hdr_resp hdr;
} PACKED;
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wconversion"
static inline void
rpmem_ntoh_msg_ibc_attr(struct rpmem_msg_ibc_attr *ibc)
{
ibc->port = be32toh(ibc->port);
ibc->persist_method = be32toh(ibc->persist_method);
ibc->rkey = be64toh(ibc->rkey);
ibc->raddr = be64toh(ibc->raddr);
}
static inline void
rpmem_ntoh_msg_pool_desc(struct rpmem_msg_pool_desc *pool_desc)
{
pool_desc->size = be32toh(pool_desc->size);
}
static inline void
rpmem_ntoh_pool_attr(struct rpmem_pool_attr_packed *attr)
{
attr->major = be32toh(attr->major);
attr->ro_compat_features = be32toh(attr->ro_compat_features);
attr->incompat_features = be32toh(attr->incompat_features);
attr->compat_features = be32toh(attr->compat_features);
}
static inline void
rpmem_ntoh_msg_hdr(struct rpmem_msg_hdr *hdrp)
{
hdrp->type = be32toh(hdrp->type);
hdrp->size = be64toh(hdrp->size);
}
static inline void
rpmem_hton_msg_hdr(struct rpmem_msg_hdr *hdrp)
{
rpmem_ntoh_msg_hdr(hdrp);
}
static inline void
rpmem_ntoh_msg_hdr_resp(struct rpmem_msg_hdr_resp *hdrp)
{
hdrp->status = be32toh(hdrp->status);
hdrp->type = be32toh(hdrp->type);
hdrp->size = be64toh(hdrp->size);
}
static inline void
rpmem_hton_msg_hdr_resp(struct rpmem_msg_hdr_resp *hdrp)
{
rpmem_ntoh_msg_hdr_resp(hdrp);
}
static inline void
rpmem_ntoh_msg_create(struct rpmem_msg_create *msg)
{
rpmem_ntoh_msg_hdr(&msg->hdr);
msg->major = be16toh(msg->major);
msg->minor = be16toh(msg->minor);
msg->pool_size = be64toh(msg->pool_size);
msg->nlanes = be32toh(msg->nlanes);
msg->provider = be32toh(msg->provider);
rpmem_ntoh_pool_attr(&msg->pool_attr);
rpmem_ntoh_msg_pool_desc(&msg->pool_desc);
}
static inline void
rpmem_hton_msg_create(struct rpmem_msg_create *msg)
{
rpmem_ntoh_msg_create(msg);
}
static inline void
rpmem_ntoh_msg_create_resp(struct rpmem_msg_create_resp *msg)
{
rpmem_ntoh_msg_hdr_resp(&msg->hdr);
rpmem_ntoh_msg_ibc_attr(&msg->ibc);
}
static inline void
rpmem_hton_msg_create_resp(struct rpmem_msg_create_resp *msg)
{
rpmem_ntoh_msg_create_resp(msg);
}
static inline void
rpmem_ntoh_msg_open(struct rpmem_msg_open *msg)
{
rpmem_ntoh_msg_hdr(&msg->hdr);
msg->major = be16toh(msg->major);
msg->minor = be16toh(msg->minor);
msg->pool_size = be64toh(msg->pool_size);
msg->nlanes = be32toh(msg->nlanes);
msg->provider = be32toh(msg->provider);
rpmem_ntoh_msg_pool_desc(&msg->pool_desc);
}
#pragma GCC diagnostic pop
static inline void
rpmem_hton_msg_open(struct rpmem_msg_open *msg)
{
rpmem_ntoh_msg_open(msg);
}
static inline void
rpmem_ntoh_msg_open_resp(struct rpmem_msg_open_resp *msg)
{
rpmem_ntoh_msg_hdr_resp(&msg->hdr);
rpmem_ntoh_msg_ibc_attr(&msg->ibc);
rpmem_ntoh_pool_attr(&msg->pool_attr);
}
static inline void
rpmem_hton_msg_open_resp(struct rpmem_msg_open_resp *msg)
{
rpmem_ntoh_msg_open_resp(msg);
}
static inline void
rpmem_ntoh_msg_set_attr(struct rpmem_msg_set_attr *msg)
{
rpmem_ntoh_msg_hdr(&msg->hdr);
rpmem_ntoh_pool_attr(&msg->pool_attr);
}
static inline void
rpmem_hton_msg_set_attr(struct rpmem_msg_set_attr *msg)
{
rpmem_ntoh_msg_set_attr(msg);
}
static inline void
rpmem_ntoh_msg_set_attr_resp(struct rpmem_msg_set_attr_resp *msg)
{
rpmem_ntoh_msg_hdr_resp(&msg->hdr);
}
static inline void
rpmem_hton_msg_set_attr_resp(struct rpmem_msg_set_attr_resp *msg)
{
rpmem_hton_msg_hdr_resp(&msg->hdr);
}
static inline void
rpmem_ntoh_msg_close(struct rpmem_msg_close *msg)
{
rpmem_ntoh_msg_hdr(&msg->hdr);
}
static inline void
rpmem_hton_msg_close(struct rpmem_msg_close *msg)
{
rpmem_ntoh_msg_close(msg);
}
static inline void
rpmem_ntoh_msg_close_resp(struct rpmem_msg_close_resp *msg)
{
rpmem_ntoh_msg_hdr_resp(&msg->hdr);
}
static inline void
rpmem_hton_msg_close_resp(struct rpmem_msg_close_resp *msg)
{
rpmem_ntoh_msg_close_resp(msg);
}
static inline void
pack_rpmem_pool_attr(const struct rpmem_pool_attr *src,
struct rpmem_pool_attr_packed *dst)
{
memcpy(dst->signature, src->signature, sizeof(src->signature));
dst->major = src->major;
dst->compat_features = src->compat_features;
dst->incompat_features = src->incompat_features;
dst->ro_compat_features = src->ro_compat_features;
memcpy(dst->poolset_uuid, src->poolset_uuid, sizeof(dst->poolset_uuid));
memcpy(dst->uuid, src->uuid, sizeof(dst->uuid));
memcpy(dst->next_uuid, src->next_uuid, sizeof(dst->next_uuid));
memcpy(dst->prev_uuid, src->prev_uuid, sizeof(dst->prev_uuid));
memcpy(dst->user_flags, src->user_flags, sizeof(dst->user_flags));
}
static inline void
unpack_rpmem_pool_attr(const struct rpmem_pool_attr_packed *src,
struct rpmem_pool_attr *dst)
{
memcpy(dst->signature, src->signature, sizeof(src->signature));
dst->major = src->major;
dst->compat_features = src->compat_features;
dst->incompat_features = src->incompat_features;
dst->ro_compat_features = src->ro_compat_features;
memcpy(dst->poolset_uuid, src->poolset_uuid, sizeof(dst->poolset_uuid));
memcpy(dst->uuid, src->uuid, sizeof(dst->uuid));
memcpy(dst->next_uuid, src->next_uuid, sizeof(dst->next_uuid));
memcpy(dst->prev_uuid, src->prev_uuid, sizeof(dst->prev_uuid));
memcpy(dst->user_flags, src->user_flags, sizeof(dst->user_flags));
}