网络包处理的中断下半部

来源:互联网 发布:金螳螂五星级酒店知乎 编辑:程序博客网 时间:2024/06/06 09:27
中断下半部处理
   中断下半部将网卡中的DMA-ring中的skb取出来,经过ip层处理,主要是netfilter
   最后决定是否传递到本地传输层

   如果交给本地传输层ip的最后处理ip_local_deliver_finish

中断的下半部的结束位置是哪里? 何时出中断上下文?

   中断下半部的结束是把这个从DMA-ring中的skb找到归宿(传输层的队列或者转发出去)

    源码版本 2.6.32

  ip_local_deliver_finish(skb)  {    int protocol = ip_hdr(skb)->protocol;    int hash, raw;    const struct net_protocol *ipprot;resubmit:    raw = raw_local_deliver(skb, protocol);    hash = protocol & (MAX_INET_PROTOS - 1);    ipprot = rcu_dereference(inet_protos[hash]);    ......    ret = ipprot->handler(skb); } static const struct net_protocol tcp_protocol = {.handler =tcp_v4_rcv,.err_handler =tcp_v4_err,.gso_send_check = tcp_v4_gso_send_check,.gso_segment =tcp_tso_segment,.gro_receive =tcp4_gro_receive,.gro_complete =tcp4_gro_complete,.no_policy =1,.netns_ok =1,};
从ip层头部中确定protocol,若为tcp,进入tcp_v4_rcv

 tcp_v4_rcv() {    struct sock *sk;   //确定数据包是属于哪个sock对象   sk = __inet_lookup_skb(&tcp_hashinfo, skb, th->source, th->dest);   //将数据包放到tcp的队列中,中断的下半部就处理结束   //此处可能会有竞争要处理,就是内核态中的中断上下文和用户进程的系统调用对sock对象的访问   if (!sock_owned_by_user(sk))    {#ifdef CONFIG_NET_DMAstruct tcp_sock *tp = tcp_sk(sk);if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)tp->ucopy.dma_chan = dma_find_channel(DMA_MEMCPY);if (tp->ucopy.dma_chan)ret = tcp_v4_do_rcv(sk, skb);else#endif{if (!tcp_prequeue(sk, skb))ret = tcp_v4_do_rcv(sk, skb);}   } elsesk_add_backlog(sk, skb);   bh_unlock_sock(sk);   sock_put(sk); }

skb这个时候才算是找到了归宿sk_receive_queue,中断的下半部结束

tcp_rcv_established(){__skb_queue_tail(&sk->sk_receive_queue, skb);skb_set_owner_r(skb, sk);tp->rcv_nxt = TCP_SKB_CB(skb)->end_seq;if (!copied_early || tp->rcv_nxt != tp->rcv_wup)   __tcp_ack_snd_check(sk, 0);}



0 0
原创粉丝点击