Linux网络收包流程

 关于linux网络包的收发流程,网上随便一搜都可以搜一桶,但自己不动手永远都搞不原理。最近在家比较闲,对网络这一块也不太了解,老婆在看《三生三世枕上书》,我只能看下代码打发下时间。

    小编习惯熟悉内核子系统原理从低版本内核开始.
 

    Linux(2.6.11.12)网络收包流程图:

        

   

  device driver interrupt handler       netif_rx()              cpu_raise_softirq()                     do_softirq()net_rx_atcion()      dev->poll(dev, &budget)( process_backlog)(注0)
      process_backlog()   netif_receive_skb()       skb_bond(skb); 如果网卡绑定,则取netdev 的master设备       pt_prev->func() (注1)       type = skb->protocol(L3层 ipv4 or ipv6 ..)          ip_rcv()             NF_HOOK(PF_INET,NF_IP_PRE_ROUTING,skb, dev, NULL,ip_rcv_finish);               ip_rcv_finish()                   dst_input()                     skb->dst->input();(注2)                        (ip_local_deliver或ip_forward)                           ip_local_deliver()                              NF_HOOK(PF_INET,NF_IP_LOCAL_IN, skb, skb->dev, NULL,                                ip_local_deliver_finish);                                    ip_local_deliver_finish()                                        ipprot->handler(skb);                                        (L4层 udp_rcv/tcp_v4_rcv..)                                         udp_rcv()                                           udp_queue_rcv_skb()                                              sock_queue_rcv_skb                                               sk->sk_data_ready()                   (sock_def_readable)
                                                             static void sock_def_readable(structsock *sk, int len)
{
       read_lock(&sk->sk_callback_lock);       if (sk->sk_sleep && waitqueue_active(sk->sk_sleep))               wake_up_interruptible(sk->sk_sleep);       sk_wake_async(sk,1,POLL_IN);       read_unlock(&sk->sk_callback_lock);}
                                                                     sys_recvfrom()       sock_recvmsg()              sock->ops->recvmsg()(sock_common_recvmsg)              sock_common_recvmsg()                     sk->sk_prot->recvmsg()(udp_recvmsg)                     udp_recvmsg()                            skb_recv_datagram()                                   wait_for_packet()   static int wait_for_packet(structsock *sk, int *err, long *timeo_p){  DEFINE_WAIT(wait);  prepare_to_wait_exclusive(sk->sk_sleep,&wait,TASK_INTERRUPTIBLE);}注0:net_dev_init(){  queue->backlog_dev.poll = process_backlog;}注1:void __init ip_init(void){  dev_add_pack(&ip_packet_type);}static struct packet_type ip_packet_type = {        .type = __constant_htons(ETH_P_IP),        .func = ip_rcv,};void __init ipv6_packet_init(void){        dev_add_pack(&ipv6_packet_type);}
static struct packet_type ipv6_packet_type = {        .type = __constant_htons(ETH_P_IPV6),        .func = ipv6_rcv,};
void dev_add_pack(struct packet_type *pt){  list_add_rcu(&pt->list, &ptype_base[hash]);}
注2:ip_rcv_finish  ip_route_input    ip_route_input_slowip_route_input_slow(){  rth->u.dst.input = ip_forward;  rth->u.dst.input= ip_local_deliver;}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值