On Fri, Jun 7, 2019 at 11:38 PM Jeff Layton <jlayton(a)kernel.org> wrote:
Add a way to decode an entity_addr_t. Once CEPH_FEATURE_MSG_ADDR2 is
enabled, the server daemons will start encoding entity_addr_t
differently.
Add a new helper function that can handle either format.
Signed-off-by: Jeff Layton <jlayton(a)kernel.org>
---
include/linux/ceph/decode.h | 2 +
net/ceph/Makefile | 2 +-
net/ceph/decode.c | 75 +++++++++++++++++++++++++++++++++++++
3 files changed, 78 insertions(+), 1 deletion(-)
create mode 100644 net/ceph/decode.c
diff --git a/include/linux/ceph/decode.h b/include/linux/ceph/decode.h
index a6c2a48d42e0..1c0a665bfc03 100644
--- a/include/linux/ceph/decode.h
+++ b/include/linux/ceph/decode.h
@@ -230,6 +230,8 @@ static inline void ceph_decode_addr(struct ceph_entity_addr *a)
WARN_ON(a->in_addr.ss_family == 512);
}
+extern int ceph_decode_entity_addr(void **p, void *end,
+ struct ceph_entity_addr *addr);
/*
* encoders
*/
diff --git a/net/ceph/Makefile b/net/ceph/Makefile
index db09defe27d0..59d0ba2072de 100644
--- a/net/ceph/Makefile
+++ b/net/ceph/Makefile
@@ -5,7 +5,7 @@
obj-$(CONFIG_CEPH_LIB) += libceph.o
libceph-y := ceph_common.o messenger.o msgpool.o buffer.o pagelist.o \
- mon_client.o \
+ mon_client.o decode.o \
cls_lock_client.o \
osd_client.o osdmap.o crush/crush.o crush/mapper.o crush/hash.o \
striper.o \
diff --git a/net/ceph/decode.c b/net/ceph/decode.c
new file mode 100644
index 000000000000..27edf5d341ec
--- /dev/null
+++ b/net/ceph/decode.c
@@ -0,0 +1,75 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/ceph/decode.h>
+
+int
+ceph_decode_entity_addr(void **p, void *end, struct ceph_entity_addr *addr)
+{
+ u8 marker, v, compat;
It's better to use name struct_v, struct_compat
+ u32 len;
+
+ ceph_decode_8_safe(p, end, marker, bad);
+ if (marker == 1) {
+ ceph_decode_8_safe(p, end, v, bad);
+ ceph_decode_8_safe(p, end, compat, bad);
+ if (!v || compat != 1)
+ goto bad;
+ /* FIXME: sanity check? */
+ ceph_decode_32_safe(p, end, len, bad);
+ /* type is __le32, so we must copy into place as-is */
+ ceph_decode_copy_safe(p, end, &addr->type,
+ sizeof(addr->type), bad);
+
+ /*
+ * TYPE_NONE == 0
+ * TYPE_LEGACY == 1
+ *
+ * Clients that don't support ADDR2 always send TYPE_NONE.
+ * For now, since all we support is msgr1, just set this to 0
+ * when we get a TYPE_LEGACY type.
+ */
+ if (addr->type == cpu_to_le32(1))
+ addr->type = 0;
+ } else if (marker == 0) {
+ addr->type = 0;
+ /* Skip rest of type field */
+ ceph_decode_skip_n(p, end, 3, bad);
+ } else {
versioned encoding has forward compatibility. The code should looks like
if (struct_v == 0) {
/* old format */
return;
}
if (struct_compat != 1)
goto bad
end = *p + struct_len;
if (struct_v == 1) {
....
}
if (struct_v == 2) {
...
}
*p = end;
> + goto bad;
> + }
> +
> + ceph_decode_need(p, end, sizeof(addr->nonce), bad);
> + ceph_decode_copy(p, &addr->nonce, sizeof(addr->nonce));
> +
> + /* addr length */
> + if (marker == 1) {
> + ceph_decode_32_safe(p, end, len, bad);
> + if (len > sizeof(addr->in_addr))
> + goto bad;
> + } else {
> + len = sizeof(addr->in_addr);
> + }
> +
> + memset(&addr->in_addr, 0, sizeof(addr->in_addr));
> +
> + if (len) {
> + ceph_decode_need(p, end, len, bad);
> + ceph_decode_copy(p, &addr->in_addr, len);
> +
> + /*
> + * Fix up sa_family. Legacy encoding sends it in BE, addr2
> + * encoding uses LE.
> + */
> + if (marker == 1)
> + addr->in_addr.ss_family =
> + le16_to_cpu((__force
__le16)addr->in_addr.ss_family);
> + else
> + addr->in_addr.ss_family =
> + be16_to_cpu((__force
__be16)addr->in_addr.ss_family);
> + }
> + return 0;
> +bad:
> + return -EINVAL;
> +}
> +EXPORT_SYMBOL(ceph_decode_entity_addr);
> +
> --
> 2.21.0
> _______________________________________________
> Dev mailing list -- dev(a)ceph.io
> To unsubscribe send an email to dev-leave(a)ceph.io