Whamcloud - gitweb
LU-10391 lnet: allow ping packet to contain large nids
[fs/lustre-release.git] / lnet / include / uapi / linux / lnet / lnet-idl.h
1 /*
2  * GPL HEADER START
3  *
4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 only,
8  * as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License version 2 for more details (a copy is included
14  * in the LICENSE file that accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License
17  * version 2 along with this program; If not, see
18  * http://www.gnu.org/licenses/gpl-2.0.html
19  *
20  * GPL HEADER END
21  */
22 /*
23  * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24  * Use is subject to license terms.
25  *
26  * Copyright (c) 2012, 2017, Intel Corporation.
27  */
28 /*
29  * This file is part of Lustre, http://www.lustre.org/
30  */
31
32 #ifndef __UAPI_LNET_IDL_H__
33 #define __UAPI_LNET_IDL_H__
34
35 #include <linux/types.h>
36
37 /************************************************************************
38  * Core LNet wire message format.
39  * These are sent in sender's byte order (i.e. receiver flips).
40  */
41
42 /** Address of an end-point in an LNet network.
43  *
44  * A node can have multiple end-points and hence multiple addresses.
45  * An LNet network can be a simple network (e.g. tcp0) or a network of
46  * LNet networks connected by LNet routers. Therefore an end-point address
47  * has two parts: network ID, and address within a network.
48  * The most-significant-byte in this format is always 0.  A larger value
49  * would imply a larger nid with a larger address.
50  *
51  * \see LNET_NIDNET, LNET_NIDADDR, and LNET_MKNID.
52  */
53 typedef __u64 lnet_nid_t;
54
55 /*
56  * Address of LNet end-point in extended form
57  *
58  * To support addresses larger than 32bits we have
59  * an extended nid which supports up to 128 bits
60  * of address and is extensible.
61  * If nid_size is 0, then the nid can be stored in an lnet_nid_t,
62  * and the first 8 bytes of the 'struct lnet_nid' are identical to
63  * the lnet_nid_t in big-endian format.
64  * If nid_type == 0xff, then all other fields should be ignored
65  * and this is an ANY wildcard address.  In particular, the nid_size
66  * can be 0xff without making the address too big to fit.
67  */
68 struct lnet_nid {
69         __u8    nid_size;       /* total bytes - 8 */
70         __u8    nid_type;
71         __be16  nid_num;
72         __be32  nid_addr[4];
73 } __attribute__((packed));
74
75 #define NID_BYTES(nid)          ((nid)->nid_size + 8)
76 #define NID_ADDR_BYTES(nid)     ((nid)->nid_size + 4)
77
78 /**
79  * ID of a process in a node. Shortened as PID to distinguish from
80  * lnet_process_id, the global process ID.
81  */
82 typedef __u32 lnet_pid_t;
83
84 /* Packed version of struct lnet_process_id to transfer via network */
85 struct lnet_process_id_packed {
86         lnet_nid_t nid;
87         lnet_pid_t pid; /* node id / process id */
88 } __attribute__((packed));
89
90 /* The wire handle's interface cookie only matches one network interface in
91  * one epoch (i.e. new cookie when the interface restarts or the node
92  * reboots).  The object cookie only matches one object on that interface
93  * during that object's lifetime (i.e. no cookie re-use).
94  */
95 struct lnet_handle_wire {
96         __u64 wh_interface_cookie;
97         __u64 wh_object_cookie;
98 } __attribute__((packed));
99
100 enum lnet_msg_type {
101         LNET_MSG_ACK = 0,
102         LNET_MSG_PUT,
103         LNET_MSG_GET,
104         LNET_MSG_REPLY,
105         LNET_MSG_HELLO,
106 };
107
108 /* The variant fields of the portals message header are aligned on an 8
109  * byte boundary in the message header.  Note that all types used in these
110  * wire structs MUST be fixed size and the smaller types are placed at the
111  * end.
112  */
113 struct lnet_ack {
114         struct lnet_handle_wire dst_wmd;
115         __u64                   match_bits;
116         __u32                   mlength;
117 } __attribute__((packed));
118
119 struct lnet_put {
120         struct lnet_handle_wire ack_wmd;
121         __u64                   match_bits;
122         __u64                   hdr_data;
123         __u32                   ptl_index;
124         __u32                   offset;
125 } __attribute__((packed));
126
127 struct lnet_get {
128         struct lnet_handle_wire return_wmd;
129         __u64                   match_bits;
130         __u32                   ptl_index;
131         __u32                   src_offset;
132         __u32                   sink_length;
133 } __attribute__((packed));
134
135 struct lnet_reply {
136         struct lnet_handle_wire dst_wmd;
137 } __attribute__((packed));
138
139 struct lnet_hello {
140         __u64                   incarnation;
141         __u32                   type;
142 } __attribute__((packed));
143
144 union lnet_cmd_hdr {
145         struct lnet_ack         ack;
146         struct lnet_put         put;
147         struct lnet_get         get;
148         struct lnet_reply       reply;
149         struct lnet_hello       hello;
150 } __attribute__((packed));
151
152 /* This is used for message headers that lnet code is manipulating.
153  *  All fields before the union are in host-byte-order.
154  */
155 struct lnet_hdr {
156         struct lnet_nid         dest_nid;
157         struct lnet_nid         src_nid;
158         lnet_pid_t              dest_pid;
159         lnet_pid_t              src_pid;
160         __u32                   type;           /* enum lnet_msg_type */
161         __u32                   payload_length; /* payload data to follow */
162         /*<------__u64 aligned------->*/
163         union lnet_cmd_hdr      msg;
164 } __attribute__((packed));
165
166 /* This is used to support conversion between an lnet_hdr and
167  * the content of a network message.
168  */
169 struct _lnet_hdr_nid4 {
170         lnet_nid_t      dest_nid;
171         lnet_nid_t      src_nid;
172         lnet_pid_t      dest_pid;
173         lnet_pid_t      src_pid;
174         __u32           type;           /* enum lnet_msg_type */
175         __u32           payload_length; /* payload data to follow */
176         /*<------__u64 aligned------->*/
177         union lnet_cmd_hdr msg;
178 } __attribute__((packed));
179
180 /* This is stored in a network message buffer.  Content cannot be accessed
181  * without converting to an lnet_hdr.
182  */
183 struct lnet_hdr_nid4 {
184         char    _bytes[sizeof(struct _lnet_hdr_nid4)];
185 } __attribute__((packed));
186
187 /* A HELLO message contains a magic number and protocol version
188  * code in the header's dest_nid, the peer's NID in the src_nid, and
189  * LNET_MSG_HELLO in the type field.  All other common fields are zero
190  * (including payload_size; i.e. no payload).
191  * This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
192  * running the same protocol and to find out its NID. These LNDs should
193  * exchange HELLO messages when a connection is first established.  Individual
194  * LNDs can put whatever else they fancy in lnet_hdr::msg.
195  */
196 struct lnet_magicversion {
197         __u32   magic;          /* LNET_PROTO_TCP_MAGIC */
198         __u16   version_major;  /* increment on incompatible change */
199         __u16   version_minor;  /* increment on compatible change */
200 } __attribute__((packed));
201
202 /* PROTO MAGIC for LNDs */
203 #define LNET_PROTO_IB_MAGIC             0x0be91b91
204 #define LNET_PROTO_GNI_MAGIC            0xb00fbabe /* ask Kim */
205 #define LNET_PROTO_TCP_MAGIC            0xeebc0ded
206 #define LNET_PROTO_KFI_MAGIC            0xdeadbeef
207 #define LNET_PROTO_ACCEPTOR_MAGIC       0xacce7100
208 #define LNET_PROTO_PING_MAGIC           0x70696E67 /* 'ping' */
209
210 /* Placeholder for a future "unified" protocol across all LNDs */
211 /* Current LNDs that receive a request with this magic will respond
212  * with a "stub" reply using their current protocol */
213 #define LNET_PROTO_MAGIC                0x45726963 /* ! */
214
215 #define LNET_PROTO_TCP_VERSION_MAJOR    1
216 #define LNET_PROTO_TCP_VERSION_MINOR    0
217
218 /* Acceptor connection request */
219 struct lnet_acceptor_connreq {
220         __u32   acr_magic;      /* LNET_PROTO_ACCEPTOR_MAGIC */
221         __u32   acr_version;    /* protocol version */
222         __u64   acr_nid;        /* target NID */
223 } __attribute__((packed));
224
225 #define LNET_PROTO_ACCEPTOR_VERSION     1
226
227 struct lnet_acceptor_connreq_v2 {
228         __u32                   acr_magic;      /* LNET_PROTO_ACCEPTOR_MAGIC */
229         __u32                   acr_version;    /* protocol version - 2 */
230         struct lnet_nid         acr_nid;        /* target NID */
231 } __attribute__((packed));
232
233 /* For use with 16-byte addresses */
234 #define LNET_PROTO_ACCEPTOR_VERSION_16  2
235
236 struct lnet_counters_common {
237         __u32   lcc_msgs_alloc;
238         __u32   lcc_msgs_max;
239         __u32   lcc_errors;
240         __u32   lcc_send_count;
241         __u32   lcc_recv_count;
242         __u32   lcc_route_count;
243         __u32   lcc_drop_count;
244         __u64   lcc_send_length;
245         __u64   lcc_recv_length;
246         __u64   lcc_route_length;
247         __u64   lcc_drop_length;
248 } __attribute__((packed));
249
250 #define LNET_NI_STATUS_UP       0x15aac0de
251 #define LNET_NI_STATUS_DOWN     0xdeadface
252 #define LNET_NI_STATUS_INVALID  0x00000000
253
254 struct lnet_ni_status {
255         lnet_nid_t ns_nid;
256         __u32      ns_status;
257         __u32      ns_msg_size; /* represents ping buffer size if message
258                                  * contains large NID addresses.
259                                  */
260 } __attribute__((packed));
261
262 /* When this appears in lnet_ping_info, it will be large
263  * enough to hold whatever nid is present, rounded up
264  * to a multiple of 4 bytes.
265  * NOTE: all users MUST check ns_nid.nid_size is usable.
266  */
267 struct lnet_ni_large_status {
268         __u32           ns_status;
269         struct lnet_nid ns_nid;
270 } __attribute__((packed));
271
272 /* NB: value of these features equal to LNET_PROTO_PING_VERSION_x
273  * of old LNet, so there shouldn't be any compatibility issue
274  */
275 #define LNET_PING_FEAT_INVAL            (0)             /* no feature */
276 #define LNET_PING_FEAT_BASE             (1 << 0)        /* just a ping */
277 #define LNET_PING_FEAT_NI_STATUS        (1 << 1)        /* return NI status */
278 #define LNET_PING_FEAT_RTE_DISABLED     (1 << 2)        /* Routing enabled */
279 #define LNET_PING_FEAT_MULTI_RAIL       (1 << 3)        /* Multi-Rail aware */
280 #define LNET_PING_FEAT_DISCOVERY        (1 << 4)        /* Supports Discovery */
281 #define LNET_PING_FEAT_LARGE_ADDR       (1 << 5)        /* Large addr nids present */
282 #define LNET_PING_FEAT_PRIMARY_LARGE    (1 << 6)        /* Primary is first Large addr */
283
284 /*
285  * All ping feature bits fit to hit the wire.
286  * In lnet_assert_wire_constants() this is compared against its open-coded
287  * value, and in lnet_ping_target_update() it is used to verify that no
288  * unknown bits have been set.
289  * New feature bits can be added, just be aware that this does change the
290  * over-the-wire protocol.
291  */
292 #define LNET_PING_FEAT_BITS             (LNET_PING_FEAT_BASE |          \
293                                          LNET_PING_FEAT_NI_STATUS |     \
294                                          LNET_PING_FEAT_RTE_DISABLED |  \
295                                          LNET_PING_FEAT_MULTI_RAIL |    \
296                                          LNET_PING_FEAT_DISCOVERY |     \
297                                          LNET_PING_FEAT_LARGE_ADDR |    \
298                                          LNET_PING_FEAT_PRIMARY_LARGE)
299
300 /* NOTE:
301  * The first address in pi_ni *must* be the loop-back nid: LNET_NID_LO_0
302  * The second address must be the primary nid for the host unless
303  * LNET_PING_FEAT_PRIMARY_LARGE is set, then the first large address
304  * is the preferred primary.  However nodes that do not recognise that
305  * flag will quietly ignore it.
306  */
307 struct lnet_ping_info {
308         __u32                   pi_magic;
309         __u32                   pi_features;
310         lnet_pid_t              pi_pid;
311         __u32                   pi_nnis;        /* number of nid4 entries */
312         struct lnet_ni_status   pi_ni[0];
313 } __attribute__((packed));
314
315 #define LNET_PING_INFO_HDR_SIZE \
316         offsetof(struct lnet_ping_info, pi_ni[0])
317 #define LNET_PING_INFO_MIN_SIZE \
318         offsetof(struct lnet_ping_info, pi_ni[LNET_INTERFACES_MIN])
319 #define LNET_PING_INFO_LONI(PINFO)      ((PINFO)->pi_ni[0].ns_nid)
320 #define LNET_PING_INFO_SEQNO(PINFO)     ((PINFO)->pi_ni[0].ns_status)
321 /* If LNET_PING_FEAT_LARGE_ADDR set, pi_nnis is the number of nid4 entries
322  * and pi_ni[0].ns_msg_size is the total number of bytes, including header and
323  * lnet_ni_large_status entries which follow the lnet_ni_status entries.
324  * This must be a multiple of 4.
325  */
326 #define lnet_ping_info_size(pinfo)                              \
327         (((pinfo)->pi_features & LNET_PING_FEAT_LARGE_ADDR)     \
328         ? ((pinfo)->pi_ni[0].ns_msg_size & ~3)                  \
329         : offsetof(struct lnet_ping_info, pi_ni[(pinfo)->pi_nnis]))
330
331 #endif