[Linux RK] change network card name | CSDN creative punch in

Posted by Duje_KH on Thu, 27 Jan 2022 22:56:09 +0100

background

When ifconfig checks the network interface information, there are network interfaces eth0 and eth1. How are the name drivers of the two ports allocated? How to change the standard eth1 and eth0 to LAN and WAN (or users can define their own names). When ifconfig is displayed again, LAN and WAN network cards are displayed.

The process of parsing and setting the default name eth0/eth1 of the network card device

Take RK3568 as an example. gmac0 and gmac1 nodes in the device tree will call rk in the driver_ gmac_ probe. The network name will be assigned when registering the network device. The previous network device name is eth%d. Next, we will analyze the whole process of assigning names.

// drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
rk_gmac_probe
    -> stmmac_dvr_probe                           // drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
    	//  printk("dwb -1- stmmac_dvr_probe --- priv->dev=%s\n\r", priv->dev->name);   You can add and view the printed log
        -> register_netdev                        // When registering a network device, it is changed to eth0\eth1. Before that, priv - > dev - > name = "eth% d"
        	-> register_netdevice                                                 // net/core/dev.c
    		-> dev_get_valid_name(net, dev, dev->name);   
      			-> if (!dev_valid_name(name))
                                    return -EINVAL;
                              if (strchr(name, '%'))              // Search for the first% position in the name
                                   return dev_alloc_name_ns(net, dev, name);
                                        -> ret = __dev_alloc_name(net, name, buf);               // net/core/dev.c
                                            if (ret >= 0)                           // If it is greater than 0, assign buf to dev - > name
                                            strlcpy(dev->name, buf, IFNAMSIZ);
    	// printk("dwb -2- stmmac_dvr_probe --- priv->dev=%s\n\r", priv->dev->name);   You can add and view the printed log
                                                      
// arch/arm64/include/asm/page-def.h
#define for_each_netdev(net, d)     \
   list_for_each_entry(d, &(net)->dev_base_head, dev_list)

#define PAGE_SHIFT      CONFIG_ARM64_PAGE_SHIFT           12
#define PAGE_SIZE       (_AC(1, UL) << PAGE_SHIFT)          
// net/core/dev.c                                                                    
static int __dev_alloc_name(struct net *net, const char *name, char *buf)
{
    int i = 0;
    const char *p;
    const int max_netdevices = 8*PAGE_SIZE;
    unsigned long *inuse;
    struct net_device *d;
    if (!dev_valid_name(name))
        return -EINVAL;
    p = strchr(name, '%');                                          // Get the location of '%'              
    if (p) {
        if (p[1] != 'd' || strchr(p + 2, '%'))                      // Check whether it is'% 'or'd', not return
            return -EINVAL;
        /* Use one page as a bit array of possible slots */
        inuse = (unsigned long *) get_zeroed_page(GFP_ATOMIC);       // Assign a physical page as a bitmap to mark the serial number of this type of device in the system
        if (!inuse)
            return -ENOMEM;
        for_each_netdev(net, d) {                                   // Loop network device variable all devices in the network namespace, i.e. net_device structure
        								//  printk("dwb -0- d->name=%s, name=%s, i=%d\n\r", d->name, name, i);      You can add and view the printed log
            if (!sscanf(d->name, name, &i))                         // Get the serial number of the same type of network device  
                continue;
                							// printk("dwb --- 11111111----continue\n\r");       You can add and view the printed log
            if (i < 0 || i >= max_netdevices)                       // Judge the range of serial number
                continue;
    								// printk("dwb -1- i=%d\n\r", i);     You can add and view the printed log
            /*  avoid cases where sscanf is not exact inverse of printf */
            snprintf(buf, IFNAMSIZ, name, i);
            if (!strncmp(buf, d->name, IFNAMSIZ))                    // Verify whether the resolved serial number is correct       
                set_bit(i, inuse);                                   // Mark this bit in bitmap
        }
        									// printk("dwb -2- i=%d\n\r", i);
        i = find_first_zero_bit(inuse, max_netdevices);               // Find the first serial number with 0
        free_page((unsigned long) inuse);
    }
    snprintf(buf, IFNAMSIZ, name, i);                                // Output the complete device name according to the found serial number
    if (!__dev_get_by_name(net, buf))                                 // In name_list to find out whether there is a device with the same name in the linked list
        return i;
    /* It is possible to run out of possible slots
     * when the name is long and there isn't enough space left
     * for the digits, or if all bits are used.
     */
    return -ENFILE;
}

dev_ alloc_ The name (DEV, dev - > name) function will find the first unused serial number of this type of network device in the system to replace% d in the device name and generate a device name such as eth5.
Here, the complete device name combination is completed for the device. In the future, when processing bitmaps, you can directly use the set implemented by the kernel_ Bit and find_first_zero_bit,clear_bit and other functions.

Change network card name

After introducing the source of the network name, we can now change eth0 to LAN display and eth1 to WLAN display

diff --git a/net/core/dev.c b/net/core/dev.c
index 768b1dd5..38e187e8 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c

@@ -8645,6 +8651,7 @@ int register_netdevice(struct net_device *dev)
 {
        int ret;
        struct net *net = dev_net(dev);
+       static int flag=1;

        BUILD_BUG_ON(sizeof(netdev_features_t) * BITS_PER_BYTE <
                     NETDEV_FEATURE_COUNT);
@@ -8663,7 +8670,20 @@ int register_netdevice(struct net_device *dev)
        ret = dev_get_valid_name(net, dev, dev->name);
        if (ret < 0)
                goto out;
-
+
+       if((!strcmp(dev->name , "eth0")) && flag)
+       {
+               snprintf(dev->name , IFNAMSIZ, "LAN");
+               flag--;
                                                                                             // printk("dwb --------55 ------eth0\n\r");  You can add and view the printed log
+       }
+       else if(!strcmp(dev->name , "eth0"))
+       {
+               snprintf(dev->name , IFNAMSIZ, "WAN");
+               flag++;
                                                                                              // printk("dwb --------55 ------eth1\n\r"); You can add and view the printed log
+       }
+
        /* Init, if this function is available */
        if (dev->netdev_ops->ndo_init) {
                ret = dev->netdev_ops->ndo_init(dev);

Parsing: through dev_ get_ valid_ After the name is assigned, change the name to the name you want. However, it should be noted that a flag flag bit should be defined to distinguish two network ports. As analyzed above, net will be scanned when assigning names_ The name function in all devices under the device * structure is compared with the passed in name=eth%d (this is the initial assignment of the network interface). If no similar name is found, eth0 is still output.
Therefore, if the flag flag bit is not defined, no matter how many network interface devices are registered, it will go through the register_ The names assigned by the netdevice function are eth0
Note: for the exchange of two names, just change the flag bit to static int flag=0;

Overall print log parsing

Add log information after printing

[    0.581826] dwb -0- d->name=lo, name=can%d, i=0
[    0.581829] dwb --- 11111111----continue
[    0.581849] dwb -2- i=0
[    0.582597] dwb -0- d->name=lo, name=can%d, i=0
[    0.582617] dwb --- 11111111----continue
[    0.582632] dwb -0- d->name=can0, name=can%d, i=0
[    0.582649] dwb -1- i=0
[    0.582663] dwb -2- i=0
---------------------- The above is the registration of other network devices -----------------------------

[    0.802759] dwb -1- stmmac_dvr_probe --- priv->dev=eth%d
[    0.802767] dwb -0- d->name=lo, name=eth%d, i=0
[    0.802785] dwb --- 11111111----continue
[    0.802801] dwb -0- d->name=can0, name=eth%d, i=0
[    0.802813] dwb --- 11111111----continue
[    0.802827] dwb -0- d->name=can1, name=eth%d, i=0
[    0.802838] dwb --- 11111111----continue
[    0.802850] dwb -2- i=0
[    0.802867] dwb --------55 ------eth0
[    0.803203] dwb -2- stmmac_dvr_probe --- priv->dev=LAN
--------------------- The above is the name of the first network port scanning assignment, traversal net_device *All device names under the structure have no matching output eth0 (dwb -2- i=0)---------------------------
[    1.022609] dwb -1- stmmac_dvr_probe --- priv->dev=eth%d
[    1.022618] dwb -0- d->name=lo, name=eth%d, i=0
[    1.022636] dwb --- 11111111----continue
[    1.022650] dwb -0- d->name=can0, name=eth%d, i=0
[    1.022663] dwb --- 11111111----continue
[    1.022672] dwb -0- d->name=can1, name=eth%d, i=0
[    1.022684] dwb --- 11111111----continue
[    1.022697] dwb -0- d->name=LAN, name=eth%d, i=0
[    1.022709] dwb --- 11111111----continue
[    1.022721] dwb -2- i=0
[    1.022737] dwb --------55 ------eth1
[    1.023078] dwb -2- stmmac_dvr_probe --- priv->dev=WAN
----------------------The above is the second network port scanning, allocation name, traversal net_device *All device names under the structure have no matching output eth0 (dwb -2- i=0)Due to flag bit flag Then open two network ports in the area--------------------------------

Implementation effect diagram

Topics: Linux network ARM