搜尋此網誌

2011年8月7日 星期日

tcpip stack(2) -- L3 send and receve


  1. 数据传输的数据结构

BSD Socket层使用struct msghdr保存数据。在INET Socket层以下使用struct sk_buff保存数据,这个结构被整个网络协议栈使用,如MAC或其他L2链路协议,三层IP,四层TCPUDP等。并且其中的成员变量在结构从一层向另一层传递时解析本层的数据头。
  1. 网络层数据收发

    a.发送数据
 raw_sendmsg
     |
     |- ip_router_output_flow 根据saddr和daddr在rt_hash_table中查找路由表。
     |                        如果没有找到则查找fib,并__mkroute_output创建struct rtable。将rtable加入rt_hash_table
     |                        neigh_create:根据rtable->dst_entry创建struct neigh邻居,设置定时操作neigh_timer_handler,
     |                        arp_constructor设置arp处理函数
     |
     |- ip_append_data   将大数据分片,创建struct sk_buffer,并将其加入struct sk->sk_write_queue
     |
     |- ip_push_pending_frames
           |
           |- ip_finish_skb  构造ip头
           |
           |- ip_send_skb
                 |
                 |- ip_local_output--> dst_output-->ip_output (__mkroute_output中指定rth->dst.output=ip_output)
                      |
                      |- ip_finish_output      如果在hh_cache中找到daddr信息则将数据传到driver
                     |                                   否则调用struct dst_entry->neighbour->output (neigh_resolve_output)
                     |- neigh_resolve_output
                           |
                           |- neigh_event_send  更改邻居状态为NUD_INCOMPLETE,neigh_timer_handler将发送arp请求(arp_solicit)
                          |     ......
                          |- apr_rev -> neigh_update      接收arp报文,更新邻居系统
                                |
                                |- neigh_resolve_output
                                     |
                                     |- neigh_hh_init     更新hh_cache
                                     |
                                     |- dev_hard_header   初始化以太网报文头
                                     |
                                     |- dev_queue_xmit 数据发送至硬件抽象层(neigh->ops->queue_xmit)
                                           |
                                           |- dev->netdev_ops->ndo_start_xmit  驱动数据发送函数

        b.发送数据
 |- netif_rx              驱动创建skb后调用此函数,函数skb加入struct softnet_data->input_pkt_queue中,之后出发软中断
 |  ......
 |- net_rx_action         数据接收软中断
     |
     |- process_backlog
           |- __skb_dequeue  从softnet_data->input_pkt_queue接收数据
           |
           |- __netif_receive_skb  调用struct packet_type->func(inet_init是注册ip_packet_type)
                 |
                 |- ip_rcv   解析ip头
                 |
                 |- ip_rcv_finish
                     |
                     |- ip_route_input_common    查找路由表,如果没有则加入fib和rt_hash_table
                     |
                     |- ip_local_deliver                 (struct dst_entry->input)
                         |
                         |- ip_local_deliver_finish
                         |      |
                         |      |- raw_v4_input     将skb加入struct sock->sk_receive_queue
                         |
                         |- 如果数据不是raw类型,则进入L4处理函数struct net_protocol->handler

沒有留言:

張貼留言