歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux綜合 >> Linux內核

Linux內核分析 - 網絡[五]:vlan協議-802.1q

內核版本:2.6.34

802.1q

1. 注冊vlan網絡系統子空間,

 
  1. err = register_pernet_subsys(&vlan_net_ops);  
  2. static struct pernet_operations vlan_net_ops = {  
  3.  .init = vlan_init_net,  
  4.  .exit = vlan_exit_net,  
  5.  .id   = &vlan_net_id,  
  6.  .size = sizeof(struct vlan_net),  
  7. };  

        每個子空間注冊成功都會分配一個ID,在register_pernet_subsys() -> register_pernet_operations() -> ida_get_new_above()獲得,而vlan_net_ops中的vlan_net_id記錄了這個ID。注冊子空間的最後會調用子空間的初始化函數vlan_init_net(),它會把vlan_net(有關vlan的proc文件系統信息)加到全局的net->gen->ptr數組中去,下標為之前分配的ID。這樣,通過vlan_net_id便可隨時查到vlan_net的信息,主要與proc有關。

2. 注冊vlan_notifier_block

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

        關於register_netdevice_notifier()做的工作並不復雜,首先會注冊vlan_notifier_block到netdev_chain:

  1. err = raw_notifier_chain_register(&netdev_chain, nb);  

        然後通知事件NETDEV_REGISTER和NETDEV_UP事件到網絡系統的中的每個設備:

 
  1. for_each_net(net) {  
  2.  for_each_netdev(net, dev) {  
  3.   err = nb->notifier_call(nb, NETDEV_REGISTER, dev);  
  4.   err = notifier_to_errno(err);  
  5.   if (err)  
  6.    goto rollback;  
  7.   
  8.   if (!(dev->flags & IFF_UP))  
  9.    continue;  
  10.   
  11.   nb->notifier_call(nb, NETDEV_UP, dev);  
  12.  }  
  13. }  

        此時nb就是vlan_notifier_block,調用通知函數vlan_device_event()。假設此時主機上擁有設備lo[環回接口], eth1[網卡], eth1.1[虛擬接口],來看vlan_device_event()函數:
         判斷是否為vlan虛擬接口,則執行__vlan_device_event(),這個函數的作用就是在proc文件系統中添加或刪除vlan虛擬設備的相應項。顯然,符合條件的是eth1.1,而事件NETDEV_REGISTER會在/proc/net目錄下創建eth1.1的文件。

  1. if (is_vlan_dev(dev))  
  2.  __vlan_device_event(dev, event);  

        然後判斷dev是否在vlan_group_hash表中[參考最後”vlan設備組織結構”],它以dev->ifindex為hash值,顯然,只有eth1才有正確的ifindex,lo和eth1.1會因查詢失敗而退出vlan_device_event。

  1. grp = __vlan_find_group(dev);  
  2. if (!grp)  
  3.  goto out;  
Copyright © Linux教程網 All Rights Reserved