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 */
|