Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ba6611c6 authored by Xiao Ma's avatar Xiao Ma
Browse files

Add onIpv6AddressRemoved method in IpClientLinkObserver.callback.

Currently when IpClient receives onInterfaceAddressRemoved callback and
if the removed address is a global IPv6 address, remove it from the set
of gratuitous NA target address as well. To remove the dependency of the
overrided NetworkObserver usage in IpClient, move the code to the new
added callback onIpv6AddressRemoved, which is also triggered from the
IpClientLinkObserver when an IPv6 address was removed and keep the
calling order consistent as before.

Bug: 163492391
Test: atest NetworkStackTests NetworkStackIntegrationTests
Change-Id: I2a36fed6efb443a7c1dc13c76ec3fb83db2df437
parent 29116813
Loading
Loading
Loading
Loading
+34 −19
Original line number Diff line number Diff line
@@ -95,6 +95,7 @@ import android.util.Pair;
import android.util.SparseArray;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.HexDump;
@@ -740,9 +741,27 @@ public class IpClient extends StateMachine {
        mLinkObserver = new IpClientLinkObserver(
                mContext, getHandler(),
                mInterfaceName,
                (ifaceUp) -> sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED, ifaceUp
                new IpClientLinkObserver.Callback() {
                    @Override
                    public void update(boolean linkState) {
                        sendMessage(EVENT_NETLINK_LINKPROPERTIES_CHANGED, linkState
                                ? ARG_LINKPROP_CHANGED_LINKSTATE_UP
                        : ARG_LINKPROP_CHANGED_LINKSTATE_DOWN),
                                : ARG_LINKPROP_CHANGED_LINKSTATE_DOWN);
                    }

                    @Override
                    public void onIpv6AddressRemoved(final Inet6Address targetIp) {
                        // The update of Gratuitous NA target addresses set should be only accessed
                        // from the handler thread of IpClient StateMachine, keeping the behaviour
                        // consistent with relying on the non-blocking NetworkObserver callbacks,
                        // see {@link registerObserverForNonblockingCallback}. This can be done
                        // by either sending a message to StateMachine or posting a handler.
                        getHandler().post(() -> {
                            if (!mGratuitousNaTargetAddresses.contains(targetIp)) return;
                            updateGratuitousNaTargetSet(targetIp, false /* remove address */);
                        });
                    }
                },
                config, mLog, mDependencies) {
            @Override
            public void onInterfaceAdded(String iface) {
@@ -775,21 +794,6 @@ public class IpClient extends StateMachine {
                logMsg(msg);
            }

            @Override
            public void onInterfaceAddressRemoved(LinkAddress address, String iface) {
                super.onInterfaceAddressRemoved(address, iface);
                if (!mInterfaceName.equals(iface)) return;
                if (!address.isIpv6()) return;
                final Inet6Address targetIp = (Inet6Address) address.getAddress();
                if (mGratuitousNaTargetAddresses.contains(targetIp)) {
                    mGratuitousNaTargetAddresses.remove(targetIp);

                    final String msg = "Global IPv6 address: " + targetIp
                            + " has removed from the set of gratuitous NA target address.";
                    logMsg(msg);
                }
            }

            private void logMsg(String msg) {
                Log.d(mTag, msg);
                getHandler().post(() -> mLog.log("OBSERVED " + msg));
@@ -1663,6 +1667,7 @@ public class IpClient extends StateMachine {
        transmitPacket(packet, sockAddress, "Failed to send GARP");
    }

    @Nullable
    private static Inet6Address getIpv6LinkLocalAddress(final LinkProperties newLp) {
        for (LinkAddress la : newLp.getLinkAddresses()) {
            if (!la.isIpv6()) continue;
@@ -1672,6 +1677,16 @@ public class IpClient extends StateMachine {
        return null;
    }

    private void updateGratuitousNaTargetSet(@NonNull final Inet6Address targetIp, boolean add) {
        if (add) {
            mGratuitousNaTargetAddresses.add(targetIp);
        } else {
            mGratuitousNaTargetAddresses.remove(targetIp);
        }
        mLog.log((add ? "Add" : "Remove") + " global IPv6 address " + targetIp
                + (add ? " to" : " from") + " the set of gratuitous NA target address.");
    }

    private void maybeSendGratuitousNAs(final LinkProperties lp, boolean afterRoaming) {
        if (!lp.hasGlobalIpv6Address()) return;

@@ -1692,7 +1707,7 @@ public class IpClient extends StateMachine {
                        + targetIp.getHostAddress() + (afterRoaming ? " after roaming" : ""));
            }
            sendGratuitousNA(srcIp, targetIp);
            if (!afterRoaming) mGratuitousNaTargetAddresses.add(targetIp);
            if (!afterRoaming) updateGratuitousNaTargetSet(targetIp, true /* add address */);
        }
    }

+15 −1
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ import android.os.Handler;
import android.system.OsConstants;
import android.util.Log;

import androidx.annotation.NonNull;

import com.android.net.module.util.netlink.NduseroptMessage;
import com.android.net.module.util.netlink.NetlinkConstants;
import com.android.net.module.util.netlink.NetlinkMessage;
@@ -56,6 +58,7 @@ import com.android.networkstack.apishim.NetworkInformationShimImpl;
import com.android.networkstack.apishim.common.NetworkInformationShim;
import com.android.server.NetworkObserver;

import java.net.Inet6Address;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Arrays;
@@ -111,6 +114,13 @@ public class IpClientLinkObserver implements NetworkObserver {
         *                  with {@link #getLinkProperties()} in particular.
         */
        void update(boolean linkState);

        /**
         * Called when an IPv6 address was removed from the interface.
         *
         * @param addr The removed IPv6 address.
         */
        void onIpv6AddressRemoved(Inet6Address addr);
    }

    /** Configuration parameters for IpClientLinkObserver. */
@@ -262,7 +272,7 @@ public class IpClientLinkObserver implements NetworkObserver {
        }
    }

    private void updateInterfaceAddress(final LinkAddress address, boolean add) {
    private void updateInterfaceAddress(@NonNull final LinkAddress address, boolean add) {
        final boolean changed;
        final boolean linkState;
        synchronized (this) {
@@ -275,6 +285,10 @@ public class IpClientLinkObserver implements NetworkObserver {
        }
        if (changed) {
            mCallback.update(linkState);
            if (!add && address.isIpv6()) {
                final Inet6Address addr = (Inet6Address) address.getAddress();
                mCallback.onIpv6AddressRemoved(addr);
            }
        }
    }