hc
2025-02-14 bbb9540dc49f70f6b703d1c8d1b85fa5f602d86e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// SPDX-License-Identifier: GPL-2.0
 
#include <linux/ceph/decode.h>
 
static int
ceph_decode_entity_addr_versioned(void **p, void *end,
                 struct ceph_entity_addr *addr)
{
   int ret;
   u8 struct_v;
   u32 struct_len, addr_len;
   void *struct_end;
 
   ret = ceph_start_decoding(p, end, 1, "entity_addr_t", &struct_v,
                 &struct_len);
   if (ret)
       goto bad;
 
   ret = -EINVAL;
   struct_end = *p + struct_len;
 
   ceph_decode_copy_safe(p, end, &addr->type, sizeof(addr->type), bad);
 
   ceph_decode_copy_safe(p, end, &addr->nonce, sizeof(addr->nonce), bad);
 
   ceph_decode_32_safe(p, end, addr_len, bad);
   if (addr_len > sizeof(addr->in_addr))
       goto bad;
 
   memset(&addr->in_addr, 0, sizeof(addr->in_addr));
   if (addr_len) {
       ceph_decode_copy_safe(p, end, &addr->in_addr, addr_len, bad);
 
       addr->in_addr.ss_family =
           le16_to_cpu((__force __le16)addr->in_addr.ss_family);
   }
 
   /* Advance past anything the client doesn't yet understand */
   *p = struct_end;
   ret = 0;
bad:
   return ret;
}
 
static int
ceph_decode_entity_addr_legacy(void **p, void *end,
                  struct ceph_entity_addr *addr)
{
   int ret = -EINVAL;
 
   /* Skip rest of type field */
   ceph_decode_skip_n(p, end, 3, bad);
 
   /*
    * Clients that don't support ADDR2 always send TYPE_NONE, change it
    * to TYPE_LEGACY for forward compatibility.
    */
   addr->type = CEPH_ENTITY_ADDR_TYPE_LEGACY;
   ceph_decode_copy_safe(p, end, &addr->nonce, sizeof(addr->nonce), bad);
   memset(&addr->in_addr, 0, sizeof(addr->in_addr));
   ceph_decode_copy_safe(p, end, &addr->in_addr,
                 sizeof(addr->in_addr), bad);
   addr->in_addr.ss_family =
           be16_to_cpu((__force __be16)addr->in_addr.ss_family);
   ret = 0;
bad:
   return ret;
}
 
int
ceph_decode_entity_addr(void **p, void *end, struct ceph_entity_addr *addr)
{
   u8 marker;
 
   ceph_decode_8_safe(p, end, marker, bad);
   if (marker == 1)
       return ceph_decode_entity_addr_versioned(p, end, addr);
   else if (marker == 0)
       return ceph_decode_entity_addr_legacy(p, end, addr);
bad:
   return -EINVAL;
}
EXPORT_SYMBOL(ceph_decode_entity_addr);