10
Getting the data from A to B 5. tcp_send_skb() call tcp_transmit_skb(sk, skb_clone(skb, GFP_KERNEL)); 6. tcp_transmit_skb(struct sock *sk, struct sk_buff *skb) {… struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); /* Build TCP header and checksum it. */ … tp->af_specific->queue_xmit(skb); 7. Ip_queue_xmit() /* Queues a packet to be sent, and starts the transmitter if necessary. This routine also needs to put in the total length and compute the checksum. */ {… /* Make sure we can route this packet. */ skb->dst = dst_clone(sk->dst_cache); /* OK, we know where to send it, allocate and build IP header. */… /* Do we need to fragment. Again this is inefficient. We need to somehow lock the original buffer and use bits of it. */… /* Add an IP checksum. */…

12
Getting the data from A to B 10. The data, embedded in an Ethernet packet, are received by NIC in B. (NIC is assumed WD8013) 11. NIC trigger an interrupt. This is handled by ei_interrupt(). Call ei_receive() (ei_* functions are chip- specific code for many 8390-based ethernet adaptors) 12. Ei_receive() { … struct sk_buff *skb; skb = dev_alloc_skb(pkt_len+2);…. netif_rx(skb); …} 13 netif_rx() receive a packet from a device driver and queue it for the upper (protocol) levels. Call {skb_queue_tail(&backlog,skb); mark_bh(NET_BH); } 14. There is only one list of backlog in the entire system. 15. Do_bottom_half() calls net_bh()

13
Getting the data from A to B 10. net_bh() {… skb = skb_dequeue(&backlog); /* Bump the pointer to the next structure. skb->data and skb->nh.raw point to the MAC and encapsulated data */ skb->h.raw = skb->nh.raw = skb->data; /* Fetch the packet protocol ID. */ type = skb->protocol; /* We got a packet ID. Now loop over the "known protocols" list. There are two lists. The ptype_all list of taps (normally empty) and the main protocol list which is hashed perfectly for normal protocols. */… if (ptype->type == type && (ptype->dev==skb->dev)) {/*We already have a match queued. Deliver to it*/ skb2=skb_clone(skb, GFP_ATOMIC); pt_prev->func(skb2, skb->dev, pt_prev);…}

14
Getting the data from A to B 10. Call ip_rcv() {… /* check the header for correctness and deal with all the IP options. Ip_forward() and ip_defrag() */ … return skb->dst->input(skb); } 11 ip_local_deliver() {… /* Reassemble IP fragments.*/ skb = ip_defrag(skb); /*Deliver to raw sockets. This is fun as to avoid copies we want to make no surplus copies. */ … /* Pass on the datagram to each protocol that wants it, based on the datagram protocol. */... ipprot->handler(skb2, ntohs(iph->tot_len) - (iph->ihl * 4)); …} 12 tcp_v4_rcv(), udp_rcv(),icmp_rcv()

16
Getting the data from A to B 15. TCP receive function for the ESTABLISHED state. * It is split into a fast path and a slow path. The fast path is disabled when: * - A zero window was announced from us - zero window probing * is only handled properly in the slow path. * - Out of order segments arrived. * - Urgent data is expected. * - There is no buffer space left * - Unexpected TCP flags/window values/header lengths are received (detected by checking the TCP header against pred_flags) * - Data is sent in both directions. Fast path only supports pure senders or pure receivers (this means either the sequence number or the ack value must stay constant) * When these conditions are not satisfied it drops into a standard * receive procedure patterned after RFC793 to handle all cases. * The first three cases are guaranteed by proper pred_flags setting, * the rest is checked inline. Fast processing is turned on in * tcp_data_queue when everything is OK.

17
Getting the data from A to B 16. Tcp_data() enter the buffer sk_buff in the list 17. Data_ready() wake up the waiting processes. 18 The former actions are carried up in the kernel, outside of any process. 19. B executes read(socket, data, len). 20. Through sys_read() --- sock_read() – inet_rcvmsg()– tcp_rcvmsg(). 21 This completes the data’s travels from process A to process B. 22 The data is copied only four times: 1) From the user space of A to kernel memory 2) From kernel memory to network card. 3) From network card to another computer’s kernel memory 4) From B’s kernel memory to B’s user space