File: nbd-protocol.h

package info (click to toggle)
libnbd 1.22.5-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,636 kB
  • sloc: ansic: 53,855; ml: 12,311; sh: 8,499; python: 4,595; makefile: 2,902; perl: 165; cpp: 24
file content (326 lines) | stat: -rw-r--r-- 12,485 bytes parent folder | download | duplicates (2)
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
/* nbdkit
 * Copyright Red Hat
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 * * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *
 * * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * * Neither the name of Red Hat nor the names of its contributors may be
 * used to endorse or promote products derived from this software without
 * specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#ifndef NBD_PROTOCOL_H
#define NBD_PROTOCOL_H

#include <stdint.h>

/* Note that all NBD fields are sent on the wire in network byte
 * order, so you must use beXXtoh or htobeXX when reading or writing
 * these structures.
 */

#if defined (__GNUC__) || defined (__clang__)
#define NBD_ATTRIBUTE_PACKED __attribute__ ((__packed__))
#else
#error "Please port to your compiler's notion of a packed struct"
#endif

#define NBD_MAX_STRING 4096 /* Maximum length of a string field */

/* Old-style handshake. */
struct nbd_old_handshake {
  uint64_t nbdmagic;          /* NBD_MAGIC */
  uint64_t version;           /* NBD_OLD_VERSION */
  uint64_t exportsize;
  uint16_t gflags;            /* global flags */
  uint16_t eflags;            /* per-export flags */
  char zeroes[124];           /* must be sent as zero bytes */
} NBD_ATTRIBUTE_PACKED;

#define NBD_MAGIC       UINT64_C (0x4e42444d41474943) /* ASCII "NBDMAGIC" */
#define NBD_OLD_VERSION UINT64_C (0x0000420281861253)

/* New-style handshake. */
struct nbd_new_handshake {
  uint64_t nbdmagic;          /* NBD_MAGIC */
  uint64_t version;           /* NBD_NEW_VERSION */
  uint16_t gflags;            /* global flags */
} NBD_ATTRIBUTE_PACKED;

#define NBD_NEW_VERSION UINT64_C (0x49484156454F5054) /* ASCII "IHAVEOPT" */

/* New-style handshake option (sent by the client to us). */
struct nbd_new_option {
  uint64_t version;           /* NBD_NEW_VERSION */
  uint32_t option;            /* NBD_OPT_* */
  uint32_t optlen;            /* option data length */
  /* option data follows */
} NBD_ATTRIBUTE_PACKED;

/* Newstyle handshake OPT_EXPORT_NAME reply message.
 * Modern clients use NBD_OPT_GO instead of this.
 */
struct nbd_export_name_option_reply {
  uint64_t exportsize;        /* size of export */
  uint16_t eflags;            /* per-export flags */
  char zeroes[124];           /* optional zeroes, unless NBD_FLAG_NO_ZEROES */
} NBD_ATTRIBUTE_PACKED;

/* Fixed newstyle handshake reply message. */
struct nbd_fixed_new_option_reply {
  uint64_t magic;             /* NBD_REP_MAGIC */
  uint32_t option;            /* option we are replying to */
  uint32_t reply;             /* NBD_REP_* */
  uint32_t replylen;
} NBD_ATTRIBUTE_PACKED;

#define NBD_REP_MAGIC UINT64_C (0x3e889045565a9)

/* Global flags. */
#define NBD_FLAG_FIXED_NEWSTYLE       (1U << 0)
#define NBD_FLAG_NO_ZEROES            (1U << 1)

/* Per-export flags. */
#define NBD_FLAG_HAS_FLAGS            (1U << 0)
#define NBD_FLAG_READ_ONLY            (1U << 1)
#define NBD_FLAG_SEND_FLUSH           (1U << 2)
#define NBD_FLAG_SEND_FUA             (1U << 3)
#define NBD_FLAG_ROTATIONAL           (1U << 4)
#define NBD_FLAG_SEND_TRIM            (1U << 5)
#define NBD_FLAG_SEND_WRITE_ZEROES    (1U << 6)
#define NBD_FLAG_SEND_DF              (1U << 7)
#define NBD_FLAG_CAN_MULTI_CONN       (1U << 8)
#define NBD_FLAG_SEND_CACHE           (1U << 10)
#define NBD_FLAG_SEND_FAST_ZERO       (1U << 11)
#define NBD_FLAG_BLOCK_STATUS_PAYLOAD (1U << 12)

/* NBD options (new style handshake only). */
#define NBD_OPT_EXPORT_NAME        1
#define NBD_OPT_ABORT              2
#define NBD_OPT_LIST               3
#define NBD_OPT_STARTTLS           5
#define NBD_OPT_INFO               6
#define NBD_OPT_GO                 7
#define NBD_OPT_STRUCTURED_REPLY   8
#define NBD_OPT_LIST_META_CONTEXT  9
#define NBD_OPT_SET_META_CONTEXT   10
#define NBD_OPT_EXTENDED_HEADERS   11

#define NBD_REP_ERR(val) (0x80000000 | (val))
#define NBD_REP_IS_ERR(val) (!!((val) & 0x80000000))

#define NBD_REP_ACK                  1
#define NBD_REP_SERVER               2
#define NBD_REP_INFO                 3
#define NBD_REP_META_CONTEXT         4
#define NBD_REP_ERR_UNSUP            NBD_REP_ERR (1)
#define NBD_REP_ERR_POLICY           NBD_REP_ERR (2)
#define NBD_REP_ERR_INVALID          NBD_REP_ERR (3)
#define NBD_REP_ERR_PLATFORM         NBD_REP_ERR (4)
#define NBD_REP_ERR_TLS_REQD         NBD_REP_ERR (5)
#define NBD_REP_ERR_UNKNOWN          NBD_REP_ERR (6)
#define NBD_REP_ERR_SHUTDOWN         NBD_REP_ERR (7)
#define NBD_REP_ERR_BLOCK_SIZE_REQD  NBD_REP_ERR (8)
#define NBD_REP_ERR_TOO_BIG          NBD_REP_ERR (9)
#define NBD_REP_ERR_EXT_HEADER_REQD  NBD_REP_ERR (10)

#define NBD_INFO_EXPORT      0
#define NBD_INFO_NAME        1
#define NBD_INFO_DESCRIPTION 2
#define NBD_INFO_BLOCK_SIZE  3

/* NBD_INFO_EXPORT reply (follows fixed_new_option_reply). */
struct nbd_fixed_new_option_reply_info_export {
  uint16_t info;                /* NBD_INFO_EXPORT */
  uint64_t exportsize;          /* size of export */
  uint16_t eflags;              /* per-export flags */
} NBD_ATTRIBUTE_PACKED;

/* NBD_INFO_NAME or NBD_INFO_DESCRIPTION reply (follows
 * fixed_new_option_reply).
 */
struct nbd_fixed_new_option_reply_info_name_or_desc {
  uint16_t info;                /* NBD_INFO_NAME, NBD_INFO_DESCRIPTION */
  /* followed by a string name or description */
} NBD_ATTRIBUTE_PACKED;

/* NBD_INFO_BLOCK_SIZE reply (follows fixed_new_option_reply). */
struct nbd_fixed_new_option_reply_info_block_size {
  uint16_t info;                /* NBD_INFO_BLOCK_SIZE */
  uint32_t minimum;             /* minimum block size */
  uint32_t preferred;           /* preferred block size */
  uint32_t maximum;             /* maximum block size */
} NBD_ATTRIBUTE_PACKED;

/* NBD_REP_SERVER reply (follows fixed_new_option_reply). */
struct nbd_fixed_new_option_reply_server {
  uint32_t export_name_len;     /* length of export name */
  /* followed by a string export name and description */
} NBD_ATTRIBUTE_PACKED;

/* NBD_REP_META_CONTEXT reply (follows fixed_new_option_reply). */
struct nbd_fixed_new_option_reply_meta_context {
  uint32_t context_id;          /* metadata context ID */
  /* followed by a string */
} NBD_ATTRIBUTE_PACKED;

/* Compact request (client -> server). */
struct nbd_request {
  uint32_t magic;               /* NBD_REQUEST_MAGIC. */
  uint16_t flags;               /* Request flags: NBD_CMD_FLAG_*. */
  uint16_t type;                /* Request type: NBD_CMD_*. */
  uint64_t cookie;              /* Opaque handle. */
  uint64_t offset;              /* Request offset. */
  uint32_t count;               /* Request length. */
} NBD_ATTRIBUTE_PACKED;

/* Extended request (client -> server). */
struct nbd_request_ext {
  uint32_t magic;               /* NBD_EXTENDED_REQUEST_MAGIC. */
  uint16_t flags;               /* Request flags: NBD_CMD_FLAG_*. */
  uint16_t type;                /* Request type: NBD_CMD_*. */
  uint64_t cookie;              /* Opaque handle. */
  uint64_t offset;              /* Request offset. */
  uint64_t count;               /* Request effect or payload length. */
} NBD_ATTRIBUTE_PACKED;

/* Extended request payload for NBD_CMD_BLOCK_STATUS, when supported. */
struct nbd_block_status_payload {
  uint64_t length;              /* Effective length of client request */
  /* followed by array of uint32_t ids */
} NBD_ATTRIBUTE_PACKED;

/* Simple reply (server -> client). */
struct nbd_simple_reply {
  uint32_t magic;               /* NBD_SIMPLE_REPLY_MAGIC. */
  uint32_t error;               /* NBD_SUCCESS or one of NBD_E*. */
  uint64_t cookie;              /* Opaque handle. */
} NBD_ATTRIBUTE_PACKED;

/* Structured reply (server -> client). */
struct nbd_structured_reply {
  uint32_t magic;               /* NBD_STRUCTURED_REPLY_MAGIC. */
  uint16_t flags;               /* NBD_REPLY_FLAG_* */
  uint16_t type;                /* NBD_REPLY_TYPE_* */
  uint64_t cookie;              /* Opaque handle. */
  uint32_t length;              /* Length of following nbd_chunk_* payload. */
} NBD_ATTRIBUTE_PACKED;

/* Extended reply (server -> client). */
struct nbd_extended_reply {
  uint32_t magic;               /* NBD_EXTENDED_REPLY_MAGIC. */
  uint16_t flags;               /* NBD_REPLY_FLAG_* */
  uint16_t type;                /* NBD_REPLY_TYPE_* */
  uint64_t cookie;              /* Opaque handle. */
  uint64_t offset;              /* Client's offset. */
  uint64_t length;              /* Length of following nbd_chunk_* payload. */
} NBD_ATTRIBUTE_PACKED;

struct nbd_chunk_offset_data {
  uint64_t offset;              /* offset */
  /* Followed by data. */
} NBD_ATTRIBUTE_PACKED;

struct nbd_chunk_offset_hole {
  uint64_t offset;
  uint32_t length;              /* Length of hole. */
} NBD_ATTRIBUTE_PACKED;

struct nbd_chunk_block_status_32 {
  uint32_t context_id;          /* metadata context ID */
  /* followed by array of nbd_block_descriptor_32 extents */
} NBD_ATTRIBUTE_PACKED;

struct nbd_block_descriptor_32 {
  uint32_t length;              /* length of block */
  uint32_t status_flags;        /* block type (hole etc) */
} NBD_ATTRIBUTE_PACKED;

struct nbd_chunk_block_status_64 {
  uint32_t context_id;          /* metadata context ID */
  uint32_t count;               /* non-zero descriptor count */
  /* followed by nbd_block_descriptor_64[count] extents */
} NBD_ATTRIBUTE_PACKED;

struct nbd_block_descriptor_64 {
  uint64_t length;              /* length of block */
  uint64_t status_flags;        /* block type (hole etc) */
} NBD_ATTRIBUTE_PACKED;

struct nbd_chunk_error {
  uint32_t error;               /* NBD_E* error number */
  uint16_t len;                 /* Length of human readable error. */
  /* Followed by human readable error string, and possibly more structure. */
} NBD_ATTRIBUTE_PACKED;

#define NBD_REQUEST_MAGIC           0x25609513
#define NBD_EXTENDED_REQUEST_MAGIC  0x21e41c71
#define NBD_SIMPLE_REPLY_MAGIC      0x67446698
#define NBD_STRUCTURED_REPLY_MAGIC  0x668e33ef
#define NBD_EXTENDED_REPLY_MAGIC    0x6e8a278c

/* Structured reply flags. */
#define NBD_REPLY_FLAG_DONE         (1U << 0)

#define NBD_REPLY_TYPE_ERR(val) ((1U<<15) | (val))
#define NBD_REPLY_TYPE_IS_ERR(val) (!!((val) & (1U<<15)))

/* Structured reply types. */
#define NBD_REPLY_TYPE_NONE             0
#define NBD_REPLY_TYPE_OFFSET_DATA      1
#define NBD_REPLY_TYPE_OFFSET_HOLE      2
#define NBD_REPLY_TYPE_BLOCK_STATUS     5
#define NBD_REPLY_TYPE_BLOCK_STATUS_EXT 6
#define NBD_REPLY_TYPE_ERROR            NBD_REPLY_TYPE_ERR (1)
#define NBD_REPLY_TYPE_ERROR_OFFSET     NBD_REPLY_TYPE_ERR (2)

/* NBD commands. */
#define NBD_CMD_READ              0
#define NBD_CMD_WRITE             1
#define NBD_CMD_DISC              2 /* Disconnect. */
#define NBD_CMD_FLUSH             3
#define NBD_CMD_TRIM              4
#define NBD_CMD_CACHE             5
#define NBD_CMD_WRITE_ZEROES      6
#define NBD_CMD_BLOCK_STATUS      7

#define NBD_CMD_FLAG_FUA          (1U << 0)
#define NBD_CMD_FLAG_NO_HOLE      (1U << 1)
#define NBD_CMD_FLAG_DF           (1U << 2)
#define NBD_CMD_FLAG_REQ_ONE      (1U << 3)
#define NBD_CMD_FLAG_FAST_ZERO    (1U << 4)
#define NBD_CMD_FLAG_PAYLOAD_LEN  (1U << 5)

/* NBD error codes. */
#define NBD_SUCCESS     0
#define NBD_EPERM       1
#define NBD_EIO         5
#define NBD_ENOMEM     12
#define NBD_EINVAL     22
#define NBD_ENOSPC     28
#define NBD_EOVERFLOW  75
#define NBD_ENOTSUP    95
#define NBD_ESHUTDOWN 108

#endif /* NBD_PROTOCOL_H */