TCP协议发送SKB时ip_summed成员的设置 http://blog.csdn.net/justlinux2010/article/details/8508455
生活随笔
收集整理的這篇文章主要介紹了
TCP协议发送SKB时ip_summed成员的设置 http://blog.csdn.net/justlinux2010/article/details/8508455
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
? /*?This?routine?computes?an?IPv4?TCP?checksum.?*/?? void?tcp_v4_send_check(struct?sock?*sk,?int?len,?struct?sk_buff?*skb)?? {?? ????struct?inet_sock?*inet?=?inet_sk(sk);?? ????struct?tcphdr?*th?=?tcp_hdr(skb);?? ?? ????if?(skb->ip_summed?==?CHECKSUM_PARTIAL)?{?? ????????th->check?=?~tcp_v4_check(len,?inet->saddr,?? ?????????????????????inet->daddr,?0);?? ????????skb->csum_start?=?skb_transport_header(skb)?-?skb->head;?? ????????skb->csum_offset?=?offsetof(struct?tcphdr,?check);?? ????}?else?{?? ????????th->check?=?tcp_v4_check(len,?inet->saddr,?inet->daddr,?? ?????????????????????csum_partial(th,?? ?????????????????????????th->doff?<<?2,?? ?????????????????????????skb->csum));?? ????}?? }?? 在這個函數中可以看到第7行中已經開始使用skb->ip_summed來做比較,那也就是說skb->ip_summed肯定在之前已經初始化過,反反復復地仔細閱讀tcp_send_ack和tcp_transmit_skb函數都沒有發現初始化的地方,真的是很奇怪。因為之前我看過alloc_skb的實現,而且又看了一次,沒看到在哪個地方“明顯地”初始化了ip_summed成員。 只能全文搜索ip_summed的所有設置的地方,看了半天還是沒有找到在tcp_send_ack到tcp_transmit_skb之間的地方有初始化ip_summed的操作,最后還是把目光鎖定在alloc_skb函數上??戳藥妆橹笸蝗豢吹揭痪洳黄鹧鄣拇a: [cpp]?view plaincopy /*? ?????*?Only?clear?those?fields?we?need?to?clear,?not?those?that?we?will? ?????*?actually?initialise?below.?Hence,?don't?put?any?more?fields?after? ?????*?the?tail?pointer?in?struct?? ?????*/?? ????memset(skb,?0,?offsetof(struct?sk_buff,?tail));?? ????skb->truesize?=?size?+?sizeof(struct?sk_buff);?? ????atomic_set(&skb->users,?1);?? 看到第6行代碼,才恍然大悟,原來是在這個地方把skb從head成員到tail的所有成員都初始化為0,當前ip_summed也在這個范圍內,也就是說ip_summed的值為0,對應的就是CHECKSUM_NONE。哎,只怪自己粗心大意,看的不夠仔細!
tcp_v4_send_check中第7行if?(skb->ip_summed?==?CHECKSUM_PARTIAL),判斷ip_summed是否等于CHECKSUM_PARTIAL,那在什么是否會將ip_summed置為CHECKSUM_PARTIAL呢?這個答案要在tcp_sendmsg中找,代碼片段如下: [cpp]?view plaincopy /*? ?????????????????*?Check?whether?we?can?use?HW?checksum.? ?????????????????*/?? ????????????????if?(sk->sk_route_caps?&?NETIF_F_ALL_CSUM)?? ????????????????????skb->ip_summed?=?CHECKSUM_PARTIAL;??
也就是說如果目的路由網絡設備的特性支持NETIF_F_ALL_CSUM時,才將ip_summed設置為CHECKSUM_PARTIAL。 當然這里的討論只限于TCP協議發送SKB包,到計算校驗和的過程中ip_summed成員的變化和值。
TCP協議發送SKB時ip_summed成員的設置
分類:?Linux內核2013-01-16 10:57?1457人閱讀?評論(0)?收藏?舉報 ?tcp_send_ack()函數是內核用來發送ACK的函數,該函數比較簡單,就是先分配一個SKB包,然后簡單的初始化(初始化操作中沒有設置ip_summed)后,調用tcp_transmit_skb()來將SKB包傳遞到IP層。tcp_transmit_skb中先做一些操作后(仔細看過,到計算校驗和之前,沒有更改過ip_summed),會調用tcp_v4_send_check(語句是:icsk->icsk_af_ops->send_check(sk, skb->len, skb);)來計算校驗和。 ?tcp_v4_send_check代碼如下: [cpp]?view plaincopytcp_v4_send_check中第7行if?(skb->ip_summed?==?CHECKSUM_PARTIAL),判斷ip_summed是否等于CHECKSUM_PARTIAL,那在什么是否會將ip_summed置為CHECKSUM_PARTIAL呢?這個答案要在tcp_sendmsg中找,代碼片段如下: [cpp]?view plaincopy
也就是說如果目的路由網絡設備的特性支持NETIF_F_ALL_CSUM時,才將ip_summed設置為CHECKSUM_PARTIAL。 當然這里的討論只限于TCP協議發送SKB包,到計算校驗和的過程中ip_summed成員的變化和值。
版權聲明:本文為博主原創文章,未經博主允許不得轉載。
總結
以上是生活随笔為你收集整理的TCP协议发送SKB时ip_summed成员的设置 http://blog.csdn.net/justlinux2010/article/details/8508455的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《事实》读书笔记
- 下一篇: 全球及中国多晶硅产业竞争态势及发展前景研