1 /* nbdkit 2 * Copyright (C) 2013-2020 Red Hat Inc. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 11 * * Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * * Neither the name of Red Hat nor the names of its contributors may be 16 * used to endorse or promote products derived from this software without 17 * specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef NBD_PROTOCOL_H 34 #define NBD_PROTOCOL_H 35 36 #include <stdint.h> 37 38 /* Note that all NBD fields are sent on the wire in network byte 39 * order, so you must use beXXtoh or htobeXX when reading or writing 40 * these structures. 41 */ 42 43 #if defined(__GNUC__) || defined(__clang__) 44 #define NBD_ATTRIBUTE_PACKED __attribute__((__packed__)) 45 #else 46 #error "Please port to your compiler's notion of a packed struct" 47 #endif 48 49 #define NBD_MAX_STRING 4096 /* Maximum length of a string field */ 50 51 /* Old-style handshake. */ 52 struct nbd_old_handshake { 53 uint64_t nbdmagic; /* NBD_MAGIC */ 54 uint64_t version; /* NBD_OLD_VERSION */ 55 uint64_t exportsize; 56 uint16_t gflags; /* global flags */ 57 uint16_t eflags; /* per-export flags */ 58 char zeroes[124]; /* must be sent as zero bytes */ 59 } NBD_ATTRIBUTE_PACKED; 60 61 #define NBD_MAGIC UINT64_C(0x4e42444d41474943) /* ASCII "NBDMAGIC" */ 62 #define NBD_OLD_VERSION UINT64_C(0x0000420281861253) 63 64 /* New-style handshake. */ 65 struct nbd_new_handshake { 66 uint64_t nbdmagic; /* NBD_MAGIC */ 67 uint64_t version; /* NBD_NEW_VERSION */ 68 uint16_t gflags; /* global flags */ 69 } NBD_ATTRIBUTE_PACKED; 70 71 #define NBD_NEW_VERSION UINT64_C(0x49484156454F5054) /* ASCII "IHAVEOPT" */ 72 73 /* New-style handshake option (sent by the client to us). */ 74 struct nbd_new_option { 75 uint64_t version; /* NBD_NEW_VERSION */ 76 uint32_t option; /* NBD_OPT_* */ 77 uint32_t optlen; /* option data length */ 78 /* option data follows */ 79 } NBD_ATTRIBUTE_PACKED; 80 81 /* Newstyle handshake OPT_EXPORT_NAME reply message. 82 * Modern clients use NBD_OPT_GO instead of this. 83 */ 84 struct nbd_export_name_option_reply { 85 uint64_t exportsize; /* size of export */ 86 uint16_t eflags; /* per-export flags */ 87 char zeroes[124]; /* optional zeroes, unless NBD_FLAG_NO_ZEROES */ 88 } NBD_ATTRIBUTE_PACKED; 89 90 /* Fixed newstyle handshake reply message. */ 91 struct nbd_fixed_new_option_reply { 92 uint64_t magic; /* NBD_REP_MAGIC */ 93 uint32_t option; /* option we are replying to */ 94 uint32_t reply; /* NBD_REP_* */ 95 uint32_t replylen; 96 } NBD_ATTRIBUTE_PACKED; 97 98 #define NBD_REP_MAGIC UINT64_C(0x3e889045565a9) 99 100 /* Global flags. */ 101 #define NBD_FLAG_FIXED_NEWSTYLE (1 << 0) 102 #define NBD_FLAG_NO_ZEROES (1 << 1) 103 104 /* Per-export flags. */ 105 #define NBD_FLAG_HAS_FLAGS (1 << 0) 106 #define NBD_FLAG_READ_ONLY (1 << 1) 107 #define NBD_FLAG_SEND_FLUSH (1 << 2) 108 #define NBD_FLAG_SEND_FUA (1 << 3) 109 #define NBD_FLAG_ROTATIONAL (1 << 4) 110 #define NBD_FLAG_SEND_TRIM (1 << 5) 111 #define NBD_FLAG_SEND_WRITE_ZEROES (1 << 6) 112 #define NBD_FLAG_SEND_DF (1 << 7) 113 #define NBD_FLAG_CAN_MULTI_CONN (1 << 8) 114 #define NBD_FLAG_SEND_CACHE (1 << 10) 115 #define NBD_FLAG_SEND_FAST_ZERO (1 << 11) 116 117 /* NBD options (new style handshake only). */ 118 #define NBD_OPT_EXPORT_NAME 1 119 #define NBD_OPT_ABORT 2 120 #define NBD_OPT_LIST 3 121 #define NBD_OPT_STARTTLS 5 122 #define NBD_OPT_INFO 6 123 #define NBD_OPT_GO 7 124 #define NBD_OPT_STRUCTURED_REPLY 8 125 #define NBD_OPT_LIST_META_CONTEXT 9 126 #define NBD_OPT_SET_META_CONTEXT 10 127 128 #define NBD_REP_ERR(val) (0x80000000 | (val)) 129 #define NBD_REP_IS_ERR(val) (!!((val) & 0x80000000)) 130 131 #define NBD_REP_ACK 1 132 #define NBD_REP_SERVER 2 133 #define NBD_REP_INFO 3 134 #define NBD_REP_META_CONTEXT 4 135 #define NBD_REP_ERR_UNSUP NBD_REP_ERR (1) 136 #define NBD_REP_ERR_POLICY NBD_REP_ERR (2) 137 #define NBD_REP_ERR_INVALID NBD_REP_ERR (3) 138 #define NBD_REP_ERR_PLATFORM NBD_REP_ERR (4) 139 #define NBD_REP_ERR_TLS_REQD NBD_REP_ERR (5) 140 #define NBD_REP_ERR_UNKNOWN NBD_REP_ERR (6) 141 #define NBD_REP_ERR_SHUTDOWN NBD_REP_ERR (7) 142 #define NBD_REP_ERR_BLOCK_SIZE_REQD NBD_REP_ERR (8) 143 #define NBD_REP_ERR_TOO_BIG NBD_REP_ERR (9) 144 145 #define NBD_INFO_EXPORT 0 146 #define NBD_INFO_NAME 1 147 #define NBD_INFO_DESCRIPTION 2 148 #define NBD_INFO_BLOCK_SIZE 3 149 150 /* NBD_INFO_EXPORT reply (follows fixed_new_option_reply). */ 151 struct nbd_fixed_new_option_reply_info_export { 152 uint16_t info; /* NBD_INFO_EXPORT */ 153 uint64_t exportsize; /* size of export */ 154 uint16_t eflags; /* per-export flags */ 155 } NBD_ATTRIBUTE_PACKED; 156 157 /* NBD_REP_META_CONTEXT reply (follows fixed_new_option_reply). */ 158 struct nbd_fixed_new_option_reply_meta_context { 159 uint32_t context_id; /* metadata context ID */ 160 /* followed by a string */ 161 } NBD_ATTRIBUTE_PACKED; 162 163 /* NBD_REPLY_TYPE_BLOCK_STATUS block descriptor. */ 164 struct nbd_block_descriptor { 165 uint32_t length; /* length of block */ 166 uint32_t status_flags; /* block type (hole etc) */ 167 } NBD_ATTRIBUTE_PACKED; 168 169 /* Request (client -> server). */ 170 struct nbd_request { 171 uint32_t magic; /* NBD_REQUEST_MAGIC. */ 172 uint16_t flags; /* Request flags. */ 173 uint16_t type; /* Request type. */ 174 uint64_t handle; /* Opaque handle. */ 175 uint64_t offset; /* Request offset. */ 176 uint32_t count; /* Request length. */ 177 } NBD_ATTRIBUTE_PACKED; 178 179 /* Simple reply (server -> client). */ 180 struct nbd_simple_reply { 181 uint32_t magic; /* NBD_SIMPLE_REPLY_MAGIC. */ 182 uint32_t error; /* NBD_SUCCESS or one of NBD_E*. */ 183 uint64_t handle; /* Opaque handle. */ 184 } NBD_ATTRIBUTE_PACKED; 185 186 /* Structured reply (server -> client). */ 187 struct nbd_structured_reply { 188 uint32_t magic; /* NBD_STRUCTURED_REPLY_MAGIC. */ 189 uint16_t flags; /* NBD_REPLY_FLAG_* */ 190 uint16_t type; /* NBD_REPLY_TYPE_* */ 191 uint64_t handle; /* Opaque handle. */ 192 uint32_t length; /* Length of payload which follows. */ 193 } NBD_ATTRIBUTE_PACKED; 194 195 struct nbd_structured_reply_offset_data { 196 uint64_t offset; /* offset */ 197 /* Followed by data. */ 198 } NBD_ATTRIBUTE_PACKED; 199 200 struct nbd_structured_reply_offset_hole { 201 uint64_t offset; 202 uint32_t length; /* Length of hole. */ 203 } NBD_ATTRIBUTE_PACKED; 204 205 struct nbd_structured_reply_error { 206 uint32_t error; /* NBD_E* error number */ 207 uint16_t len; /* Length of human readable error. */ 208 /* Followed by human readable error string, and possibly more structure. */ 209 } NBD_ATTRIBUTE_PACKED; 210 211 #define NBD_REQUEST_MAGIC 0x25609513 212 #define NBD_SIMPLE_REPLY_MAGIC 0x67446698 213 #define NBD_STRUCTURED_REPLY_MAGIC 0x668e33ef 214 215 /* Structured reply flags. */ 216 #define NBD_REPLY_FLAG_DONE (1<<0) 217 218 #define NBD_REPLY_TYPE_ERR(val) ((1<<15) | (val)) 219 #define NBD_REPLY_TYPE_IS_ERR(val) (!!((val) & (1<<15))) 220 221 /* Structured reply types. */ 222 #define NBD_REPLY_TYPE_NONE 0 223 #define NBD_REPLY_TYPE_OFFSET_DATA 1 224 #define NBD_REPLY_TYPE_OFFSET_HOLE 2 225 #define NBD_REPLY_TYPE_BLOCK_STATUS 5 226 #define NBD_REPLY_TYPE_ERROR NBD_REPLY_TYPE_ERR (1) 227 #define NBD_REPLY_TYPE_ERROR_OFFSET NBD_REPLY_TYPE_ERR (2) 228 229 /* NBD commands. */ 230 #define NBD_CMD_READ 0 231 #define NBD_CMD_WRITE 1 232 #define NBD_CMD_DISC 2 /* Disconnect. */ 233 #define NBD_CMD_FLUSH 3 234 #define NBD_CMD_TRIM 4 235 #define NBD_CMD_CACHE 5 236 #define NBD_CMD_WRITE_ZEROES 6 237 #define NBD_CMD_BLOCK_STATUS 7 238 239 #define NBD_CMD_FLAG_FUA (1<<0) 240 #define NBD_CMD_FLAG_NO_HOLE (1<<1) 241 #define NBD_CMD_FLAG_DF (1<<2) 242 #define NBD_CMD_FLAG_REQ_ONE (1<<3) 243 #define NBD_CMD_FLAG_FAST_ZERO (1<<4) 244 245 /* NBD error codes. */ 246 #define NBD_SUCCESS 0 247 #define NBD_EPERM 1 248 #define NBD_EIO 5 249 #define NBD_ENOMEM 12 250 #define NBD_EINVAL 22 251 #define NBD_ENOSPC 28 252 #define NBD_EOVERFLOW 75 253 #define NBD_ENOTSUP 95 254 #define NBD_ESHUTDOWN 108 255 256 #endif /* NBD_PROTOCOL_H */ 257