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

Commit 9c82e969 authored by Xiao Ma's avatar Xiao Ma
Browse files

Get rtnetlink route information from netlink event instead of Netd.

Bug: 163492391
Test: atest NetworkStackTests NetworkStackIntegrationTests
Change-Id: Ifcb686a9bf577d990b8ccef20b86a3d906d1a57c
parent ebc22a81
Loading
Loading
Loading
Loading
+77 −25
Original line number Diff line number Diff line
@@ -23,6 +23,11 @@ import static android.system.OsConstants.IFF_LOOPBACK;

import static com.android.net.module.util.NetworkStackConstants.ICMPV6_ROUTER_ADVERTISEMENT;
import static com.android.net.module.util.netlink.NetlinkConstants.IFF_LOWER_UP;
import static com.android.net.module.util.netlink.NetlinkConstants.RTM_F_CLONED;
import static com.android.net.module.util.netlink.NetlinkConstants.RTN_UNICAST;
import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_KERNEL;
import static com.android.net.module.util.netlink.NetlinkConstants.RTPROT_RA;
import static com.android.net.module.util.netlink.NetlinkConstants.RT_SCOPE_UNIVERSE;

import android.app.AlarmManager;
import android.content.Context;
@@ -42,6 +47,7 @@ import com.android.net.module.util.netlink.NetlinkConstants;
import com.android.net.module.util.netlink.NetlinkMessage;
import com.android.net.module.util.netlink.RtNetlinkAddressMessage;
import com.android.net.module.util.netlink.RtNetlinkLinkMessage;
import com.android.net.module.util.netlink.RtNetlinkRouteMessage;
import com.android.net.module.util.netlink.StructIfaddrMsg;
import com.android.net.module.util.netlink.StructIfinfoMsg;
import com.android.net.module.util.netlink.StructNdOptPref64;
@@ -218,34 +224,18 @@ public class IpClientLinkObserver implements NetworkObserver {

    @Override
    public void onRouteUpdated(RouteInfo route) {
        if (mInterfaceName.equals(route.getInterface())) {
        if (isNetlinkEventParsingEnabled()) return;
        if (!mInterfaceName.equals(route.getInterface())) return;
        maybeLog("routeUpdated", route);
            final boolean changed;
            final boolean linkState;
            synchronized (this) {
                changed = mLinkProperties.addRoute(route);
                linkState = getInterfaceLinkStateLocked();
            }
            if (changed) {
                mCallback.update(linkState);
            }
        }
        updateInterfaceRoute(route, true /* add route */);
    }

    @Override
    public void onRouteRemoved(RouteInfo route) {
        if (mInterfaceName.equals(route.getInterface())) {
        if (isNetlinkEventParsingEnabled()) return;
        if (!mInterfaceName.equals(route.getInterface())) return;
        maybeLog("routeRemoved", route);
            final boolean changed;
            final boolean linkState;
            synchronized (this) {
                changed = mLinkProperties.removeRoute(route);
                linkState = getInterfaceLinkStateLocked();
            }
            if (changed) {
                mCallback.update(linkState);
            }
        }
        updateInterfaceRoute(route, false /* remove route */);
    }

    @Override
@@ -288,6 +278,22 @@ public class IpClientLinkObserver implements NetworkObserver {
        }
    }

    private void updateInterfaceRoute(final RouteInfo route, boolean add) {
        final boolean changed;
        final boolean linkState;
        synchronized (this) {
            if (add) {
                changed = mLinkProperties.addRoute(route);
            } else {
                changed = mLinkProperties.removeRoute(route);
            }
            linkState = getInterfaceLinkStateLocked();
        }
        if (changed) {
            mCallback.update(linkState);
        }
    }

    /**
     * Returns a copy of this object's LinkProperties.
     */
@@ -326,6 +332,18 @@ public class IpClientLinkObserver implements NetworkObserver {
        mNetlinkMonitor.setIfindex(0);  // 0 is never a valid ifindex.
    }

    private static boolean isSupportedRouteProtocol(RtNetlinkRouteMessage msg) {
        // Checks whether the protocol is supported. The behaviour is defined by the legacy
        // implementation in NetlinkEvent.cpp.
        return msg.getRtMsgHeader().protocol == RTPROT_KERNEL
                || msg.getRtMsgHeader().protocol == RTPROT_RA;
    }

    private static boolean isGlobalUnicastRoute(RtNetlinkRouteMessage msg) {
        return msg.getRtMsgHeader().scope == RT_SCOPE_UNIVERSE
                && msg.getRtMsgHeader().type == RTN_UNICAST;
    }

    /**
     * Simple NetlinkMonitor. Listen for netlink events from kernel.
     * All methods except the constructor must be called on the handler thread.
@@ -339,7 +357,9 @@ public class IpClientLinkObserver implements NetworkObserver {
                    ? NetlinkConstants.RTMGRP_ND_USEROPT
                    : (NetlinkConstants.RTMGRP_ND_USEROPT | NetlinkConstants.RTMGRP_LINK
                            | NetlinkConstants.RTMGRP_IPV4_IFADDR
                            | NetlinkConstants.RTMGRP_IPV6_IFADDR));
                            | NetlinkConstants.RTMGRP_IPV6_IFADDR
                            | NetlinkConstants.RTMGRP_IPV6_ROUTE));

            mHandler = h;
        }

@@ -516,6 +536,36 @@ public class IpClientLinkObserver implements NetworkObserver {
            }
        }

        private void processRtNetlinkRouteMessage(RtNetlinkRouteMessage msg) {
            if (!isNetlinkEventParsingEnabled()) return;
            if (msg.getInterfaceIndex() != mIfindex) return;
            // Ignore the unsupported route protocol and non-global unicast routes.
            if (!isSupportedRouteProtocol(msg)
                    || !isGlobalUnicastRoute(msg)
                    // don't support source routing
                    || (msg.getRtMsgHeader().srcLen != 0)
                    // don't support cloned routes
                    || ((msg.getRtMsgHeader().flags & RTM_F_CLONED) != 0)) {
                return;
            }

            final RouteInfo route = new RouteInfo(msg.getDestination(), msg.getGateway(),
                    mInterfaceName, msg.getRtMsgHeader().type);
            switch (msg.getHeader().nlmsg_type) {
                case NetlinkConstants.RTM_NEWROUTE:
                    maybeLog("routeUpdated", route);
                    updateInterfaceRoute(route, true /* add route */);
                    break;
                case NetlinkConstants.RTM_DELROUTE:
                    maybeLog("routeRemoved", route);
                    updateInterfaceRoute(route, false /* remove route */);
                    break;
                default:
                    Log.e(mTag, "Unknown rtnetlink route msg type " + msg.getHeader().nlmsg_type);
                    break;
            }
        }

        @Override
        protected void processNetlinkMessage(NetlinkMessage nlMsg, long whenMs) {
            if (nlMsg instanceof NduseroptMessage) {
@@ -524,6 +574,8 @@ public class IpClientLinkObserver implements NetworkObserver {
                processRtNetlinkLinkMessage((RtNetlinkLinkMessage) nlMsg);
            } else if (nlMsg instanceof RtNetlinkAddressMessage) {
                processRtNetlinkAddressMessage((RtNetlinkAddressMessage) nlMsg);
            } else if (nlMsg instanceof RtNetlinkRouteMessage) {
                processRtNetlinkRouteMessage((RtNetlinkRouteMessage) nlMsg);
            } else {
                Log.e(mTag, "Unknown netlink message: " + nlMsg);
            }