Linux 系統操作 使用 nameif 修改 Linux 網路卡名稱 話說 net-tools::nameif 可以更改網卡的名稱,
例如,以下是在eth1網路卡狀態為 down 的環境情況下處理:
假設 eth1 MAC 為 00:30:48:84:76:07
修改 /etc/mactab
# cat /etc/mactab
abc200 00:30:48:84:76:07
# nameif
# ifconfig -a
發現 eth1 被改成 abc200
這樣可以用來作啥呢?...
引述 OuTian 是這麼用的
--# OuTian::Start #------------------------------------------
ip link set eth0 down (因為在 up 的情況下會噴 resource busy ... )
ip link set eth0 name NEWNAME
ip link set eth0 up
以前管了一台機器接七條 isp 時
通通把網卡 rename 掉 .... hinet seednet sparq ... 都設 isp 名字
才不用每次要 ping/traceroute 時 , 想半天到底 ethx 是哪條線 XD
--# OuTian::END #------------------------------------------
OuTian 兄說得真是不錯的想法,我之前看 linux kernel source code 得知一開始在命名時 eth0
以 eth 是指該裝置為 ethernet 才會以 eth 開頭,而 eth0, 1, 2, ... 則是以偵測到的順序,
而用 nameif 改名稱,對 kernel 內部的改變是如何的?(ex. kernel 中紀錄 Network 裝置的 link-list 是否有什麼改變?)
我檢視程式碼 nameif.c,發現關鍵下列,並順便寫個小程式測試玩玩
---------------------------------------------------------
ioctl(sk, SIOCSIFNAME, &ifr);
// sk = socket(PF_INET, SOCK_DGRAM, 0);
---------------------------------------------------------
Copy #include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <sys/socket.h>
#include <linux/sockios.h>
int main ( void )
{
char * mac = "00:30:48:84:76:07" ;
char * old = "lalala001" ;
char * new = "NBA2000" ;
int sk;
struct ifreq ifr;
sk = socket(PF_INET , SOCK_DGRAM , 0 ) ;
if (sk < 0 )
exit;
memset( & ifr , 0 , sizeof ( struct ifreq)) ;
strcpy( ifr . ifr_name , old) ;
strcpy( ifr . ifr_newname , new) ;
ioctl(sk , SIOCSIFNAME , & ifr) ;
close(sk) ;
return 0 ;
}
下列我追蹤 Linux Kernel (linux-2.6.14.7) 的程式碼:
Copy LinuxKernel::net / core / dev.c
2361
2362 case SIOCSIFNAME:
2363 ifr -> ifr_newname[IFNAMSIZ - 1 ] = '\0' ;
2364 return dev_change_name (dev , ifr -> ifr_newname);
2365
Copy 711 int dev_change_name ( struct net_device * dev ,
char * newname)
712 {
713 int err = 0 ;
714
715 ASSERT_RTNL() ;
716
717 if ( dev -> flags & IFF_UP)
718 return - EBUSY;
719
720 if ( ! dev_valid_name(newname) )
721 return - EINVAL;
722
723 if ( strchr(newname , '%' ) ) {
724 err = dev_alloc_name(dev , newname) ;
也可以用 eth%d 當作新名稱,至於 %d 是多少跟原本取得名稱一樣是給 kernel 計算 我在 /etc/mactab 玩看看,下列是測試結果:
Copy 在 /etc/mactab 填入此行內容:eth%d 00:30:48:84:76:07
執行指令測試
# nameif
# ifconfig -a
# nameif
# ifconfig -a
# nameif
# ifconfig -a
# nameif
# ifconfig -a
上面的指令將可以看到,名字會跳來跳去的,如:eth1, eth2, eth1, eth2 ..
(因為這邊有兩張網路卡,我沒有動 eth0 ,而是動 eth1,所以才會是在 eth1 , eth2 之間跳)
Copy 725 if (err < 0)
726 return err;
727 strcpy(newname, dev->name);
728 }
檢查該裝置(名稱)是否存在
Copy 729 else if (__dev_get_by_name(newname))
730 return -EEXIST;
731 else
732 strlcpy(dev->name, newname, IFNAMSIZ);
733
734 err = class_device_rename(&dev->class_dev, dev->name);
735 if (!err) {
736 hlist_del(&dev->name_hlist);
737 hlist_add_head(&dev->name_hlist,
dev_name_hash(dev->name));
738 notifier_call_chain(&netdev_chain, NETDEV_CHANGENAME,dev);
739 }
740
741 return err;
742 }
743
初步得到的結論是 nameif 直接改了 kernel 裡的裝置名稱,而沒有其他的別名(alias name)。