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

Commit 25ee83bc authored by Xiao Ma's avatar Xiao Ma Committed by Gerrit Code Review
Browse files

Merge "Get rtnetlink route information from netlink event instead of Netd."

parents ac984403 9c82e969
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);
            }