The bridge implementation of the linux protocol stack

  

outlines the processing of data on the NIC driver, and then the flow of the packet continues down. The last function of the NIC driver is netif_receive_skb. Let's start with it. For the sake of simplicity, the pre-compiled code int netif_receive_skb(struct sk_buff *skb) (net/core/dev.c){struct packet_type *ptype, *pt_prev;int ret = NET_RX_DROP;unsigned short type;//received Timestamp if (!skb->stamp.tv_sec)net_timestamp(&skb->stamp);//If dev->master is present. Then update the corresponding pointer skb_bond(skb); //update the CPU's receiving statistics __get_cpu_var(netdev_rx_stat).total++;skb->h.raw = skb->nh.raw = skb->data;skb-> ;mac_len = skb->nh.raw - skb->mac.raw;pt_prev = NULL;rcu_read_lock();//Modules for all protocols list_for_each_entry_rcu(ptype, &ptype_all, list) {if (!ptype- >dev | |  Ptype->dev == skb->dev) {if (pt_prev)

ret = deliver_skb(skb, pt_prev);pt_prev = ptype;}}//Slice processing handle_diverter(skb);//bridge processing if (handle_bridge(&skb, &pt_prev, &ret)) goto out; type = skb->protocol; //for the protocol call the corresponding module processing. List_for_each_entry_rcu(ptype, &ptype_base[ntohs(type)&15], list) {if (ptype->type == type &&(!ptype->dev | |  Ptype->dev == skb->dev)) {if (pt_prev)

ret = deliver_skb(skb, pt_prev);pt_prev = ptype;}}if (pt_prev) {ret = pt_prev-> ;func(skb, skb->dev, pt_prev);} else {kfree_skb(skb);/* Jamal, now you will not able to escape explaining* me how you were going to use this. :-)*/ret = NET_RX_DROP;}out:rcu_read_unlock();return ret;} This function mainly completes fragment reassembly, bridge processing, and calls different transport layer processing modules according to different protocols. The focus of this section is to outline the implementation and processing of linux bridges. The transport layer protocol layering will be given in subsequent chapters. Enter the bridge processing code: #if defined(CONFIG_BRIDGE) | |  Defined (CONFIG_BRIDGE_MODULE) (net/core/dev.c)int (*br_handle_frame_hook)(struct net_bridge_port *p, struct sk_buff **pskb);static __inline__ int handle_bridge(struct sk_buff **pskb,struct packet_type **pt_prev, int * Ret) {struct net_bridge_port *port; //loopback interface? Non-Ethernet interface? If ((*pskb)->pkt_type == PACKET_LOOPBACK | | (port = rcu_dereference((*pskb)->dev->br_port)) == NULL)return 0;if (*pt_prev) {*ret = deliver_skb(*pskb, *pt_prev);*pt_prev = NULL;}

//br_handle_frame_hook is a global function pointer return br_handle_frame_hook(port, pskb);}#else#define handle_bridge(skb, pt_prev, ret) (0)#endif can be seen from this. If the bridge mode is selected during compilation, it will enter the processing module of the bridge. Otherwise, it is just an empty function and returns directly. What is the function represented by br_handle_frame_hook? What is the data processing framework of the bridge? Ha ha. This is the problem that we are analyzing today.

Copyright © Windows knowledge All Rights Reserved