# 使用 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 是這麼用的\ <br>

> \--# 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);\
\---------------------------------------------------------<br>

> ```c
> #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) 的程式碼： \ <br>

> ```c
> 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
> ```

<br>

> ```c
> 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 玩看看，下列是測試結果：\ <br>

> ```
> 在 /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 之間跳) \ <br>

> ```
> 725 if (err < 0)
> 726     return err;
> 727     strcpy(newname, dev->name);
> 728 }
> ```

\
檢查該裝置(名稱)是否存在 \ <br>

> ```
> 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）。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://applezulab.netdpi.net/02-linux-xi-tong-cao-zuo/set-nic-name-with-nameif.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
