Loading src/android/net/ip/IpClientLinkObserver.java +77 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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); } Loading Loading
src/android/net/ip/IpClientLinkObserver.java +77 −25 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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. */ Loading Loading @@ -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. Loading @@ -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; } Loading Loading @@ -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) { Loading @@ -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); } Loading