<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ## 17.14.?多播 一個多播報文是一個會被多個主機接收的網絡報文, 但不是所有主機. 這個功能通過給一組主機分配特殊的硬件地址來獲得. 發向一個特殊地址的報文應當被那個組當中的所有主機接收. 在以太網的情況下, 一個多播地址在目的地址的第一個字節的最低位為 1, 而每個設備板在它自己的硬件地址的這一位上為 0. 處理主機組和硬件地址的技巧由應用程序和內核處理, 接口驅動不必處理這個問題. 多播報文的傳送是一個簡單問題, 因為它們看起來就如同其他的報文. 接口發送它們通過通訊媒介, 不查看目的地址. 內核必須要安排一個正確的硬件目的地址; hard_header 設備方法, 如果定義了, 不必查看它安排的數據. 內核來跟蹤在任何給定時間對哪些多播地址感興趣. 這個列表可能經常改變, 因為它是在任何給定時間和按照用戶意愿運行的應用程序的功能. 驅動的工作是接收感興趣的多播地址列表并遞交給內核任何發向這些地址的報文. 驅動如何實現多播列表是依賴于底層硬件是如何工作的. 典型地, 在多播的角度上, 硬件屬于 3 類中的 1 種: - 不能處理多播的接口. 這樣的接口要么接收特別地發向它們的硬件地址(加上廣播報文)的報文, 要么接收每一個報文. 它們只能通過接收每一個報文來接收多播報文, 因此, 潛在地壓垮操作系統, 使用大量的"不感興趣"報文. 你不經常認為這樣的接口是有多播能力的, 驅動不會在 dev->flags 設置 IFF_MULTICAST. 點對點接口是特殊情況, 因為它們一直接收每個報文, 不進行任何硬件過濾. - 能夠區別多播報文和其他報文(主機到主機, 或者廣播). 這些接口能夠被命令來接收每個多播報文, 讓軟件決定地址是否是主機感興趣的. 這種情況下的開銷是可接受的, 因為在一個典型網絡上的多播報文的數目是少的. - 可以進行硬件檢測多播地址的接口. 可以傳遞一個多播地址的列表給這些接口, 這些地址的報文接收, 并忽略其他多播地址的報文. 對內核這是優化的情況, 因為它不浪費處理器時間來丟棄接口收到的"不感興趣"的報文. 內核盡力利用高級接口的能力, 通過支持第 3 種設備類型, 它是最通用的. 因此, 內核通知驅動, 在任何有效多播地址列表發生改變時, 并且它傳遞新的列表給驅動, 因此它能夠根據新的信息來更新硬件過濾器. ### 17.14.1.?多播的內核支持 對多播報文的支持有幾項組成:一個設備方法, 一個數據結構, 以及設備標識: void (*dev->set_multicast_list)(struct net_device *dev); 設備方法, 在與設備相關的機器地址改變時調用. 它也在 dev->flags 被修改時調用, 因為一些標志(例如, IFF_PROMISC) 可能也要求你重新編程硬件過濾器. 這個方法接收一個 struct net_device 指針作為一個參數, 并返回 void. 一個對實現這個方法不感興趣的驅動可以聽任它為 NULL. struct dev_mc_list *dev->mc_list; 所有設備相關的多播地址的列表. 這個結構的實際定義在本節的末尾介紹. int dev->mc_count; 鏈表里的項數. 這個信息有些重復, 但是用 0 來檢查 mc_count 是檢查這個列表的有用的方法. IFF_MULTICAST 除非驅動在 dev->flags 中設置這個標志, 接口不會被要求來處理多播報文. 然而, 內核調用驅動的 set_multicast_list 方法, 當 dev->flags 改變時, 因為多播列表可能在接口未激活時改變了. IFF_ALLMULTI 在 dev->flags 中設置的標志, 網絡軟件來告知驅動從網絡上接收所有多播報文. 這發生在當多播路由激活時. 如果標志設置了, dev->ma_list 不該用來過濾多播報文. IFF_PROMISC 在 dev->flags 中設置的標志, 當接口在混雜模式下. 接口應當接收每個報文, 不管 dev->ma_list. 驅動開發者需要的最后一點信息是 struct dev_mc_list 的定義, 在 <linux/netdevice.h>: ~~~ struct dev_mc_list { struct dev_mc_list *next; /* Next address in list */ __u8 dmi_addr[MAX_ADDR_LEN]; /* Hardware address */ unsigned char dmi_addrlen; /* Address length */ int dmi_users; /* Number of users */ int dmi_gusers; /* Number of groups */ }; ~~~ 因為多播和硬件地址是獨立于真正的報文發送, 這個結構在網絡實現中是可移植的, 每個地址由一個字符串和一個長度標識, 就像 dev->dev_addr. ### 17.14.2.?典型實現 描述 set_multicast_list 的設計的最好方法是給你看一些偽碼. 下面的函數是一個典型函數實現在一個全特性(ff)驅動中. 這個驅動是全模式的, 它控制的接口有一個復雜的硬件報文過濾器, 它能夠持有一個主機要接收的多播地址表. 表的最大尺寸是 FF_TABLE_SIZE. 所有以 ff_ 前綴的函數是給特定硬件操作的占位者: ~~~ void ff_set_multicast_list(struct net_device *dev) { struct dev_mc_list *mcptr; if (dev->flags & IFF_PROMISC) { ff_get_all_packets(); return; } /* If there's more addresses than we handle, get all multicast packets and sort them out in software. */ if (dev->flags & IFF_ALLMULTI || dev->mc_count > FF_TABLE_SIZE) { ff_get_all_multicast_packets(); return; } /* No multicast? Just get our own stuff */ if (dev->mc_count == 0) { ff_get_only_own_packets(); return; } /* Store all of the multicast addresses in the hardware filter */ ff_clear_mc_list(); for (mc_ptr = dev->mc_list; mc_ptr; mc_ptr = mc_ptr->next) ff_store_mc_address(mc_ptr->dmi_addr); ff_get_packets_in_multicast_list(); } ~~~ 這個實現可以簡化, 如果接口不能為進入報文存儲多播表在硬件過濾器中. 這種情況下, FF_TABLE_SIZE 減為 0, 并且代碼的最后 4 行不需要了. 如同前面提過的, 不能處理多播報文的接口不需要實現 set_multicast_list 方法來獲取 dev->flags 改變的通知. 這個辦法可能被稱為一個"非特性的"(nf)實現. 實現非常簡單, 如下面代碼所示: ~~~ void nf_set_multicast_list(struct net_device *dev) { if (dev->flags & IFF_PROMISC) nf_get_all_packets(); else nf_get_only_own_packets(); } ~~~ 實現 IFF_PROMISC 是非常重要的, 因為不這樣用戶就不能運行 tcpdump 或任何其他網絡分析器. 如果接口運行一個點對點連接, 另一方面, 根本沒有必要實現 set_multicast_list, 因為用戶接收每個報文.
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看