免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Linux內(nèi)核實踐 - 如何添加網(wǎng)絡(luò)協(xié)議[三]:實現(xiàn)

內(nèi)核版本:2.6.34
接上篇《添加網(wǎng)絡(luò)協(xié)議》。
        為了用戶方便查看brcm設(shè)備的工作狀態(tài),使用proc文件系統(tǒng)是很好的方式。一個網(wǎng)絡(luò)協(xié)議模塊可以注冊到網(wǎng)絡(luò)空間中register_pernet_subsys(),這個函數(shù)會為子空間分配一個id號,通過id可以在網(wǎng)絡(luò)空間中找到分配給該子空間的內(nèi)存:init_net->gen->ptr[id - 1]。而我們正是利用這塊內(nèi)存去存儲proc中的相關(guān)信息:struct brcm_net,它記錄了brcm設(shè)備在proc文件系統(tǒng)中的位置。

  1. struct brcm_net {  
  2.     /* /proc/net/brcm */  
  3.     struct proc_dir_entry *proc_brcm_dir;  
  4.     /* /proc/net/brcm/config */  
  5.     struct proc_dir_entry *proc_brcm_conf;  
  6. };  

        在加載brcm模塊時會注冊子空間,brcm_init_net創(chuàng)建在proc中的相關(guān)項,并記錄路徑在brcm_net中;brcm_exit_net刪除在proc中的相關(guān)項;brcm_net_id記錄分配給子空間的id,這樣通過init_net->gen->ptr[brcm_net_id - 1]就可以操作brcm_net了。

  1. err = register_pernet_subsys(&brcm_net_ops);  
  2. static struct pernet_operations brcm_net_ops = {  
  3.     .init = brcm_init_net,  
  4.     .exit = brcm_exit_net,  
  5.     .id = &brcm_net_id,  
  6.     .size = sizeof(struct brcm_net),  
  7. };  

        注意到在brcm_init_net和brcm_exit_net中添加和刪除的僅僅是/proc/net/brcm目錄和config文件,而在使用中brcm設(shè)備是可以動態(tài)創(chuàng)建的,因此這部分代碼應(yīng)該發(fā)生在添加和刪除brcm設(shè)備時,而不是在brcm模塊注冊和刪除時。最簡單的是直接添加在register方法或unregister方法中,但內(nèi)核提供了更好的機(jī)制:事件,將對proc的操作分離出來,因為proc的操作實際上屬于附加的操作而不是必須的操作。下面就來看event機(jī)制。
        前面幾篇已經(jīng)有描述過event機(jī)制,這里的事件都是關(guān)于設(shè)備的事件,使用的是register_netdevice_notifier()來,注冊notifier到netdev_chain鏈表上。在加載brcm模塊時注冊notifier,brcm_notifier_block包含了brcm設(shè)備對所關(guān)心的事件作出的反應(yīng)。

  1. err = register_netdevice_notifier(&brcm_notifier_block);  
  2. static struct notifier_block brcm_notifier_block __read_mostly = {  
  3.     .notifier_call = brcm_device_event,  
  4. };  

        設(shè)備對哪些事件會感興趣,首先,brcm設(shè)備對注冊和注銷是感興趣的,要操作proc文件系統(tǒng);其次,對于發(fā)往brcm下層設(shè)備的事件,要考慮這些事件造成的連帶影響(比如eth1被down掉,則其上的brcm設(shè)備也應(yīng)該被down掉),一般是下層設(shè)備的事件對其上的所有brcm設(shè)備都進(jìn)行相應(yīng)操作。
        所以在brcm_device_event有兩類進(jìn)入的設(shè)備dev會進(jìn)行操作,一類是brcm設(shè)備,它僅僅是操作proc文件系統(tǒng)。判斷是否為brcm設(shè)備,是的話則由__brcm_device_event() 處理。 

  1. if (is_brcm_dev(dev))  
  2.     __brcm_device_event(dev, event);  
  3.   
  4. static void __brcm_device_event(struct net_device *dev, unsigned long event)  
  5. {  
  6.     switch (event) {  
  7.     case NETDEV_CHANGENAME:  
  8.         brcm_proc_rem_dev(dev);  
  9.         if (brcm_proc_add_dev(dev) < 0)  
  10.             pr_warning("BRCM: failed to change proc name for %s\n",  
  11.                     dev->name);  
  12.         break;  
  13.     case NETDEV_REGISTER:  
  14.         if (brcm_proc_add_dev(dev) < 0)  
  15.             pr_warning("BRCM: failed to add proc entry for %s\n",  
  16.                     dev->name);  
  17.         break;  
  18.     case NETDEV_UNREGISTER:  
  19.         brcm_proc_rem_dev(dev);  
  20.         break;  
  21.     }  
  22. }  

        如何是brcm的下層設(shè)備,如根據(jù)brcm_group_hash中的映射關(guān)系,對下層設(shè)備相關(guān)的所有brcm設(shè)備進(jìn)行操作:

  1. switch (event) {  
  2. case NETDEV_CHANGE:  
  3.     /* Propagate real device state to vlan devices */  
  4.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  5.         brcmdev = brcm_group_get_device(grp, i);  
  6.         if (!brcmdev)  
  7.             continue;  
  8.   
  9.         netif_stacked_transfer_operstate(dev, brcmdev);  
  10.     }  
  11.     break;  
  12.   
  13. case NETDEV_CHANGEADDR:  
  14.     /* Adjust unicast filters on underlying device */  
  15.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  16.         brcmdev = brcm_group_get_device(grp, i);  
  17.         if (!brcmdev)  
  18.             continue;  
  19.   
  20.         flgs = brcmdev->flags;  
  21.         if (!(flgs & IFF_UP))  
  22.             continue;  
  23.   
  24.         brcm_sync_address(dev, brcmdev);  
  25.     }  
  26.     break;  
  27.   
  28. case NETDEV_CHANGEMTU:  
  29.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  30.         brcmdev = brcm_group_get_device(grp, i);  
  31.         if (!brcmdev)  
  32.             continue;  
  33.   
  34.         if (brcmdev->mtu <= dev->mtu)  
  35.             continue;  
  36.   
  37.         dev_set_mtu(brcmdev, dev->mtu);  
  38.     }  
  39.     break;  
  40.   
  41. case NETDEV_DOWN:  
  42.     /* Put all VLANs for this dev in the down state too.  */  
  43.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  44.         brcmdev = brcm_group_get_device(grp, i);  
  45.         if (!brcmdev)  
  46.             continue;  
  47.   
  48.         flgs = brcmdev->flags;  
  49.         if (!(flgs & IFF_UP))  
  50.             continue;  
  51.   
  52.         brcm = brcm_dev_info(brcmdev);  
  53.         dev_change_flags(brcmdev, flgs & ~IFF_UP);  
  54.         netif_stacked_transfer_operstate(dev, brcmdev);  
  55.     }  
  56.     break;  
  57.   
  58. case NETDEV_UP:  
  59.     /* Put all VLANs for this dev in the up state too.  */  
  60.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  61.         brcmdev = brcm_group_get_device(grp, i);  
  62.         if (!brcmdev)  
  63.             continue;  
  64.   
  65.         flgs = brcmdev->flags;  
  66.         if (flgs & IFF_UP)  
  67.             continue;  
  68.   
  69.         brcm = brcm_dev_info(brcmdev);  
  70.         dev_change_flags(brcmdev, flgs | IFF_UP);  
  71.         netif_stacked_transfer_operstate(dev, brcmdev);  
  72.     }  
  73.     break;  
  74.   
  75. case NETDEV_UNREGISTER:  
  76.     /* Delete all BRCMs for this dev. */  
  77.     grp->killall = 1;  
  78.   
  79.     for (i = 0; i < BRCM_GROUP_ARRAY_LEN; i++) {  
  80.         brcmdev = brcm_group_get_device(grp, i);  
  81.         if (!brcmdev)  
  82.             continue;  
  83.   
  84.         /* unregistration of last brcm destroys group, abort 
  85.          * afterwards */  
  86.         if (grp->nr_ports == 1)  
  87.             i = BRCM_GROUP_ARRAY_LEN;  
  88.   
  89.         unregister_brcm_dev(brcmdev, &list);  
  90.     }  
  91.     unregister_netdevice_many(&list);  
  92.     break;  
  93. }  

        到這里,協(xié)議的添加就大致完成了,當(dāng)然還包括一些頭文件的修改,宏變量的添加等就不一一詳述,具體可見最后的附件。
        為了編譯進(jìn)內(nèi)核,還需要修改以下文件:
              $(linux)/net/Kconfig  $(linux)/net/Makefile

        最后,在make menuconfig選擇添加brcm協(xié)議
              Networking Support -> Networking options     
  

        同時,需要一個簡單的用戶空間工具來配置我們的brcm設(shè)備,就像vconfig用來配置vlan設(shè)備一樣;編寫的簡單的bconfig工具,命令格式:
                "Usage: add [interface-name] [brcm_port]\n"
                "       rem [dev-name]";

        內(nèi)核編譯完成后就該進(jìn)行測試了,如果開啟了內(nèi)核調(diào)試信息,啟動內(nèi)核就看到以下信息: 

        然后啟用網(wǎng)卡,可以查看到添加了brcm設(shè)備后的狀態(tài): 

        可以使用原生套接字自己打上brcm頭后發(fā)送報文讓協(xié)議棧接收,或者用wireshark等捕獲協(xié)議棧發(fā)出的報文,下圖即是捕獲到的報文: 

        這是主機(jī)發(fā)出的arp報文,可以看到,在源mac后接的不是vlan報頭,而是我們添加的brcm報文,協(xié)議號是8744。
        查看proc中信息:
 

        :patch補丁 && 重要的源文件 && bconfig工具源碼

              http://download.csdn.net/source/3548117

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
TCP/IP協(xié)議棧初始化流程
Linux內(nèi)核網(wǎng)絡(luò)協(xié)議棧筆記
剖析Linux網(wǎng)絡(luò)包接收過程:掌握數(shù)據(jù)如何被捕獲和分發(fā)的全過程
Linux時間系統(tǒng)之RTC時間
一步步設(shè)計自己的驅(qū)動程序
Essayteam>>Linux驅(qū)動程序開發(fā)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服