网络数据接收流程:
以下为链路层
1、e100_intr(drivers/net/ethernet/intel/e100.c)
网卡驱动接收中断服务程序
2、__napi_schedule(net/core/dev.c)
3、____napi_schedule (net/core/dev.c)
主要功能:
将驱动程序中的napi->poll_list链接到cpu的softnet_data->poll_list
4、__raise_softirq_irqoff(net/core/dev.c)
触发软中断
5、net_rx_action(net/core/dev.c)
软中断服务程序、n->poll(调用e100_poll)
6、e100_poll(drivers/net/ethernet/intel/e100.c)
7、e100_rx_clean(drivers/net/ethernet/intel/e100.c)
通过DMA传输方式将网卡硬件接收的数据存储到struct nic结构中的skb接收缓存链表
8、e100_rx_indicate(drivers/net/ethernet/intel/e100.c)
解析以太网协议类型(MAC协议)
9、netif_receive_skb(net/core/dev.c)
10、enqueue_to_backlog(net/core/dev.c)
将skb缓存链接到softnet_data(struct softnet_data结构)
11、__netif_receive_skb(net/core/dev.c)
12、__netif_receive_skb_core(net/core/dev.c)
13、deliver_skb(net/core/dev.c)
通过struct packet_type结构的func (接收函数指针)调用网络层接收接口
Ip协议接收回调函数定义如下:
static struct packet_type ip_packet_type __read_mostly = {
.type = cpu_to_be16(ETH_P_IP),
.func = ip_rcv,
};
以下接口为网络层(ip层)
14、ip_rcv(net/ipv4/ip_input.c)
接口主要功能
Ip协议头解析
Netfilter 防火墙处理(NF_INET_PRE_ROUTING)
15、ip_rcv_finish(net/ipv4/ip_input.c)
16、ip_route_input_noref(net/ipv4/route.c)
设置ip接收路由处理回调函数,分为本地传输和转发两种分支:
a、本地接收上传
ip_route_input_mc->ip_local_deliver
ip_local_deliver(net/ipv4/ip_input.c)
Ip路由处理回调函数,本地传输
Netfilter 防火墙处理(NF_INET_LOCAL_IN)
ip_local_deliver_finish(net/ipv4/ip_input.c)
struct net_protocol *ipprot;
ipprot = rcu_dereference(inet_protos[protocol]);
inet_protos[protocol]数组在(/net/ipv4/af_inet.c)中inet_init->inet_add_protocol函数初始化:
static const struct net_protocol tcp_protocol = {
.early_demux = tcp_v4_early_demux,
.handler = tcp_v4_rcv,
.err_handler = tcp_v4_err,
.no_policy = 1,
.netns_ok = 1,
};
ipprot->handler(skb);
传输层接口调用,将skb数据包传到本地上层应用层
以下接口为传输层(tcp层)
tcp_v4_rcv(net/ipv4/tcp_ipv4.c)
接口功能:
解析tcp协议头
tcp_queue_rcv(net/ipv4/tcp_input.c)
__skb_queue_tail
将skb添加到socket->sock->sk_receive_queue队列中
tcp_recvmsg
应用层读取套节子接收队列
b、转发到其他主机
ip_route_input_slow->ip_mkroute_input->__mkroute_input->ip_forward (net/ipv4/route.c)
ip_forward (net/ipv4/ip_forward.c)
Netfilter 防火墙处理(NF_INET_FORWARD)
ip_forward_finish (net/ipv4/ip_forward.c)
dst_output_sk (net/ipv4/ip_forward.c)
调用发送接口将数据包转发出去
16、dst_input (include/net/dst.h)
调用上面设置的路由处理回调函数
Ip层数据收发流程图: