jinxinxin163 发表于 2014-11-18 19:11

linux下网卡名字eth0 eth1保存在哪里?

以前一直认为ifconfig看到的eth0、eth1这些值是在网卡驱动中的struct net_device 结构体的 char name;中保存的
驱动中指定net_device 的name为eth0,那么ifconfig看到的就是eth0

今天看到在/etc/udev/rules.d下的70-persistent-net.rules下有这么一条规则可以设定网卡的名字:

SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="3c:97:0e:c2:fc:f1", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"

难道这条语句还会通过netlink把eth0这个名字传给内核,然后修改net_device结构体中的name成员么?
假如是这样,那么是怎么做到的?

Tinnal 发表于 2014-11-18 23:48

回复 1# jinxinxin163


除了udev外,你可以看看ifrename,这是改网卡名字的独立程序。对应的源码可以看下面的网站(不是官网):
http://sourceforge.net/mirror/android-wifi-tether/code/434/tree/tools/wireless-tools/ifrename.c#l582

当然也可以自己写程序:
http://linux.die.net/man/7/netdevice

其中SIOCSIFNAME就是用来改名字的。
Changes the name of the interface specified in ifr_name to ifr_newname. This is a privileged operation. It is only allowed when the interface is not up.

Tinnal 发表于 2014-11-18 23:51

对应的内核源码为:/**
*        dev_change_name - change name of a device
*        @dev: device
*        @newname: name (or format string) must be at least IFNAMSIZ
*
*        Change name of a device, can pass format strings "eth%d".
*        for wildcarding.
*/
int dev_change_name(struct net_device *dev, char *newname)
{
        char oldname;
        int err = 0;
        int ret;
        struct net *net;

        ASSERT_RTNL();
        BUG_ON(!dev->nd_net);

        net = dev->nd_net;
        if (dev->flags & IFF_UP)
                return -EBUSY;

        if (!dev_valid_name(newname))
                return -EINVAL;

        if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
                return 0;

        memcpy(oldname, dev->name, IFNAMSIZ);

        if (strchr(newname, '%')) {
                err = dev_alloc_name(dev, newname);
                if (err < 0)
                        return err;
                strcpy(newname, dev->name);
        }
        else if (__dev_get_by_name(net, newname))
                return -EEXIST;
        else
                strlcpy(dev->name, newname, IFNAMSIZ);

rollback:
        device_rename(&dev->dev, dev->name);

        write_lock_bh(&dev_base_lock);
        hlist_del(&dev->name_hlist);
        hlist_add_head(&dev->name_hlist, dev_name_hash(net, dev->name));
        write_unlock_bh(&dev_base_lock);

        ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
        ret = notifier_to_errno(ret);

        if (ret) {
                if (err) {
                        printk(KERN_ERR
                             "%s: name change rollback failed: %d.\n",
                             dev->name, ret);
                } else {
                        err = ret;
                        memcpy(dev->name, oldname, IFNAMSIZ);
                        goto rollback;
                }
        }

        return err;
}

jinxinxin163 发表于 2014-11-24 20:04

谢谢回复啊,你的意思是udev会调用ioctl来改变网卡的名字?

但是“udev调用ioctl来改变网卡的名字”是在哪里实现的?肯定不是udev的代码里,udev的rules里我也没有看到相关的配置啊

回复 3# Tinnal


   

Tinnal 发表于 2014-11-24 22:50

jinxinxin163 发表于 2014-11-24 20:04 static/image/common/back.gif
谢谢回复啊,你的意思是udev会调用ioctl来改变网卡的名字?

但是“udev调用ioctl来改变网卡的名字”是在 ...

我没有看过udev源码,但对你这个问法觉得很奇怪。为什么就不能在udev里ioctl呢?这不是很正常的事情吗?

至于你于的“udev的rules里我也没有看到相关的配置啊”我想你连最基本的udev man手册都没有去看。
给你一个在线版本的:
http://linux.die.net/man/8/udev

其中对NAME关键字的说明为:
NAME
The name of the node to be created, or the name, the network interface should be renamed to.
If given with the attribute NAME{all_partitions} it will create all 15 partitions of a blockdevice. This may be useful for removable media devices.

兄台,学Linux要多google,多看man手册。

pingmm 发表于 2014-12-11 23:26

...
版主好,请教个问题,假如没用udev,内核初始化的时候是根据什么来决定eth0,eth1,....的顺序的?如果我想改变这种顺序,有什么办法?

wait_rabbit 发表于 2014-12-12 13:12


key:

ioctl &&SIOCSIFNAME

Tinnal 发表于 2014-12-15 13:03

回复 6# pingmm


   根据网卡驱动插入的先后顺序。先插入的得eth0,后插入的得eth1, 以此类推。

pingmm 发表于 2014-12-17 13:33

回复 8# Tinnal


    谢谢
页: [1]
查看完整版本: linux下网卡名字eth0 eth1保存在哪里?