Android13 wired network switch research

Android13 wired network switch research

This article compares the wired network switch code developed by Android9.

foreword

1、api

The api of Android13 provides the wired network switch EthernetManager.setEthernetEnabled(boolean), and
if you want to set the wired network switch in Android9, you need to implement it yourself.

2. Problem

On Android 13, there is a situation where the wired network is turned on and connected to the wired network without ip,
and calling the switch wired network switch has no effect (the node eth0 is not removed), and ifconfig etho down/up operation once has an ip.

3. Purpose

On Android9, the wired network switch interface will turn off the node; on Android13, the switch wired network node always exists.
So I decided to study the wired network switch, hoping to solve the problem.

The main research code is: related processing of EthernetTracker.java

The wired network switch article added by Android 9 before:
https://blog.csdn.net/wenzhi20102321/article/details/122243396

2. Code Analysis

1. EthernetTracker on Android 13

E:\982\code\android_source\packages\modules\Connectivity\service-t\src\com\android\server\ethernet\EthernetTracker.java


    private final INetd mNetd;

    @VisibleForTesting(visibility = PACKAGE)
    protected void setEthernetEnabled(boolean enabled) {
        mHandler.post(() -> {
            int newState = enabled ? ETHERNET_STATE_ENABLED : ETHERNET_STATE_DISABLED;

            //set state,by liwenzhi ,Start
            Log.i(TAG, "setEthernetEnabled newState = " +newState + ", old state = " + mEthernetState);
            setPersistedState(newState); //自己加的值,用于保存系统属性,不用关注
            //set state,by liwenzhi ,End
            
            if (mEthernetState == newState) return;

            mEthernetState = newState;

            //关键
            if (enabled) {
                trackAvailableInterfaces();//设置有线网可用
            } else {
                // TODO: maybe also disable server mode interface as well.
                untrackFactoryInterfaces();//设置有线网不可用
            }
            broadcastEthernetStateChange(mEthernetState);
        });
    }


    //开启网络
    private void trackAvailableInterfaces() {
        try {
            final String[] ifaces = mNetd.interfaceGetList();
            for (String iface : ifaces) {
                maybeTrackInterface(iface);
            }
        } catch (RemoteException | ServiceSpecificException e) {
            Log.e(TAG, "Could not get list of interfaces " + e);
        }
    }


    //添加有线网节点,一般是 eth0
    private void maybeTrackInterface(String iface) {
。。。

        addInterface(iface);
        broadcastInterfaceStateChange(iface);
    }


    //添加配置有线网节点
    private void addInterface(String iface) {
        InterfaceConfigurationParcel config = null;
        // Bring up the interface so we get link status indications.
        try {
            PermissionUtils.enforceNetworkStackPermission(mContext);
            NetdUtils.setInterfaceUp(mNetd, iface); // NetdUtils 是Android13 新增的工具类
            config = NetdUtils.getInterfaceConfigParcel(mNetd, iface);
        } catch (IllegalStateException e) {
            // Either the system is crashing or the interface has disappeared. Just ignore the
            // error; we haven't modified any state because we only do that if our calls succeed.
            Log.e(TAG, "Error upping interface " + iface, e);
        }

    }



    //关闭有线网网络
    private void untrackFactoryInterfaces() {
        for (String iface : mFactory.getAvailableInterfaces(true /* includeRestricted */)) {
            stopTrackingInterface(iface);
        }
    }

    //停止有线网节点,一般是eth0
    private void stopTrackingInterface(String iface) {
        removeInterface(iface);
        if (iface.equals(mDefaultInterface)) {
            mDefaultInterface = null;
        }
        broadcastInterfaceStateChange(iface); //发送广播通知该节点网络断开
    }

    //删除有线网节点的数据,应该是断开某个netId
    private void removeInterface(String iface) {
        mFactory.removeInterface(iface);
        maybeUpdateServerModeInterfaceState(iface, false);
    }

Pay attention to the removeInterface method above, the node is not removed here;

From the serial port, ifconfig, no matter whether the wired network is turned on or off, there will always be an eth0 node, but there is no ip when the call is turned off.

2. EthernetTracker on Android 13

E:\project_android11\code\android\frameworks\opt\net\ethernet\java\com\android\server\ethernet\EthernetTracker.java


private final INetworkManagementService mNMService;

//对比Android11 上开关有线网的最后实现,是通过mNMService 进行开关节点
+    public synchronized void setIntefaceState(boolean state) {
+        try {
+            String[] interfaces = getInterfaces(true);
+            for (String iface : interfaces) {
+                if (isTrackingInterface(iface)) {
+                    if (state) {
+                        mNMService.setInterfaceUp(iface);
+                    } else {
+                        mNMService.setInterfaceDown(iface);
+                    }
+                }
+            }
+            if (state) mHandler.post(this::trackAvailableInterfaces);
+        } catch (Exception e) {
+            Log.e(TAG, "Error change eth state : " + state); 
+        }
+    }

Android does not have the "+" code above, it is added by itself;
here mNMService.setInterfaceDown(iface) will remove the node when closing the node.

3. Compare the switching process

1. Android13 closes the wired network, but does not remove the node:

EthernetNetworkFactory mFactory;
mFactory.removeInterface(iface);

In fact, the EthernetTracker of Android9 also has an EthernetNetworkFactory object, but it is not transferred to removeInterface;
on Android11 ​​native code, the wired network is enabled by default, and the wired network interface is not disabled.

In fact, Android9 can also refer to Android13 to remove only a certain network, without removing the wired network node.

2. Android9 closes the wired network and removes the node:

INetworkManagementService mNMService;
mNMService.setInterfaceDown(iface);

Although Android13 EthernetNetworkFactory.java does not have an INetworkManagementService object, it has an INetd object with a similar meaning.
NetdUtils on Android13 contains the setInterfaceDown method with the same meaning.

3、NetdUtils

This class is a new tool class in Android13

framework\libs\net\client-libs\netd\com\android\net\module\util\NetdUtils.java

    /**
     * Set the given interface down.
     */
    public static void setInterfaceDown(INetd netd, String iface) {
        final InterfaceConfigurationParcel configParcel = getInterfaceConfigParcel(netd, iface);
        configParcel.flags = removeAndAddFlags(configParcel.flags, IF_STATE_UP /* remove */,
                IF_STATE_DOWN /* add */);
        setInterfaceConfig(netd, configParcel);
    }

    /**
     * Set interface configuration to netd by passing InterfaceConfigurationParcel.
     */
    public static void setInterfaceConfig(INetd netd, InterfaceConfigurationParcel configParcel) {
        try {
            netd.interfaceSetCfg(configParcel);
        } catch (RemoteException | ServiceSpecificException e) {
            throw new IllegalStateException(e);
        }
    }

3. Summary

1. Android 13 has added api for wired network switch

 mEthernetManager.setEthernetEnabled(boolean);

But there is no api for querying the status of the switch! You need to record the status of the wired network after the switch.

2. Differences between wired network switches

The automatic switch of Android9 will turn off the wired network node, and
the wired network switch that comes with Android13 will not turn off the wired network node.

The method of removing the wired network node will take two to three seconds;
the method of not removing the wired network is basically not time-consuming.

(1) Android9 should refer to Android13 without removing nodes

When closing the wired network, execute the following related code:

    //关闭有线网网络(Android13 复制过来的代码)
    private void untrackFactoryInterfaces() {
        for (String iface : mFactory.getAvailableInterfaces(true /* includeRestricted */)) {
            stopTrackingInterface(iface);
        }
    }

(2) Android13 should refer to Android9 to remove nodes

Just call NetdUtils.setInterfaceDown in the removeInterface method.


    private void removeInterface(String iface) {
        mFactory.removeInterface(iface);
        //remove jiedian!by liwenzhi,Start
        NetdUtils.setInterfaceDown(mNetd, iface);
        //remove jiedian!by liwenzhi,End
        maybeUpdateServerModeInterfaceState(iface, false);
    }

In the test, it is found that after switching the source and returning to the interface, removeInterface will be removed to other nodes. This is an additional judgment, only remove the related nodes of the wired network, such as whether eth0/eth1.

3. There is no IP problem in the wired network

The solution here to remove the wired network node can only be regarded as a means of circumvention. It is estimated that a whole set of system process analysis is required to solve this file.
Because it is a small probability problem, it should be avoided first.

Guess you like

Origin blog.csdn.net/wenzhi20102321/article/details/131871354
Recommended