1use anyhow::{Context, Result, bail};
16
17pub const STATUS_OK: u8 = 0;
19pub const STATUS_ERR: u8 = 1;
20pub const MODE_TCP: u8 = 0;
22pub const MODE_VERBS: u8 = 1;
25
26#[derive(Clone, Debug, PartialEq, Eq)]
31pub struct VerbsServerParams {
32 pub qpn: u32,
33 pub psn: u32,
34 pub gid: [u8; 16],
35 pub layers: Vec<(u64, u32)>,
38}
39
40#[derive(Clone, Copy, Debug, PartialEq, Eq)]
42pub struct VerbsClientParams {
43 pub qpn: u32,
44 pub psn: u32,
45 pub gid: [u8; 16],
46}
47
48#[derive(Clone, Copy, Debug, PartialEq, Eq)]
51pub struct CacheServerParams {
52 pub qpn: u32,
53 pub psn: u32,
54 pub gid: [u8; 16],
55 pub base_addr: u64,
56 pub rkey: u32,
57}
58
59pub trait RemoteQp {
63 fn qp_identity(&self) -> (u32, u32, [u8; 16]);
64}
65
66impl RemoteQp for VerbsServerParams {
67 fn qp_identity(&self) -> (u32, u32, [u8; 16]) {
68 (self.qpn, self.psn, self.gid)
69 }
70}
71
72impl RemoteQp for CacheServerParams {
73 fn qp_identity(&self) -> (u32, u32, [u8; 16]) {
74 (self.qpn, self.psn, self.gid)
75 }
76}
77
78impl VerbsServerParams {
79 pub fn write_to<W: std::io::Write>(&self, w: &mut W) -> Result<()> {
81 w.write_all(&self.qpn.to_le_bytes())?;
82 w.write_all(&self.psn.to_le_bytes())?;
83 w.write_all(&self.gid)?;
84 w.write_all(&(self.layers.len() as u32).to_le_bytes())?;
85 for (base, rkey) in &self.layers {
86 w.write_all(&base.to_le_bytes())?;
87 w.write_all(&rkey.to_le_bytes())?;
88 }
89 Ok(())
90 }
91
92 pub fn read_from<R: std::io::Read>(r: &mut R) -> Result<Self> {
93 let qpn = read_u32(r)?;
94 let psn = read_u32(r)?;
95 let mut gid = [0u8; 16];
96 r.read_exact(&mut gid).context("read server gid")?;
97 let n = read_u32(r)? as usize;
98 if n == 0 || n > 4096 {
99 bail!("implausible verbs layer count: {n}");
100 }
101 let mut layers = Vec::with_capacity(n);
102 for _ in 0..n {
103 let mut b8 = [0u8; 8];
104 r.read_exact(&mut b8).context("read mr base")?;
105 let base = u64::from_le_bytes(b8);
106 let rkey = read_u32(r)?;
107 layers.push((base, rkey));
108 }
109 Ok(Self {
110 qpn,
111 psn,
112 gid,
113 layers,
114 })
115 }
116}
117
118impl VerbsClientParams {
119 pub fn write_to<W: std::io::Write>(&self, w: &mut W) -> Result<()> {
121 w.write_all(&self.qpn.to_le_bytes())?;
122 w.write_all(&self.psn.to_le_bytes())?;
123 w.write_all(&self.gid)?;
124 Ok(())
125 }
126
127 pub fn read_from<R: std::io::Read>(r: &mut R) -> Result<Self> {
128 let qpn = read_u32(r)?;
129 let psn = read_u32(r)?;
130 let mut gid = [0u8; 16];
131 r.read_exact(&mut gid).context("read client gid")?;
132 Ok(Self { qpn, psn, gid })
133 }
134}
135
136impl CacheServerParams {
137 pub fn write_to<W: std::io::Write>(&self, w: &mut W) -> Result<()> {
139 w.write_all(&self.qpn.to_le_bytes())?;
140 w.write_all(&self.psn.to_le_bytes())?;
141 w.write_all(&self.gid)?;
142 w.write_all(&self.base_addr.to_le_bytes())?;
143 w.write_all(&self.rkey.to_le_bytes())?;
144 Ok(())
145 }
146
147 pub fn read_from<R: std::io::Read>(r: &mut R) -> Result<Self> {
148 let mut b4 = [0u8; 4];
149 let mut b8 = [0u8; 8];
150 let mut gid = [0u8; 16];
151 r.read_exact(&mut b4).context("kv qpn")?;
152 let qpn = u32::from_le_bytes(b4);
153 r.read_exact(&mut b4).context("kv psn")?;
154 let psn = u32::from_le_bytes(b4);
155 r.read_exact(&mut gid).context("kv gid")?;
156 r.read_exact(&mut b8).context("kv base")?;
157 let base_addr = u64::from_le_bytes(b8);
158 r.read_exact(&mut b4).context("kv rkey")?;
159 let rkey = u32::from_le_bytes(b4);
160 Ok(Self {
161 qpn,
162 psn,
163 gid,
164 base_addr,
165 rkey,
166 })
167 }
168}
169
170fn read_u32<R: std::io::Read>(r: &mut R) -> Result<u32> {
171 let mut b = [0u8; 4];
172 r.read_exact(&mut b).context("read u32")?;
173 Ok(u32::from_le_bytes(b))
174}
175
176pub fn write_server_rails<W: std::io::Write>(w: &mut W, rails: &[VerbsServerParams]) -> Result<()> {
181 if rails.is_empty() || rails.len() > 8 {
182 bail!("implausible server rail count: {}", rails.len());
183 }
184 w.write_all(&[rails.len() as u8])?;
185 for sp in rails {
186 sp.write_to(w)?;
187 }
188 Ok(())
189}
190
191pub fn read_server_rails<R: std::io::Read>(
195 r: &mut R,
196 want: usize,
197) -> Result<Vec<VerbsServerParams>> {
198 let mut b1 = [0u8; 1];
199 r.read_exact(&mut b1).context("read server rail count")?;
200 let n = b1[0] as usize;
201 if n == 0 || n > 8 {
202 bail!("implausible server rail count: {n}");
203 }
204 if n != want {
205 bail!("server framed {n} rails but client negotiated {want}");
206 }
207 let mut rails = Vec::with_capacity(n);
208 for _ in 0..n {
209 rails.push(VerbsServerParams::read_from(r)?);
210 }
211 Ok(rails)
212}