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