一文了解Linux内核网络数据包处理流程

0. Linux内核网络数据包处理流程 - 网络硬件

网卡工作在物理层和数据链路层,主要由PHY/MAC芯片、Tx/Rx FIFO、DMA等组成,其中网线通过变压器接PHY芯片、PHY芯片通过MII接MAC芯片、MAC芯片接PCI总线

PHY/MAC芯片

PHY芯片主要负责:CSMA/CD、模数转换、编解码、串并转换

MAC芯片主要负责:

  1. 比特流和帧的转换:7字节的前导码Preamble和1字节的帧首定界符SFD
  2. CRC校验
  3. Packet Filtering:L2 Filtering、VLAN Filtering、Manageability / Host Filtering

Intel的千兆网卡以82575/82576为代表、万兆网卡以82598/82599为代表

1. Linux内核网络数据包处理流程 - 网卡驱动

网卡驱动ixgbe初始化

网卡驱动为每个新的接口在一个全局的网络设备列表里插入一个数据结构.每个接口由一个结构 net_device 项来描述, 它在<linux/netdevice.h>里定义。该结构必须动态分配。

每个网卡,无论是物理还是虚拟的网卡,都必须有一个:net_device,这个struct是在网卡驱动中分配创建的,不通的网卡,对应厂商不同的驱动,那么看看ixgbe的驱动初始化; 创建net_device 的函数是: alloc_etherdev , 或者: alloc_etherdev_mq

https://www.cnblogs.com/lidp/archive/2009/05/13/1697981.html

pci设备:

在内核中,一个PCI设备,使用struct pci_driver结构来描述, 因为在系统引导的时候,PCI设备已经被识别,当内核发现一个已经检测到的设备同驱动注册的id_table中的信息相匹配时,
它就会触发驱动的probe函数,

比如,看看ixgbe 驱动:

static struct pci_driver ixgb_driver = {
    .name     = ixgb_driver_name,
    .id_table = ixgb_pci_tbl,
    .probe    = ixgb_probe,
    .remove   = ixgb_remove,
    .err_handler = &ixgb_err_handler
};
#vim drivers/net/ethernet/intel/ixgbe/ixgbe_main.c

module_init
    ixgbe_init_module
        pci_register_driver

probe函数被调用,证明已经发现了我们所支持的网卡,这样,就可以调用register_netdev函数向内核注册网络设备了,注册之前,一般会调用alloc_etherdev分配一个net_device,然后初始化它的重要成员。

ixgbe_probe  
    struct net_device *netdev;
    struct pci_dev *pdev;
    pci_enable_device_mem(pdev);
    pci_request_mem_regions(pdev, ixgbe_driver_name);
    pci_set_master(pdev);
    pci_save_state(pdev);
    netdev = alloc_etherdev_mq(sizeof(struct ixgbe_adapter), indices);// 这里分配struct net_device
    	alloc_etherdev_mqs
    		alloc_netdev_mqs(sizeof_priv, "eth%d", NET_NAME_UNKNOWN, ether_setup, txqs, rxqs);
    			ether_setup  // Initial struct net_device
    			
    SET_NETDEV_DEV(netdev, &pdev->dev);
    adapter = netdev_priv(netdev);

refs: https://blog.csdn.net/shallnet/article/details/25470775

alloc_etherdev_mqs() -> ether_setup()
void ether_setup(struct net_device *dev)
{
    dev->header_ops     = &eth_header_ops;
    dev->type       = ARPHRD_ETHER;
    dev->hard_header_len    = ETH_HLEN;
    dev->min_header_len = ETH_HLEN;
    dev->mtu        = ETH_DATA_LEN;
    dev->addr_len       = ETH_ALEN;
    dev->tx_queue_len   = 1000; /* Ethernet wants good queues */
    dev->flags      = IFF_BROADCAST|IFF_MULTICAST;
   
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值