Problem
ethernet.rs::ArpResponder::handle_arp allocates a new Vec<u8> for every ARP reply (Vec::with_capacity(ARP_FRAME_MIN_LEN) = 42 bytes). Replies are buffered in FrameClassifier::pending_arp_replies: Vec<Vec<u8>> and drained each tick.
ARP volume is low in steady state (guest typically caches the gateway MAC for minutes), so this is the lowest-priority allocation on the hot path. But:
- On boot, the guest does an initial ARP Request → we reply → guest caches → no more ARP for a while.
- Under aggressive ARP expiry or misconfigured guest, or in test scenarios, ARP can become frequent.
- Cleaning it up removes the last
Vec::with_capacity in the classifier's inline path, leaving only the packet pool.
Proposed fix
Return FrameBuf instead of Vec<u8> from ArpResponder::handle_arp:
FrameClassifier already owns a PacketPool (pool: Arc<PacketPool>).
- Pass a
&Arc<PacketPool> into handle_arp or restructure so the classifier builds the reply itself using its pool.
- Change
pending_arp_replies: Vec<Vec<u8>> → Vec<FrameBuf>.
- Update
take_arp_replies return type and the consumer in datapath_loop.rs::send_to_guest.
Files
virt/arcbox-net/src/ethernet.rs::ArpResponder::handle_arp (around line 131)
virt/arcbox-net/src/darwin/classifier.rs::pending_arp_replies, take_arp_replies, classify_frame (ARP branch)
virt/arcbox-net/src/darwin/datapath_loop.rs (ARP reply drain in the main loop)
Acceptance
- ARP replies flow through
FrameBuf::Pooled on the pool-hit path.
- Existing classifier tests still pass (
classify_arp_generates_reply, drain_guest_fd_reads_and_classifies).
- No behavioral change to ARP semantics.
Priority note
Priority: Low. ARP traffic is rare in steady state; only worth doing if done alongside other classifier/ethernet pooling work.
Problem
ethernet.rs::ArpResponder::handle_arpallocates a newVec<u8>for every ARP reply (Vec::with_capacity(ARP_FRAME_MIN_LEN)= 42 bytes). Replies are buffered inFrameClassifier::pending_arp_replies: Vec<Vec<u8>>and drained each tick.ARP volume is low in steady state (guest typically caches the gateway MAC for minutes), so this is the lowest-priority allocation on the hot path. But:
Vec::with_capacityin the classifier's inline path, leaving only the packet pool.Proposed fix
Return
FrameBufinstead ofVec<u8>fromArpResponder::handle_arp:FrameClassifieralready owns aPacketPool(pool: Arc<PacketPool>).&Arc<PacketPool>intohandle_arpor restructure so the classifier builds the reply itself using its pool.pending_arp_replies: Vec<Vec<u8>>→Vec<FrameBuf>.take_arp_repliesreturn type and the consumer indatapath_loop.rs::send_to_guest.Files
virt/arcbox-net/src/ethernet.rs::ArpResponder::handle_arp(around line 131)virt/arcbox-net/src/darwin/classifier.rs::pending_arp_replies,take_arp_replies,classify_frame(ARP branch)virt/arcbox-net/src/darwin/datapath_loop.rs(ARP reply drain in the main loop)Acceptance
FrameBuf::Pooledon the pool-hit path.classify_arp_generates_reply,drain_guest_fd_reads_and_classifies).Priority note
Priority: Low. ARP traffic is rare in steady state; only worth doing if done alongside other classifier/ethernet pooling work.