Skip to content

Commit 87c7460

Browse files
committed
feat(ibverbs): add GlobalRoutingHeader wrapper for parsing GRH from buffers
Add a smoltcp-style `GlobalRoutingHeader<T>` wrapper that provides zero-copy read/write access to Global Routing Header fields directly from byte buffers. - `new_unchecked` / `new_checked` constructors for buffer wrapping - Field accessors: version, traffic_class, flow_label, payload_length, next_header, hop_limit, source_gid, destination_gid - Mutable setters for all fields when buffer is writable - `as_ptr` / `as_mut_ptr` for FFI interop - `grh` for copying to owned `ibv_grh` struct Also add `--debug-grh` flag to ud_pingpong_split example to print received GRH on each iteration for debugging purposes. Signed-off-by: Luke Yue <lukedyue@gmail.com>
1 parent 4810ef0 commit 87c7460

2 files changed

Lines changed: 336 additions & 160 deletions

File tree

examples/ud_pingpong_split.rs

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use byte_unit::{Byte, UnitType};
1010
use clap::{Parser, ValueEnum};
1111
use postcard::{from_bytes, to_allocvec};
1212
use serde::{Deserialize, Serialize};
13-
use sideway::ibverbs::address::{AddressHandle, AddressHandleAttribute, Gid};
13+
use sideway::ibverbs::address::{AddressHandle, AddressHandleAttribute, Gid, GlobalRoutingHeader};
1414
use sideway::ibverbs::completion::{
1515
CreateCompletionQueueWorkCompletionFlags, ExtendedCompletionQueue, ExtendedWorkCompletion, GenericCompletionQueue,
1616
WorkCompletionStatus,
@@ -62,6 +62,9 @@ pub struct Args {
6262
/// Get CQE with timestamp
6363
#[arg(long, short = 't', default_value_t = false)]
6464
ts: bool,
65+
/// Print GRH on each received packet
66+
#[arg(long, default_value_t = false)]
67+
debug_grh: bool,
6568
/// If no value provided, start a server and wait for connection, otherwise, connect to server at [host]
6669
#[arg(name = "host")]
6770
server_ip: Option<String>,
@@ -251,7 +254,7 @@ impl PingPongContext {
251254
fn parse_single_work_completion(
252255
&self, wc: &ExtendedWorkCompletion, ts_param: &mut TimeStamps, scnt: &mut u32, rcnt: &mut u32,
253256
outstanding_send: &mut bool, rout: &mut u32, rx_depth: u32, need_post_recv: &mut bool, to_post_recv: &mut u32,
254-
use_ts: bool,
257+
use_ts: bool, debug_grh: bool,
255258
) {
256259
if wc.status() != WorkCompletionStatus::Success as u32 {
257260
panic!(
@@ -270,6 +273,33 @@ impl PingPongContext {
270273
*rcnt += 1;
271274
*rout -= 1;
272275

276+
// Print GRH if debug mode is enabled
277+
if debug_grh {
278+
let recv_buf = unsafe {
279+
std::slice::from_raw_parts(self.recv_mr.get_ptr() as *const u8, (self.size + 40) as usize)
280+
};
281+
match GlobalRoutingHeader::new_checked(recv_buf) {
282+
Ok(grh) => {
283+
println!(
284+
"[recv #{}] GRH: version={}, traffic_class={:#04x}, flow_label={:#07x}, \
285+
payload_len={}, next_hdr={:#04x}, hop_limit={}, src_gid={}, dst_gid={}",
286+
*rcnt,
287+
grh.version(),
288+
grh.traffic_class(),
289+
grh.flow_label(),
290+
grh.payload_length(),
291+
grh.next_header(),
292+
grh.hop_limit(),
293+
grh.source_gid(),
294+
grh.destination_gid()
295+
);
296+
},
297+
Err(e) => {
298+
eprintln!("[recv #{}] Failed to parse GRH: {}", *rcnt, e);
299+
},
300+
}
301+
}
302+
273303
if *rout <= rx_depth / 2 {
274304
*to_post_recv = rx_depth - *rout;
275305
*need_post_recv = true;
@@ -439,6 +469,7 @@ fn main() -> Result<()> {
439469
&mut need_post_recv,
440470
&mut to_post_recv,
441471
args.ts,
472+
args.debug_grh,
442473
);
443474

444475
if scnt < args.iter && !outstanding_send {

0 commit comments

Comments
 (0)