1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
4 * Use is subject to license terms.
6 * Copyright (c) 2012, 2017, Intel Corporation.
9 /* This file is part of Lustre, http://www.lustre.org/ */
11 #ifndef __UAPI_LNET_IDL_H__
12 #define __UAPI_LNET_IDL_H__
14 #include <linux/types.h>
16 /************************************************************************
17 * Core LNet wire message format.
18 * These are sent in sender's byte order (i.e. receiver flips).
21 /** Address of an end-point in an LNet network.
23 * A node can have multiple end-points and hence multiple addresses.
24 * An LNet network can be a simple network (e.g. tcp0) or a network of
25 * LNet networks connected by LNet routers. Therefore an end-point address
26 * has two parts: network ID, and address within a network.
27 * The most-significant-byte in this format is always 0. A larger value
28 * would imply a larger nid with a larger address.
30 * \see LNET_NIDNET, LNET_NIDADDR, and LNET_MKNID.
32 typedef __u64 lnet_nid_t;
35 * Address of LNet end-point in extended form
37 * To support addresses larger than 32bits we have
38 * an extended nid which supports up to 128 bits
39 * of address and is extensible.
40 * If nid_size is 0, then the nid can be stored in an lnet_nid_t,
41 * and the first 8 bytes of the 'struct lnet_nid' are identical to
42 * the lnet_nid_t in big-endian format.
43 * If nid_type == 0xff, then all other fields should be ignored
44 * and this is an ANY wildcard address. In particular, the nid_size
45 * can be 0xff without making the address too big to fit.
48 __u8 nid_size; /* total bytes - 8 */
52 } __attribute__((packed));
54 #define NID_BYTES(nid) ((nid)->nid_size + 8)
55 #define NID_ADDR_BYTES(nid) ((nid)->nid_size + 4)
58 * ID of a process in a node. Shortened as PID to distinguish from
59 * lnet_process_id, the global process ID.
61 typedef __u32 lnet_pid_t;
63 /* Packed version of struct lnet_process_id to transfer via network */
64 struct lnet_process_id_packed {
66 lnet_pid_t pid; /* node id / process id */
67 } __attribute__((packed));
69 /* The wire handle's interface cookie only matches one network interface in
70 * one epoch (i.e. new cookie when the interface restarts or the node
71 * reboots). The object cookie only matches one object on that interface
72 * during that object's lifetime (i.e. no cookie re-use).
74 struct lnet_handle_wire {
75 __u64 wh_interface_cookie;
76 __u64 wh_object_cookie;
77 } __attribute__((packed));
87 /* The variant fields of the portals message header are aligned on an 8
88 * byte boundary in the message header. Note that all types used in these
89 * wire structs MUST be fixed size and the smaller types are placed at the
93 struct lnet_handle_wire dst_wmd;
96 } __attribute__((packed));
99 struct lnet_handle_wire ack_wmd;
104 } __attribute__((packed));
107 struct lnet_handle_wire return_wmd;
112 } __attribute__((packed));
115 struct lnet_handle_wire dst_wmd;
116 } __attribute__((packed));
121 } __attribute__((packed));
127 struct lnet_reply reply;
128 struct lnet_hello hello;
129 } __attribute__((packed));
131 /* This is used for message headers that lnet code is manipulating.
132 * All fields before the union are in host-byte-order.
135 struct lnet_nid dest_nid;
136 struct lnet_nid src_nid;
139 __u32 type; /* enum lnet_msg_type */
140 __u32 payload_length; /* payload data to follow */
141 /*<------__u64 aligned------->*/
142 union lnet_cmd_hdr msg;
143 } __attribute__((packed));
145 /* This is used to support conversion between an lnet_hdr and
146 * the content of a network message.
148 struct _lnet_hdr_nid4 {
153 __u32 type; /* enum lnet_msg_type */
154 __u32 payload_length; /* payload data to follow */
155 /*<------__u64 aligned------->*/
156 union lnet_cmd_hdr msg;
157 } __attribute__((packed));
159 /* This is stored in a network message buffer. Content cannot be accessed
160 * without converting to an lnet_hdr.
162 struct lnet_hdr_nid4 {
163 char _bytes[sizeof(struct _lnet_hdr_nid4)];
164 } __attribute__((packed));
166 /* A HELLO message contains a magic number and protocol version
167 * code in the header's dest_nid, the peer's NID in the src_nid, and
168 * LNET_MSG_HELLO in the type field. All other common fields are zero
169 * (including payload_size; i.e. no payload).
170 * This is for use by byte-stream LNDs (e.g. TCP/IP) to check the peer is
171 * running the same protocol and to find out its NID. These LNDs should
172 * exchange HELLO messages when a connection is first established. Individual
173 * LNDs can put whatever else they fancy in lnet_hdr::msg.
175 struct lnet_magicversion {
176 __u32 magic; /* LNET_PROTO_TCP_MAGIC */
177 __u16 version_major; /* increment on incompatible change */
178 __u16 version_minor; /* increment on compatible change */
179 } __attribute__((packed));
181 /* PROTO MAGIC for LNDs */
182 #define LNET_PROTO_IB_MAGIC 0x0be91b91
183 #define LNET_PROTO_GNI_MAGIC 0xb00fbabe /* ask Kim */
184 #define LNET_PROTO_TCP_MAGIC 0xeebc0ded
185 #define LNET_PROTO_KFI_MAGIC 0xdeadbeef
186 #define LNET_PROTO_ACCEPTOR_MAGIC 0xacce7100
187 #define LNET_PROTO_PING_MAGIC 0x70696E67 /* 'ping' */
189 /* Placeholder for a future "unified" protocol across all LNDs */
190 /* Current LNDs that receive a request with this magic will respond
191 * with a "stub" reply using their current protocol */
192 #define LNET_PROTO_MAGIC 0x45726963 /* ! */
194 #define LNET_PROTO_TCP_VERSION_MAJOR 1
195 #define LNET_PROTO_TCP_VERSION_MINOR 0
197 /* Acceptor connection request */
198 struct lnet_acceptor_connreq {
199 __u32 acr_magic; /* LNET_PROTO_ACCEPTOR_MAGIC */
200 __u32 acr_version; /* protocol version */
201 __u64 acr_nid; /* target NID */
202 } __attribute__((packed));
204 #define LNET_PROTO_ACCEPTOR_VERSION 1
206 struct lnet_acceptor_connreq_v2 {
207 __u32 acr_magic; /* LNET_PROTO_ACCEPTOR_MAGIC */
208 __u32 acr_version; /* protocol version - 2 */
209 struct lnet_nid acr_nid; /* target NID */
210 } __attribute__((packed));
212 /* For use with 16-byte addresses */
213 #define LNET_PROTO_ACCEPTOR_VERSION_16 2
215 struct lnet_counters_common {
216 __u32 lcc_msgs_alloc;
219 __u32 lcc_send_count;
220 __u32 lcc_recv_count;
221 __u32 lcc_route_count;
222 __u32 lcc_drop_count;
223 __u64 lcc_send_length;
224 __u64 lcc_recv_length;
225 __u64 lcc_route_length;
226 __u64 lcc_drop_length;
227 } __attribute__((packed));
229 #define LNET_NI_STATUS_UP 0x15aac0de
230 #define LNET_NI_STATUS_DOWN 0xdeadface
231 #define LNET_NI_STATUS_INVALID 0x00000000
233 struct lnet_ni_status {
236 __u32 ns_msg_size; /* represents ping buffer size if message
237 * contains large NID addresses.
239 } __attribute__((packed));
241 /* When this appears in lnet_ping_info, it will be large
242 * enough to hold whatever nid is present, rounded up
243 * to a multiple of 4 bytes.
244 * NOTE: all users MUST check ns_nid.nid_size is usable.
246 struct lnet_ni_large_status {
248 struct lnet_nid ns_nid;
249 } __attribute__((packed));
251 /* NB: value of these features equal to LNET_PROTO_PING_VERSION_x
252 * of old LNet, so there shouldn't be any compatibility issue
254 #define LNET_PING_FEAT_INVAL (0) /* no feature */
255 #define LNET_PING_FEAT_BASE (1 << 0) /* just a ping */
256 #define LNET_PING_FEAT_NI_STATUS (1 << 1) /* return NI status */
257 #define LNET_PING_FEAT_RTE_DISABLED (1 << 2) /* Routing enabled */
258 #define LNET_PING_FEAT_MULTI_RAIL (1 << 3) /* Multi-Rail aware */
259 #define LNET_PING_FEAT_DISCOVERY (1 << 4) /* Supports Discovery */
260 #define LNET_PING_FEAT_LARGE_ADDR (1 << 5) /* Large addr nids present */
261 #define LNET_PING_FEAT_PRIMARY_LARGE (1 << 6) /* Primary is first Large addr */
264 * All ping feature bits fit to hit the wire.
265 * In lnet_assert_wire_constants() this is compared against its open-coded
266 * value, and in lnet_ping_target_update() it is used to verify that no
267 * unknown bits have been set.
268 * New feature bits can be added, just be aware that this does change the
269 * over-the-wire protocol.
271 #define LNET_PING_FEAT_BITS (LNET_PING_FEAT_BASE | \
272 LNET_PING_FEAT_NI_STATUS | \
273 LNET_PING_FEAT_RTE_DISABLED | \
274 LNET_PING_FEAT_MULTI_RAIL | \
275 LNET_PING_FEAT_DISCOVERY | \
276 LNET_PING_FEAT_LARGE_ADDR | \
277 LNET_PING_FEAT_PRIMARY_LARGE)
280 * The first address in pi_ni *must* be the loop-back nid: LNET_NID_LO_0
281 * The second address must be the primary nid for the host unless
282 * LNET_PING_FEAT_PRIMARY_LARGE is set, then the first large address
283 * is the preferred primary. However nodes that do not recognise that
284 * flag will quietly ignore it.
286 struct lnet_ping_info {
290 __u32 pi_nnis; /* number of nid4 entries */
291 struct lnet_ni_status pi_ni[];
292 } __attribute__((packed));
294 #define LNET_PING_INFO_HDR_SIZE \
295 offsetof(struct lnet_ping_info, pi_ni[0])
296 #define LNET_PING_INFO_MIN_SIZE \
297 offsetof(struct lnet_ping_info, pi_ni[LNET_INTERFACES_MIN])
298 #define LNET_PING_INFO_LONI(PINFO) ((PINFO)->pi_ni[0].ns_nid)
299 #define LNET_PING_INFO_SEQNO(PINFO) ((PINFO)->pi_ni[0].ns_status)
300 /* If LNET_PING_FEAT_LARGE_ADDR set, pi_nnis is the number of nid4 entries
301 * and pi_ni[0].ns_msg_size is the total number of bytes, including header and
302 * lnet_ni_large_status entries which follow the lnet_ni_status entries.
303 * This must be a multiple of 4.
305 #define lnet_ping_info_size(pinfo) \
306 (((pinfo)->pi_features & LNET_PING_FEAT_LARGE_ADDR) \
307 ? ((pinfo)->pi_ni[0].ns_msg_size & ~3) \
308 : offsetof(struct lnet_ping_info, pi_ni[(pinfo)->pi_nnis]))