0

在 realtek 的 r8169 驱动程序中

    rx_buf = page_address(tp->Rx_databuff[entry]);
    dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE);
    prefetch(rx_buf);
    skb_copy_to_linear_data(skb, rx_buf, pkt_size);<----//Do I get packet at this????
    skb->tail += pkt_size;
    skb->len = pkt_size;
    dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE);
    //csum...
    skb->protocol = eth_type_trans(skb, dev);
    napi_gro_receive(&tp->napi, skb);

这是从驱动程序轮询调用的 rtl_rx 函数内部。我想在上面的代码中知道如何在之后的哪一行从 skb 中提取整个数据包。

我假设在这条线上

             skb_copy_to_linear_data(skb, rx_buf, pkt_size);

我应该有一个数据包,但想知道创建 kmalloc obect 的正确方法

         void   *packet=   kmalloc(....sizeof(struct ethhdr)+sizeof(struct iphdr)+sizeof(tcphdr))

并从 void *packet 读取以太网 ip 和 tcp 标头

如何实现

或者我应该简单地做 skb_netword_header、skb_tcp_header 等...在上面的行中填充 skb 后从 skb 中提取标头和有效负载,

或者我可以简单地转换为

              rx_buf = page_address(tp->Rx_databuff[entry]);
              struct ether_header ethhdr_of_packet=(struct eher_header *) rx_buf;

它应该工作吗?

4

1 回答 1

1

突出显示的行(带有 的行skb_copy_to_linear_data())确实将整个数据包数据驱动程序内部 Rx 环 ( rx_buf)中的缓冲区复制skb 的数据缓冲区。

static inline void skb_copy_to_linear_data(struct sk_buff *skb,
                       const void *from,
                       const unsigned int len)
{
    memcpy(skb->data, from, len);
}

将指针投射rx_buf到以太网标头也应该没问题。但是,在您的问题中,像这样访问数据包标头的目的相当模糊。您是想打印(“转储”)数据包还是打算将数据包数据复制到完全不同的缓冲区以在其他地方使用?

于 2021-02-06T12:27:12.530 回答