实现Loopback回环网卡设备及其驱动

Loopback回环网卡设备及其驱动实现开发进度

Loopback开发思路

参考virto_net网卡,Loopback设备自顶向下由LoopbackInterface层、LoopbackDriverWapper层、LoopbackDriver层、Loopback层实现,每层有自己的功能实现。

Loopback层是Loopback实现的核心,其结构为一个VecDeque<Vec<v8>>,VecDeque<Vec<v8>>负责形成回环结构,从头部发送数据,接收的数据从尾部传入,FIFO。

Loopback驱动开发思路

Loopback设备驱动用于操作Loopback设备,通过实现调用Loopback的receive函数和transmission函数实现smoltcp的device接口

对LoopbackDriver层实现phy::Device接口,重写capability函数、receive函数、transmit函数;

capability函数重写:创建默认DeviceCapability结构体,设置max_transmission_unit = 65535;设置max_burst_size = 1;

receive函数重写:在这个方法中,我们首先尝试从self.inner.lock().queue的前端弹出一个数据包。这个队列是一个VecDeque<Vec>,它存储了待处理的数据包。如果队列中有数据包,我们使用map函数创建一个接收token和一个发送token。接收token包含了弹出的数据包,发送token包含了一个指向队列的可变引用,这样我们就可以在发送数据包时将其添加到队列中。如果队列为空。pop_front方法会返回None,此时map函数也会返回None,表示当前没有数据包可供接收。

transmit函数重写: 返回Loopback的queue用于send

对LoopbackDeviceInnerWapper层实现Send、Sync、Deref、DereMut,用于包裹Loopback设备驱动。

LoopbackInterface设计

对LoopbackInterface作为接口设备吗,用来规范化内核注册设备。接口层实现Device接口,KObject层。

设备注册流程

编写init函数作为设备注册的接口,调用probe函数在NETDEVICE列表中添加网卡设备。

2 个赞

我想到一个问题,linux里面它loop back网卡,比如说发出去,但是对面没接收的话,他这个数据缓存的大小是多少?

(感觉总要有个丢包的机制

模仿e1000e网卡向内核注册lo网卡,报错virtio_probe_mmio failed: ENODEV,明明lo和virtio是没有关联的,请教一下大家

现在传输接收仍有些奇怪的bug、、

我修改了下测试程序可以接受到返回的数据重新测了一下,如果输出那条debug日志,ping127.0.0.1是lo发的和收的,验证办法是我把lo的底层发包函数改为空函数就接受不到数据包了,不改就能;然后如果不输出那条debug日志,lo就不工作了,ping也没法接收到数据。我现在在弄明白为啥加上一条日志就可以正常工作


选中行

输出日志正常工作情况:


取消输出日志不工作情况:

把发送和接受的Debug信息注释掉吧

然后test_lo这样写会不会好点:

use std::net::UdpSocket;
use std::str;

fn main() -> std::io::Result<()> {
    let socket = UdpSocket::bind("127.0.0.1:34254")?;
    socket.connect("127.0.0.1:34254")?;

    let msg = "Hello, loopback!";
    socket.send(msg.as_bytes())?;

    let mut buf = [0; 1024];
    let (amt, _src) = socket.recv_from(&mut buf)?;

    let received_msg = str::from_utf8(&buf[..amt]).expect("Could not read buffer as UTF-8");

    println!("Sent: {}", msg);
    println!("Received: {}", received_msg);

    assert_eq!(msg, received_msg, "The sent and received messages do not match!");

    Ok(())
}