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
use crate::*;

/// This file defines the types directly or indirectly involving union,
/// in that BindGen cannot handle union very well, so mannually define them.

/// Struct types involve union in <infiniband/verbs.h>

// ibv_gid related union and struct types
#[repr(C)]
#[derive(Clone, Copy)]
pub struct ibv_gid_global_t {
    pub subnet_prefix: __be64,
    pub interface_id: __be64,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub union ibv_gid {
    pub raw: [u8; 16],
    pub global: ibv_gid_global_t,
}

// ibv_async_event related union and struct type
#[repr(C)]
pub union ibv_async_event_element_t {
    pub cq: *mut ibv_cq,
    pub qp: *mut ibv_qp,
    pub srq: *mut ibv_srq,
    pub wq: *mut ibv_wq,
    pub port_num: c_int,
}

#[repr(C)]
pub struct ibv_async_event {
    pub element: ibv_async_event_element_t,
    pub event_type: ibv_event_type::Type,
}

// ibv_wc related union and struct types
#[repr(C)]
pub union imm_data_invalidated_rkey_union_t {
    /// When (wc_flags & IBV_WC_WITH_IMM): Immediate data in network byte order.
    pub imm_data: __be32,
    /// When (wc_flags & IBV_WC_WITH_INV): Stores the invalidated rkey.
    pub invalidated_rkey: u32,
}

#[repr(C)]
pub struct ibv_wc {
    pub wr_id: u64,
    pub status: ibv_wc_status::Type,
    pub opcode: ibv_wc_opcode::Type,
    pub vendor_err: u32,
    pub byte_len: u32,
    pub imm_data_invalidated_rkey_union: imm_data_invalidated_rkey_union_t,
    pub qp_num: u32,
    pub src_qp: u32,
    pub wc_flags: c_uint,
    pub pkey_index: u16,
    pub slid: u16,
    pub sl: u8,
    pub dlid_path_bits: u8,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct ibv_global_route {
    pub dgid: ibv_gid,
    pub flow_label: u32,
    pub sgid_index: u8,
    pub hop_limit: u8,
    pub traffic_class: u8,
}

// ibv_send_wr related union and struct types
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ibv_mw_bind_info {
    pub mr: *mut ibv_mr,
    pub addr: u64,
    pub length: u64,
    pub mw_access_flags: ::std::os::raw::c_uint,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct rdma_t {
    pub remote_addr: u64,
    pub rkey: u32,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct atomic_t {
    pub remote_addr: u64,
    pub compare_add: u64,
    pub swap: u64,
    pub rkey: u32,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct ud_t {
    pub ah: *mut ibv_ah,
    pub remote_qpn: u32,
    pub remote_qkey: u32,
}

#[repr(C)]
pub union wr_t {
    pub rdma: rdma_t,
    pub atomic: atomic_t,
    pub ud: ud_t,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct xrc_t {
    pub remote_srqn: u32,
}

#[repr(C)]
pub union qp_type_t {
    pub xrc: xrc_t,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct bind_mw_t {
    pub mw: *mut ibv_mw,
    pub rkey: u32,
    pub bind_info: ibv_mw_bind_info,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct tso_t {
    pub hdr: *mut c_void,
    pub hdr_sz: u16,
    pub mss: u16,
}

#[repr(C)]
pub union bind_mw_tso_union_t {
    pub bind_mw: bind_mw_t,
    pub tso: tso_t,
}

#[repr(C)]
pub struct ibv_send_wr {
    pub wr_id: u64,
    pub next: *mut Self,
    pub sg_list: *mut ibv_sge,
    pub num_sge: c_int,
    pub opcode: ibv_wr_opcode::Type,
    pub send_flags: c_uint,
    /// When opcode is *_WITH_IMM: Immediate data in network byte order.
    /// When opcode is *_INV: Stores the rkey to invalidate
    pub imm_data_invalidated_rkey_union: imm_data_invalidated_rkey_union_t,
    pub wr: wr_t,
    pub qp_type: qp_type_t,
    pub bind_mw_tso_union: bind_mw_tso_union_t,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct add_t {
    pub recv_wr_id: u64,
    pub sg_list: *mut ibv_sge,
    pub num_sge: c_int,
    pub tag: u64,
    pub mask: u64,
}

#[repr(C)]
#[derive(Copy, Clone)]
pub struct tm_t {
    pub unexpected_cnt: u32,
    pub handle: u32,
    pub add: add_t,
}

#[repr(C)]
pub struct ibv_ops_wr {
    wr_id: u64,
    next: *mut Self,
    opcode: ibv_ops_wr_opcode::Type,
    flags: c_int,
    tm: tm_t,
}

// ibv_flow_spec related union and struct types
#[repr(C)]
#[derive(Clone, Copy)]
pub struct hdr_t {
    pub type_: ibv_flow_spec_type::Type,
    pub size: u16,
}

#[repr(C)]
pub union ibv_flow_spec_union_t {
    pub hdr: hdr_t,
    pub eth: ibv_flow_spec_eth,
    pub ipv4: ibv_flow_spec_ipv4,
    pub tcp_udp: ibv_flow_spec_tcp_udp,
    pub ipv4_ext: ibv_flow_spec_ipv4_ext,
    pub ipv6: ibv_flow_spec_ipv6,
    pub esp: ibv_flow_spec_esp,
    pub tunnel: ibv_flow_spec_tunnel,
    pub gre: ibv_flow_spec_gre,
    pub mpls: ibv_flow_spec_mpls,
    pub flow_tag: ibv_flow_spec_action_tag,
    pub drop: ibv_flow_spec_action_drop,
    pub handle: ibv_flow_spec_action_handle,
    pub flow_count: ibv_flow_spec_counter_action,
}

#[repr(C)]
pub struct ibv_flow_spec {
    pub ibv_flow_spec_union: ibv_flow_spec_union_t,
}

/// Struct types involve union in <rdma/rdma_cma.h>

// rdma_addr related union and struct types
#[repr(C)]
#[derive(Clone, Copy)]
pub struct rdma_ib_addr {
    pub sgid: ibv_gid,
    pub dgid: ibv_gid,
    pub pkey: __be16,
}

#[repr(C)]
pub union src_addr_union_t {
    pub src_addr: libc::sockaddr,
    pub src_sin: libc::sockaddr_in,
    pub src_sin6: libc::sockaddr_in6,
    pub src_storage: libc::sockaddr_storage,
}

#[repr(C)]
pub union dst_addr_union_t {
    pub dst_addr: libc::sockaddr,
    pub dst_sin: libc::sockaddr_in,
    pub dst_sin6: libc::sockaddr_in6,
    pub dst_storage: libc::sockaddr_storage,
}

#[repr(C)]
pub union addr_union_t {
    pub ibaddr: rdma_ib_addr,
}

#[repr(C)]
pub struct rdma_addr {
    pub src_addr_union: src_addr_union_t,
    pub dst_addr_union: dst_addr_union_t,
    pub addr: addr_union_t,
}

/// rdma_cm_event related union and struct types

#[repr(C)]
#[derive(Clone, Copy)]
pub struct ibv_ah_attr {
    pub grh: ibv_global_route,
    pub dlid: u16,
    pub sl: u8,
    pub src_path_bits: u8,
    pub static_rate: u8,
    pub is_global: u8,
    pub port_num: u8,
}

#[repr(C)]
#[derive(Clone, Copy)]
pub struct rdma_ud_param {
    pub private_data: *const ::std::os::raw::c_void,
    pub private_data_len: u8,
    pub ah_attr: ibv_ah_attr,
    pub qp_num: u32,
    pub qkey: u32,
}

#[repr(C)]
pub union param_t {
    pub conn: rdma_conn_param,
    pub ud: rdma_ud_param,
}

#[repr(C)]
pub struct rdma_cm_event {
    pub id: *mut rdma_cm_id,
    pub listen_id: *mut rdma_cm_id,
    pub event: rdma_cm_event_type::Type,
    pub status: c_int,
    pub param: param_t,
}