日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

网络设备的注册与初始化

發(fā)布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 网络设备的注册与初始化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

2019獨角獸企業(yè)重金招聘Python工程師標準>>>

NIC可用之前,其相關(guān)聯(lián)的net_device數(shù)據(jù)結(jié)構(gòu)必須先初始化,添加到內(nèi)核網(wǎng)絡(luò)設(shè)備數(shù)據(jù)庫、配置并開啟。不要把注冊/除名以及開啟/關(guān)閉混淆是十分重要的,這是兩種不同的概念:

  • 如果把加載設(shè)備驅(qū)動程序模塊的動作排除的話,注冊和除名是獨立于用戶之外的,是由內(nèi)核驅(qū)動的。僅僅注冊了的設(shè)備還不能運轉(zhuǎn)。
  • 開啟和關(guān)閉設(shè)備都需要用戶參與。一旦設(shè)備已由內(nèi)核注冊,用戶就可通過用戶命令看到該設(shè)備,配置并予以開啟。

設(shè)備注冊之時

加載NIC設(shè)備驅(qū)動程序

如果NIC設(shè)備驅(qū)動程序內(nèi)建至內(nèi)核中,則在引導期間初始化;否則,如果以模塊加載,就會在運行期間初始化;否則,如果以模塊加載,就會在運行期間初始化。每當發(fā)生初始化時,該驅(qū)動程序所控制的所有NIC都會被注冊。

插入可熱插拔網(wǎng)絡(luò)設(shè)備

當用戶把可熱插拔NIC設(shè)備插入進來時,內(nèi)核會通知其驅(qū)動程序,而驅(qū)動程序在注冊該設(shè)備。

設(shè)備除名之時

卸載NIC設(shè)備驅(qū)動程序

這僅是針對那些以模塊加載的驅(qū)動程序,不適合那些內(nèi)建至內(nèi)核的驅(qū)動程序。當管理員卸載NIC設(shè)備驅(qū)動程序時,所有相關(guān)聯(lián)的NIC都必須除名。

刪除可熱插拔網(wǎng)絡(luò)設(shè)備

當用戶從系統(tǒng)(其運行的內(nèi)核支持可熱插拔設(shè)備)刪除可熱插拔NIC時,則網(wǎng)絡(luò)設(shè)備就會被除名。

設(shè)備注冊狀態(tài)通知

內(nèi)核組件和用戶空間應(yīng)用程序可能都想知道何時發(fā)生網(wǎng)絡(luò)設(shè)備注冊、除名、關(guān)閉或者開啟之事。這類事件的通知是通過兩種通道傳送的:

netdev_chain,內(nèi)核組件可以注冊此通知鏈。設(shè)備的注冊和除名在各個階段的進展都是通過netdev_chain通知鏈報告的。此鏈定義在net/core/dev.c中,而對此類事件感興趣的內(nèi)核組件可以通過register_netdevice_notifier和unregister_netdevice_notifier分別對該鏈注冊或除名。

netdev_chain報告的事件:

NETDEV_UP,NETDEV_GOING_DOWN,NETDEV_DOWN,送出NETDEV_UP以報告設(shè)備已開啟,而且此事件是由dev_open產(chǎn)生。當設(shè)備要關(guān)閉時,就會送出NETDEV_GOING_DOWN.當設(shè)備已關(guān)閉時,就會送出NETDEV_DOWN.這些事件都是由dev_close()產(chǎn)生的。

NETDEV_REGISTER設(shè)備已注冊,此事件是有register_netdevice產(chǎn)生的。

NETDEV_UNREGISTER,設(shè)備已經(jīng)除名,此事件是由unregister_netdevice產(chǎn)生的。

NETDEV_CHANGEADDR設(shè)備的硬件地址已改變。

NETDEV_CHANGENAME設(shè)備已改變其名稱

NETDEV_CHANGE設(shè)備的狀態(tài)或配置已經(jīng)改變,此事件會用在上述情況未包括的其他情況下。

注意,向鏈注冊時,register_netdevice_notifier也會(僅對新注冊者)重放當前系統(tǒng)已注冊設(shè)備的所有過去的NETDEV_REGISTER和NETDEV_UP通知信息。這樣就能給新注冊者有關(guān)已注冊設(shè)備的清晰圖像。內(nèi)核注冊該鏈的子系統(tǒng):路由,使用此通知信息新增或刪除與此設(shè)備相關(guān)聯(lián)的所有路由項目;協(xié)議代碼,當改變一個本地設(shè)備的MAC地址時,ARP表也必須據(jù)此更新。RTnetlink。

Netlink的RTMGRP_LINK多播群組,用戶空間程序可以注冊netlink的RTMGRP_LINK多播群組,當設(shè)備的狀態(tài)或配置中有變更時,就會用rtmsg_ifinfo把通知信息傳送給Link多播群組RTMGRP_LINK,其中一些通知信息如下:

  • 當netdev_chain通知鏈收到一個通知信息時,RTnetlink會注冊前一節(jié)所提及的netdev_chain,然后重放其接受到的通知信息。
  • 當一個已關(guān)閉的設(shè)備開啟時或者處于相反的過程。
  • 當net_device->flags中的一個標識有變動時。

netplugd是守護進程,會監(jiān)聽這些通知信息,然后根據(jù)用戶配置文件而反應(yīng)。

函數(shù)netdev_wait_allrefs

netdev_wait_allrefs由一個循環(huán)組成,只有當dev->refcnt建至零時才會結(jié)束。此函數(shù)每秒都會發(fā)送出一個NETDEV_UNREGISTER通知信息,而沒10秒都會在控制臺上打印出一條警告信息。剩余時間都在休眠。此函數(shù)直到對輸入net_device結(jié)構(gòu)的所有引用都已釋放為止。有兩種常見情況需要傳送一個以上的通知信息:

bug,例如有段代碼持有對net_device結(jié)構(gòu)的引用,但是因為沒有在netdev_chain通知鏈注冊,或因為沒有正確處理通知信息,使其無法釋放。

未決的定時器,例如,假設(shè)當定時器到期時要執(zhí)行的那個函數(shù)必須訪問的數(shù)據(jù)中,包含了對net_device結(jié)構(gòu)的引用。在這種情況下,你必須等待直到該定時器到期,而且其處理函數(shù)有望會釋放其引用。

1: /* 2: * netdev_wait_allrefs - wait until all references are gone. 3: * 4: * This is called when unregistering network devices. 5: * 6: * Any protocol or device that holds a reference should register 7: * for netdevice notification, and cleanup and put back the 8: * reference if they receive an UNREGISTER event. 9: * We can get stuck here if buggy protocols don't correctly 10: * call dev_put. 11: */ 12: static void netdev_wait_allrefs(struct net_device *dev) 13: { 14: unsigned long rebroadcast_time, warning_time; 15: int refcnt; 16: ? 17: linkwatch_forget_dev(dev); 18: ? 19: rebroadcast_time = warning_time = jiffies; 20: refcnt = netdev_refcnt_read(dev); 21: ? 22: while (refcnt != 0) { 23: if (time_after(jiffies, rebroadcast_time + 1 * HZ)) { 24: rtnl_lock(); 25: ? 26: /* Rebroadcast unregister notification */ 27: call_netdevice_notifiers(NETDEV_UNREGISTER, dev); 28: /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users 29: * should have already handle it the first time */ 30: ? 31: if (test_bit(__LINK_STATE_LINKWATCH_PENDING, 32: &dev->state)) { 33: /* We must not have linkwatch events 34: * pending on unregister. If this 35: * happens, we simply run the queue 36: * unscheduled, resulting in a noop 37: * for this device. 38: */ 39: linkwatch_run_queue(); 40: } 41: ? 42: __rtnl_unlock(); 43: ? 44: rebroadcast_time = jiffies; 45: } 46: ? 47: msleep(250); 48: ? 49: refcnt = netdev_refcnt_read(dev); 50: ? 51: if (time_after(jiffies, warning_time + 10 * HZ)) { 52: printk(KERN_EMERG "unregister_netdevice: " 53: "waiting for %s to become free. Usage " 54: "count = %d\n", 55: dev->name, refcnt); 56: warning_time = jiffies; 57: } 58: } 59: }

開啟和關(guān)閉網(wǎng)絡(luò)設(shè)備

設(shè)備一旦注冊就可用,但是,除非用戶明確的開啟,否則還是無法傳輸和接收數(shù)據(jù)流。開始設(shè)備函數(shù)為dev_open

  • 如果有定義的話,調(diào)用dev->open。并非所有設(shè)備驅(qū)動程序都初始化此函數(shù)
  • 設(shè)置dev->state中的__LINK_STATE_START標識,把設(shè)備標識為開啟和運行中。
  • 設(shè)置dev->flags中的IFF_UP標識,把設(shè)備標識為開啟。
  • 調(diào)用dev_activate以初始化由流量控制使用的出口隊列規(guī)則,然后啟動看門狗定時器。如果流量控制沒有用戶配置,就指定默認的FIFO
  • 傳送NETDEV_UP通知信息給netdev_chain通知鏈,以通知感興趣的內(nèi)核組件,該設(shè)備現(xiàn)已開啟。

設(shè)備關(guān)閉

  • 傳送NETDEV_GOING_DOWN通知信息給netdev_chain通知鏈,以通知感興趣的內(nèi)核組件該設(shè)備即將被關(guān)閉
  • 調(diào)用dev_deactivate以關(guān)閉出口隊列規(guī)則,使得該設(shè)備再也無法用于傳輸,然后因為不在需要,停止看門狗定時器
  • 清除dev->state中的__LINK_STATE_START標識,把設(shè)備標識為關(guān)閉
  • 如果一個輪詢動作被調(diào)度,以讀取設(shè)備上的入口封包,就要等待該動作完成。因為__LINK_STATE_START標識已被清除,該設(shè)備上已不能再為其他接收的輪詢動作進行調(diào)度了,但是在該標志清除前可能有一個輪詢動作未決。
  • 如果有定義,調(diào)用dev->stop。
  • 清除dev->flags中的IFF_UP標識,把設(shè)備標識為關(guān)閉
  • 傳送NETDEV_DOWN通知鏈

鏈接狀態(tài)變更偵測

可能導致鏈接狀態(tài)變更的一些情況:

1,電纜線插入NIC,或者從NIC中拔出。

2. 電纜線另一端的設(shè)備電源關(guān)掉或關(guān)閉了。這類設(shè)備有HUB,橋接器,路由器以及PC NIC等

轉(zhuǎn)載于:https://my.oschina.net/longscu/blog/57354

總結(jié)

以上是生活随笔為你收集整理的网络设备的注册与初始化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。