|
|
|
@ -29,7 +29,7 @@ fn af_xdp() {
|
|
|
|
|
// So this needs to be page aligned. Pages are 4k on all mainstream architectures except for
|
|
|
|
|
// Apple Silicon which uses 16k pages. So let's align on that for tests to run natively there.
|
|
|
|
|
#[repr(C, align(16384))]
|
|
|
|
|
struct PacketMap(MaybeUninit<[u8; 4096]>);
|
|
|
|
|
struct PacketMap(MaybeUninit<[u8; 2 * 4096]>);
|
|
|
|
|
|
|
|
|
|
// Safety: don't access alloc down the line.
|
|
|
|
|
let mut alloc = Box::new(PacketMap(MaybeUninit::uninit()));
|
|
|
|
@ -60,10 +60,12 @@ fn af_xdp() {
|
|
|
|
|
socks.set(0, rx.as_raw_fd(), 0).unwrap();
|
|
|
|
|
|
|
|
|
|
let frame = umem.frame(BufIdx(0)).unwrap();
|
|
|
|
|
let frame1 = umem.frame(BufIdx(1)).unwrap();
|
|
|
|
|
|
|
|
|
|
// Produce a frame to be filled by the kernel
|
|
|
|
|
let mut writer = fq_cq.fill(1);
|
|
|
|
|
// Produce two frames to be filled by the kernel
|
|
|
|
|
let mut writer = fq_cq.fill(2);
|
|
|
|
|
writer.insert_once(frame.offset);
|
|
|
|
|
writer.insert_once(frame1.offset);
|
|
|
|
|
writer.commit();
|
|
|
|
|
|
|
|
|
|
let sock = UdpSocket::bind("127.0.0.1:0").unwrap();
|
|
|
|
@ -84,6 +86,17 @@ fn af_xdp() {
|
|
|
|
|
assert_eq!(&udp[0..2], port.to_be_bytes().as_slice()); // Source
|
|
|
|
|
assert_eq!(&udp[2..4], 1777u16.to_be_bytes().as_slice()); // Dest
|
|
|
|
|
assert_eq!(payload, b"hello AF_XDP");
|
|
|
|
|
|
|
|
|
|
assert_eq!(rx.available(), 1);
|
|
|
|
|
// Removes socket from map, no more packets will be redirected.
|
|
|
|
|
socks.clear_index(0).unwrap();
|
|
|
|
|
assert_eq!(rx.available(), 1);
|
|
|
|
|
sock.send_to(b"hello AF_XDP", "127.0.0.1:1777").unwrap();
|
|
|
|
|
assert_eq!(rx.available(), 1);
|
|
|
|
|
// Adds socket to map again, packets will be redirected again.
|
|
|
|
|
socks.set(0, rx.as_raw_fd(), 0).unwrap();
|
|
|
|
|
sock.send_to(b"hello AF_XDP", "127.0.0.1:1777").unwrap();
|
|
|
|
|
assert_eq!(rx.available(), 2);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|