为什么导出的网络设备 xmit 调用导致内核崩溃?

why is exported net device xmit call causing kernel crash?

我有一个修改过的网络设备 driver 导出它的 xmit 函数。该函数暴露给另一个独立的 driver。每次我从独立模块调用设备 xmit 函数时,内核都会崩溃。在 xmit 调用之前有调试打印,但它们从未出现。

现在我是这样实现的。

社区header:

struct net_dev_op {
    netdev_tx_t (*xmit) (struct sk_buff * skb, struct net_device * dev);
};

网络设备driver:

static const struct net_dev_op op = {
    .xmit = dev_xmit;
};

stand_alone_module_register(op);

在独立模块中:

static const struct net_dev_op *ops;

int stand_alone_module_register(static const struct net_dev_op op) {
    ops = &op;
}

static int someFun() {
    ... // code reading ethernet header and manipulating skb
    ops->xmit(skb, dev);  // <-- this is where it crashes
    ...
}

在上面的代码中,内核在调用 ops->xmit 函数时崩溃。我已经验证了 xmit 函数、ops 结构、skb 缓冲区和 dev 设备指针的指针地址。 None 个为 NULL。然而,内核崩溃,好像在某处遇到了 NULL 指针。

那么为什么会出现这种行为?在调用设备特定的 xmit 函数之前,我需要调用任何特定的函数吗? linux内核中,net device xmit函数是如何处理的?任何人都知道在哪里可以找到原始代码?我目前正在 Ubuntu 服务器 14.04 LTS 和 3.13.0-43 上开发,尽管我严重怀疑这是内核版本特定的东西。

您将堆栈上的结构传递给寄存器函数,然后存储指向它的指针(堆栈上的副本)。一旦你从 register 函数中 return ,堆栈上的结构就会被破坏。然后稍后您尝试通过堆栈上现在重用的 space 调用函数。

stand_alone_module_register 应该接受指向结构的 指针 (并且调用者应该传递其结构的地址)。然后把指针存起来备用就好了。