您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 项目/工程管理 > linux内核网络子模块学习笔记
一.网络设备的数据包处理。如下1.驱动装调用:net_dev_init2.net_dev_init中设定收包处理函数process_backlogsd-backlog.poll=process_backlog;3.process_backlog中调用__netif_receive_skb(skb);4.__netif_receive_skb中找到对应的包处理函数,然后处理type=skb-protocol;list_for_each_entry_rcu(ptype,&ptype_base[ntohs(type)&PTYPE_HASH_MASK],list){if(ptype-type==type&&(ptype-dev==null_or_dev||ptype-dev==skb-dev||ptype-dev==orig_dev)){if(pt_prev)ret=deliver_skb(skb,pt_prev,orig_dev);pt_prev=ptype;}}ret=pt_prev-func(skb,skb-dev,pt_prev,orig_dev);以上就把数据包传到了上层了。二.IP层的数据包处理。1.向ptype_base数组注册处理函数.(调用dev_add_pack)在数据inet_init中dev_add_pack(&ip_packet_type);2.staticstructpacket_typeip_packet_type__read_mostly={.type=cpu_to_be16(ETH_P_IP),.func=ip_rcv,.gso_send_check=inet_gso_send_check,.gso_segment=inet_gso_segment,.gro_receive=inet_gro_receive,.gro_complete=inet_gro_complete,};3.ip_rcv中做ip的正确性检查后,调用:returnNF_HOOK(NFPROTO_IPV4,NF_INET_PRE_ROUTING,skb,dev,NULL,ip_rcv_finish);3.ip_recv_finish中if(skb_dst(skb)==NULL){interr=ip_route_input_noref(skb,iph-daddr,iph-saddr,iph-tos,skb-dev);}returndst_input(skb);其中ip_route_input_noref是设置skb_dst(skb);而dst_input(skb)是调用skb_dst(skb)-input(skb);三.ip层路由处理.即是设定skb_dst(skb)-input函数的过程。1.ip_route_input_noref调用ip_route_input_common2.intip_route_input_common(structsk_buff*skb,__be32daddr,__be32saddr,u8tos,structnet_device*dev,boolnoref)中如果if(!rt_caching(net))/*路由加速缓冲*/gotoskip_cache;慢速查找路由res=ip_route_input_slow(skb,daddr,saddr,tos,dev);以下是研究的重点了。fl4.flowi4_oif=0;fl4.flowi4_iif=dev-ifindex;fl4.flowi4_mark=skb-mark;fl4.flowi4_tos=tos;fl4.flowi4_scope=RT_SCOPE_UNIVERSE;fl4.daddr=daddr;fl4.saddr=saddr;fib_lookup(net,&fl4,&res);ip_mkroute_input(skb,&res,&fl4,in_dev,daddr,saddr,tos);以上这二个函数,一个是查找,如果找到了就在rt_intern_hash里设定skb_dst(skb)-input好。现在研究数据结构!structflowi41.意义:2.作用:现在看是用来做匹配源的。structfib_result1.意义:fib匹配结果2.作用:保存匹配的fib结果structfib_table{structhlist_nodetb_hlist;u32tb_id;inttb_default;inttb_num_default;unsignedlongtb_data[0];---------------新内核中用的数据结构为structtire的指针};1.意义:fibtable转发信息表2.作用:转发信息结构的总入口3.获取:structfib_tabletable=fib_get_table(net,RT_TABLE_MAIN);structtrie{structrt_trie_node__rcu*trie;};1.意义:字典树2.作用:trie字典树头3.获取:structtrie*t=(structtrie*)tb-tb_data;structrt_trie_node{unsignedlongparent;t_keykey;};1.意义:路由表字典树结点2.作用:路由表字黄树结点,第一个结点是t-trie指针指向3.获取:structrt_trie_noden=rcu_dereference(t-trie);structtnode{unsignedlongparent;t_keykey;unsignedcharpos;/*2log(KEYLENGTH)bitsneeded*/unsignedcharbits;/*2log(KEYLENGTH)bitsneeded*/unsignedintfull_children;/*KEYLENGTHbitsneeded*/unsignedintempty_children;/*KEYLENGTHbitsneeded*/union{structrcu_headrcu;structwork_structwork;structtnode*tnode_free;};structrt_trie_node__rcu*child[0];-------子结点。可由强制t_trie_node转换而来};1.意义:????2.作用:?????3.获取:structtnodepn=(structtnode*)n如何查找字典数1.t_keykey=ntohl(flp-daddr);用主机序目地IP做为KEY2.cindex=tkey_extract_bits(mask_pfx(key,current_prefix_length),pos,bits);根据K计算一个索引值。3.n=tnode_get_child_rcu(pn,cindex);根据索引于child[cindex];4.if(IS_LEAF(n)){//如果是叶子ret=check_leaf(tb,t,(structleaf*)n,key,flp,res,fib_flags);//检查叶子if(ret0)//不成功.回逆gotobacktrace;gotofound;//成功找到}check_leaf(tb,t,(structleaf*)n,key,flp,res,fib_flags);参数:tbfib_get_table(net,RT_TABLE_MAIN);t(structtrie*)tb-tb_data;ntnode_get_child_rcu(pn,cindex);//structrt_trie_node*child[cindex];keyntohl(flp-daddr)学习资源=://blog.chinaunix.net/uid-23629988-id-2010885.html=23629988&do=blog&frmd=5372&classid=5377&view=me
本文标题:linux内核网络子模块学习笔记
链接地址:https://www.777doc.com/doc-5018170 .html