1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/ceph/ceph_debug.h>
4 #include <linux/inet.h>
6 #include <linux/ceph/decode.h>
9 ceph_decode_entity_addr_versioned(void **p
, void *end
,
10 struct ceph_entity_addr
*addr
)
14 u32 struct_len
, addr_len
;
17 ret
= ceph_start_decoding(p
, end
, 1, "entity_addr_t", &struct_v
,
23 struct_end
= *p
+ struct_len
;
25 ceph_decode_copy_safe(p
, end
, &addr
->type
, sizeof(addr
->type
), bad
);
27 ceph_decode_copy_safe(p
, end
, &addr
->nonce
, sizeof(addr
->nonce
), bad
);
29 ceph_decode_32_safe(p
, end
, addr_len
, bad
);
30 if (addr_len
> sizeof(addr
->in_addr
))
33 memset(&addr
->in_addr
, 0, sizeof(addr
->in_addr
));
35 ceph_decode_copy_safe(p
, end
, &addr
->in_addr
, addr_len
, bad
);
37 addr
->in_addr
.ss_family
=
38 le16_to_cpu((__force __le16
)addr
->in_addr
.ss_family
);
41 /* Advance past anything the client doesn't yet understand */
49 ceph_decode_entity_addr_legacy(void **p
, void *end
,
50 struct ceph_entity_addr
*addr
)
54 /* Skip rest of type field */
55 ceph_decode_skip_n(p
, end
, 3, bad
);
58 * Clients that don't support ADDR2 always send TYPE_NONE, change it
59 * to TYPE_LEGACY for forward compatibility.
61 addr
->type
= CEPH_ENTITY_ADDR_TYPE_LEGACY
;
62 ceph_decode_copy_safe(p
, end
, &addr
->nonce
, sizeof(addr
->nonce
), bad
);
63 memset(&addr
->in_addr
, 0, sizeof(addr
->in_addr
));
64 ceph_decode_copy_safe(p
, end
, &addr
->in_addr
,
65 sizeof(addr
->in_addr
), bad
);
66 addr
->in_addr
.ss_family
=
67 be16_to_cpu((__force __be16
)addr
->in_addr
.ss_family
);
74 ceph_decode_entity_addr(void **p
, void *end
, struct ceph_entity_addr
*addr
)
78 ceph_decode_8_safe(p
, end
, marker
, bad
);
80 return ceph_decode_entity_addr_versioned(p
, end
, addr
);
82 return ceph_decode_entity_addr_legacy(p
, end
, addr
);
86 EXPORT_SYMBOL(ceph_decode_entity_addr
);
89 * Return addr of desired type (MSGR2 or LEGACY) or error.
90 * Make sure there is only one match.
92 * Assume encoding with MSG_ADDR2.
94 int ceph_decode_entity_addrvec(void **p
, void *end
, bool msgr2
,
95 struct ceph_entity_addr
*addr
)
97 __le32 my_type
= msgr2
? CEPH_ENTITY_ADDR_TYPE_MSGR2
:
98 CEPH_ENTITY_ADDR_TYPE_LEGACY
;
99 struct ceph_entity_addr tmp_addr
;
106 ceph_decode_8_safe(p
, end
, marker
, e_inval
);
108 pr_err("bad addrvec marker %d\n", marker
);
112 ceph_decode_32_safe(p
, end
, addr_cnt
, e_inval
);
115 for (i
= 0; i
< addr_cnt
; i
++) {
116 ret
= ceph_decode_entity_addr(p
, end
, &tmp_addr
);
120 if (tmp_addr
.type
== my_type
) {
122 pr_err("another match of type %d in addrvec\n",
123 le32_to_cpu(my_type
));
127 memcpy(addr
, &tmp_addr
, sizeof(*addr
));
131 if (!found
&& addr_cnt
!= 0) {
132 pr_err("no match of type %d in addrvec\n",
133 le32_to_cpu(my_type
));
142 EXPORT_SYMBOL(ceph_decode_entity_addrvec
);
144 static int get_sockaddr_encoding_len(sa_family_t family
)
148 struct sockaddr_in sin
;
149 struct sockaddr_in6 sin6
;
154 return sizeof(u
.sin
);
156 return sizeof(u
.sin6
);
162 int ceph_entity_addr_encoding_len(const struct ceph_entity_addr
*addr
)
164 sa_family_t family
= get_unaligned(&addr
->in_addr
.ss_family
);
165 int addr_len
= get_sockaddr_encoding_len(family
);
167 return 1 + CEPH_ENCODING_START_BLK_LEN
+ 4 + 4 + 4 + addr_len
;
170 void ceph_encode_entity_addr(void **p
, const struct ceph_entity_addr
*addr
)
172 sa_family_t family
= get_unaligned(&addr
->in_addr
.ss_family
);
173 int addr_len
= get_sockaddr_encoding_len(family
);
175 ceph_encode_8(p
, 1); /* marker */
176 ceph_start_encoding(p
, 1, 1, sizeof(addr
->type
) +
177 sizeof(addr
->nonce
) +
178 sizeof(u32
) + addr_len
);
179 ceph_encode_copy(p
, &addr
->type
, sizeof(addr
->type
));
180 ceph_encode_copy(p
, &addr
->nonce
, sizeof(addr
->nonce
));
182 ceph_encode_32(p
, addr_len
);
183 ceph_encode_16(p
, family
);
184 ceph_encode_copy(p
, addr
->in_addr
.__data
, addr_len
- sizeof(family
));