Analysis of data sending and receiving process of Linux network card

User 7686797 2021-04-08 12:00:08
analysis data sending receiving process


Generally speaking , Network card has two important functions : receive data and send data .

therefore , When the network card receives the packet , To inform Linux The kernel has data to process . in addition , The NIC driver should provide Linux The interface that the kernel sends data to .

net_device Structure is Linux Objects abstracted for adapting different types of network card devices , Different NIC drivers just need to press Linux To fill in net_device Each member variable of the structure ,Linux The kernel can recognize the network card , And work .

Next, we will analyze the implementation principle of receiving and sending packets by network card devices .

net_device structure

net_device Structure is Linux The abstraction of network card device by kernel , But for historical reasons ,net_device The definition of structure is very complicated .

However, this paper mainly analyzes the implementation of receiving and sending data of network card equipment , So I won't analyze net_device All members of the structure . The members related to sending and receiving data are listed below , as follows :

struct net_device
{
char name[IFNAMSIZ]; // Device name
...
unsigned int irq; // Interrupt number
...
int (*init)(struct net_device *dev); // The device initializes the interface of the device
...
int (*open)(struct net_device *dev); // Interface called when opening the device
int (*stop)(struct net_device *dev); // Interface called when shutting down the device
// Send data interface
int (*hard_start_xmit)(struct sk_buff *skb,struct net_device *dev);
...
};
  • name: Name of equipment . It is used to display the name of the device on the terminal or search for the device through the device name .
  • irq: Interrupt number . When the network card receives a packet from the network , An interrupt needs to be generated to notify Linux The kernel has packets to process , and irq Is the interrupt number registered by the NIC driver to the kernel interrupt service .
  • initopenstop: They are the initialization interface of the device , Open the interface and close the interface .
  • hard_start_xmit: When you need to send data through network card device , You can call this interface to send data .

therefore , A NIC driver must complete the following two tasks :

  • By implementing net_device Structural hard_start_xmit Method to provide the function of sending data .
  • By registering the hardware interrupt service with the kernel , To inform the kernel to process the packets received by the network card device .

in other words , The function of sending data is by net_device Structural hard_start_xmit Method provides , The function of notifying the kernel to process the received packets is provided by the hardware interrupt of the network card .

chart 1 It shows the process of receiving and sending data :

chart 1 Network card receiving and sending data process

The picture above shows NS8390 network card The process of receiving and sending data ( The red brackets indicate the receiving process , The blue brackets indicate the sending process ), You can see from the picture above ,NS8390 Network card driver Two things have been done :

  • take net_device Structural hard_start_xmit Method set to ei_start_xmit.
  • towards Linux The kernel has registered ei_interrupt Hardware interrupt service .

therefore , When the network card receives a packet , Will trigger ei_interrupt Interrupt the service to inform the kernel that there are packets to process . And when you need to send data through the network card , Will call ei_start_xmit Method to send the data out .

The process of receiving data

When the network card receives a packet from the network , Will trigger ei_interrupt Interruption of service , Let's see ei_interrupt Interrupt service implementation :

void ei_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct net_device *dev = dev_id;
long e8390_base;
int interrupts, nr_serviced = 0;
struct ei_device *ei_local;
e8390_base = dev->base_addr;
ei_local = (struct ei_device *)dev->priv;
spin_lock(&ei_local->page_lock);
...
// (1) Read the interrupt type of the network card to perform the corresponding operation
while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
&& ++nr_serviced < MAX_SERVICE)
{
...
// (2) If the interrupt type is packet received
if (interrupts & (ENISR_RX + ENISR_RX_ERR)) {
ei_receive(dev); // (3) Read data from the network card
}
...
}
...
spin_unlock(&ei_local->page_lock);
return;
}

The above code removes a lot of hardware related operations , Because this article is not to analyze the implementation of NIC driver .

ei_interrupt The interrupt service first reads the type of interrupt , Save to interrupts variable . Then judge whether the interrupt type is received packet , If so, call ei_receive Function to read data from the network card .

We continue to analyze ei_receive Implementation of function :

static void ei_receive(struct net_device *dev)
{
...
while (++rx_pkt_count < 10)
{
int pkt_len; // The length of the packet
int pkt_stat; // The state of the packet
...
if ((pkt_stat & 0x0F) == ENRSR_RXOK) { // If the packet state is legal
struct sk_buff *skb;
skb = dev_alloc_skb(pkt_len + 2); // Apply for a packet object
if (skb) {
skb_reserve(skb, 2);
skb->dev = dev; // Set the device to receive the packet
skb_put(skb, pkt_len); // Increase the length of the data
// Read data from network card ( Driven by network card ), And save the data to skb in
ei_block_input(dev, pkt_len, skb, current_offset+sizeof(rx_frame));
skb->protocol = eth_type_trans(skb, dev); // Get the protocol type from the Ethernet layer
netif_rx(skb); // Send the packet to the kernel network protocol stack
...
}
}
...
}
...
return;
}

ei_receive Function mainly completes the following work :

  • Apply for one sk_buff Package object , And set it dev The field is the device receiving the packet .
  • By calling ei_block_input Function to read the received data from the network card , And save it to the one you just applied for sk_buff In the packet object .ei_block_input The function is implemented by the NIC driver , Therefore, we will not make a detailed analysis here .
  • By calling eth_type_trans Function gets the network layer protocol type from the Ethernet header of the packet .
  • call netif_rx Function to send the packet to the kernel network protocol stack .

When the packet is sent to the kernel network protocol stack , The processing of packets is taken over by the kernel . Generally speaking , The kernel network protocol stack will pass through the network layer IP agreement And transport layer TCP agreement perhaps UDP agreement To process packets , After processing, the data will be submitted to the application layer process for processing .

The process of sending data

When the network protocol stack needs to send data through the network card device , Would call net_device Structural hard_start_xmit Method , And for NS8390 network card Come on ,hard_start_xmit Method will be set to ei_start_xmit function .

in other words , Use NS8390 network card When sending data , Will eventually call ei_start_xmit Function to send data out . Let's see ei_start_xmit Implementation of function :

static int ei_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
...
length = skb->len; // The length of the packet
...
disable_irq_nosync(dev->irq); // Turn off hardware interrupt
spin_lock(&ei_local->page_lock); // Lock the device , Avoid multicore CPU The use of equipment
...
// Use the sending interface driven by network card to send data out ,skb->data For the data part of the packet
ei_block_output(dev, length, skb->data, ei_local->tx_start_page);
...
spin_unlock(&ei_local->page_lock); // Unlock the device
enable_irq(dev->irq); // Turn on hardware interrupt
...
return 0;
}

After deleting hardware related operations ,ei_start_xmit The implementation of the function is very simple :

  • First, turn off the hardware interrupt of the network card , To prevent interference from hardware interrupt during transmission .
  • call ei_block_output Function to send out the data of the packet , This function is implemented by network card driver , There is no detailed analysis here .
  • Turn on the hardware interrupt of the network card , Let the NIC continue to notify the kernel .

summary

This paper mainly introduces the process of receiving and sending packets by network card equipment , The initialization process of network card device is not involved . Of course, the initialization process of NIC devices is also very important , We may continue to analyze it in later articles .

This article is from WeChat official account. - Linux The kernel thing (like_linux)

The source and reprint of the original text are detailed in the text , If there is any infringement , Please contact the yunjia_community@tencent.com Delete .

Original publication time : 2021-03-19

Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .

版权声明
本文为[User 7686797]所创,转载请带上原文链接,感谢
https://javamana.com/2021/04/20210408111751325s.html

  1. A love diary about http
  2. navicat连接win10 mysql8.0 报错2059
  3. [rocketmq source code analysis] in depth message storage (3)
  4. Implementation of service configuration center with spring cloud + Nacos (Hoxton version)
  5. SCIP: constructing data abstraction -- Explanation of queue and tree in data structure
  6. SCIP: abstraction of construction process -- object oriented explanation
  7. Using docker to build elasticsearch + kibana cluster
  8. What are the spring IOC features? I can't understand the source code!
  9. Spring cloud upgrade road - 2020.0. X - 3. Accesslog configuration of undertow
  10. 导致Oracle性能抖动的参数提醒
  11. 风险提醒之Oracle RAC高可用失效
  12. 小机上运行Oracle需要注意的进程调度bug
  13. Oracle内存过度消耗风险提醒
  14. Oracle SQL monitor
  15. 使用Bifrost实现Mysql的数据同步
  16. 揭秘Oracle数据库truncate原理
  17. 看了此文,Oracle SQL优化文章不必再看!
  18. Mybatis (3) map and fuzzy query expansion
  19. Kafka性能篇:为何这么“快”?
  20. 两个高频设计类面试题:如何设计HashMap和线程池
  21. [TTS] AIX - & gt; Linux -- Based on RMAN (real environment)
  22. 为什么学编程大部分人选Java编程语言?
  23. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原理
  24. redis 为什么把简单的字符串设计成 SDS?
  25. [TTS] transfer table space AIX - & gt; Linux based on RMAN
  26. Linux 网卡数据收发过程分析
  27. Redis 高可用篇:你管这叫 Sentinel 哨兵集群原
  28. Redis 6.X Cluster 集群搭建
  29. [TTS] transfer table space AIX ASM - & gt; Linux ASM
  30. [TTS] transfer table space Linux ASM - & gt; AIX ASM
  31. 高性能通讯框架——Netty
  32. Brief introduction and test of orchestrator, a high availability management tool for MySQL
  33. [TTS] transfer table space Linux - & gt; AIX based on RMAN
  34. A love diary about http
  35. [rocketmq source code analysis] in depth message storage (3)
  36. Implementation of service configuration center with spring cloud + Nacos (Hoxton version)
  37. SiCp: abstraction of construction process -- object oriented explanation
  38. springboot网上点餐系统
  39. 【SPM】oracle如何固定执行计划
  40. 用好HugePage,告别Linux性能故障
  41. 3 W word long text, java basic interview questions! It's amazing!!!
  42. Spring cloud upgrade road - 2020.0. X - 3. Accesslog configuration of undertow
  43. Win10 uninstall mysql5.7
  44. CentOS下dotnet Core使用HttpWebRequest进行HTTP通讯,系统存在大量CLOSE_WAIT连接问题的分析,已解决。
  45. MySQL batch insert, how not to insert duplicate data?
  46. K8s cronjob application example
  47. Unconventional method, easy to deal with Oracle database critical exception
  48. How to use sqlplus - prelim in Oracle hang
  49. How to search Oracle official documents in full text
  50. Install mysql8.0 on win10
  51. Oracle OCR的备份与恢复
  52. Oracle kill session相关问题
  53. 《Oracle DBA工作笔记》第二章 常用工具和问题分析
  54. Oracle回收站及flashback drop
  55. Hand in hand to teach you to write a spring IOC container
  56. Exception in Java (1) - basic concept
  57. 3w 字长文爆肝 Java 基础面试题!太顶了!!!
  58. Error 2059 when Navicat connects to win10 mysql8.0
  59. Parameter reminder causing Oracle Performance jitter
  60. 「技术分享」Java线程状态间的互相转换看这个就行了