Merge changes I4a624ea4,I8626932e am: 0f0bff0594 am: a081a0cbab
Change-Id: I691053b22cb0b20e49419212f378cc473b1f35dc
This commit is contained in:
@@ -810,7 +810,7 @@ public class IpServer extends StateMachine {
|
|||||||
rule.dstMac.toByteArray());
|
rule.dstMac.toByteArray());
|
||||||
mIpv6ForwardingRules.put(rule.address, rule);
|
mIpv6ForwardingRules.put(rule.address, rule);
|
||||||
} catch (RemoteException | ServiceSpecificException e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
Log.e(TAG, "Could not add IPv6 downstream rule: " + e);
|
mLog.e("Could not add IPv6 downstream rule: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -821,10 +821,17 @@ public class IpServer extends StateMachine {
|
|||||||
mIpv6ForwardingRules.remove(rule.address);
|
mIpv6ForwardingRules.remove(rule.address);
|
||||||
}
|
}
|
||||||
} catch (RemoteException | ServiceSpecificException e) {
|
} catch (RemoteException | ServiceSpecificException e) {
|
||||||
Log.e(TAG, "Could not remove IPv6 downstream rule: " + e);
|
mLog.e("Could not remove IPv6 downstream rule: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void clearIpv6ForwardingRules() {
|
||||||
|
for (Ipv6ForwardingRule rule : mIpv6ForwardingRules.values()) {
|
||||||
|
removeIpv6ForwardingRule(rule, false /*removeFromMap*/);
|
||||||
|
}
|
||||||
|
mIpv6ForwardingRules.clear();
|
||||||
|
}
|
||||||
|
|
||||||
// Convenience method to replace a rule with the same rule on a new upstream interface.
|
// Convenience method to replace a rule with the same rule on a new upstream interface.
|
||||||
// Allows replacing the rules in one iteration pass without ConcurrentModificationExceptions.
|
// Allows replacing the rules in one iteration pass without ConcurrentModificationExceptions.
|
||||||
// Relies on the fact that rules are in a map indexed by IP address.
|
// Relies on the fact that rules are in a map indexed by IP address.
|
||||||
@@ -837,6 +844,12 @@ public class IpServer extends StateMachine {
|
|||||||
// changes or if a neighbor event is received.
|
// changes or if a neighbor event is received.
|
||||||
private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
|
private void updateIpv6ForwardingRules(int prevUpstreamIfindex, int upstreamIfindex,
|
||||||
NeighborEvent e) {
|
NeighborEvent e) {
|
||||||
|
// If we no longer have an upstream, clear forwarding rules and do nothing else.
|
||||||
|
if (upstreamIfindex == 0) {
|
||||||
|
clearIpv6ForwardingRules();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// If the upstream interface has changed, remove all rules and re-add them with the new
|
// If the upstream interface has changed, remove all rules and re-add them with the new
|
||||||
// upstream interface.
|
// upstream interface.
|
||||||
if (prevUpstreamIfindex != upstreamIfindex) {
|
if (prevUpstreamIfindex != upstreamIfindex) {
|
||||||
@@ -846,13 +859,14 @@ public class IpServer extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If we're here to process a NeighborEvent, do so now.
|
// If we're here to process a NeighborEvent, do so now.
|
||||||
|
// mInterfaceParams must be non-null or the event would not have arrived.
|
||||||
if (e == null) return;
|
if (e == null) return;
|
||||||
if (!(e.ip instanceof Inet6Address) || e.ip.isMulticastAddress()
|
if (!(e.ip instanceof Inet6Address) || e.ip.isMulticastAddress()
|
||||||
|| e.ip.isLoopbackAddress() || e.ip.isLinkLocalAddress()) {
|
|| e.ip.isLoopbackAddress() || e.ip.isLinkLocalAddress()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ipv6ForwardingRule rule = new Ipv6ForwardingRule(mLastIPv6UpstreamIfindex,
|
Ipv6ForwardingRule rule = new Ipv6ForwardingRule(upstreamIfindex,
|
||||||
mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr,
|
mInterfaceParams.index, (Inet6Address) e.ip, mInterfaceParams.macAddr,
|
||||||
e.macAddr);
|
e.macAddr);
|
||||||
if (e.isValid()) {
|
if (e.isValid()) {
|
||||||
@@ -1095,6 +1109,7 @@ public class IpServer extends StateMachine {
|
|||||||
|
|
||||||
for (String ifname : mUpstreamIfaceSet.ifnames) cleanupUpstreamInterface(ifname);
|
for (String ifname : mUpstreamIfaceSet.ifnames) cleanupUpstreamInterface(ifname);
|
||||||
mUpstreamIfaceSet = null;
|
mUpstreamIfaceSet = null;
|
||||||
|
clearIpv6ForwardingRules();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cleanupUpstreamInterface(String upstreamIface) {
|
private void cleanupUpstreamInterface(String upstreamIface) {
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ import static org.junit.Assert.assertTrue;
|
|||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
import static org.mockito.ArgumentMatchers.argThat;
|
import static org.mockito.ArgumentMatchers.argThat;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyInt;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
import static org.mockito.Mockito.doAnswer;
|
import static org.mockito.Mockito.doAnswer;
|
||||||
@@ -546,9 +547,9 @@ public class IpServerTest {
|
|||||||
reset(mNetd);
|
reset(mNetd);
|
||||||
|
|
||||||
// Link-local and multicast neighbors are ignored.
|
// Link-local and multicast neighbors are ignored.
|
||||||
recvNewNeigh(notMyIfindex, neighLL, NUD_REACHABLE, macA);
|
recvNewNeigh(myIfindex, neighLL, NUD_REACHABLE, macA);
|
||||||
verifyNoMoreInteractions(mNetd);
|
verifyNoMoreInteractions(mNetd);
|
||||||
recvNewNeigh(notMyIfindex, neighMC, NUD_REACHABLE, macA);
|
recvNewNeigh(myIfindex, neighMC, NUD_REACHABLE, macA);
|
||||||
verifyNoMoreInteractions(mNetd);
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
// A neighbor that is no longer valid causes the rule to be removed.
|
// A neighbor that is no longer valid causes the rule to be removed.
|
||||||
@@ -578,6 +579,52 @@ public class IpServerTest {
|
|||||||
eq(neighB.getAddress()), eq(myMac.toByteArray()), eq(macB.toByteArray()));
|
eq(neighB.getAddress()), eq(myMac.toByteArray()), eq(macB.toByteArray()));
|
||||||
inOrder.verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX),
|
inOrder.verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX),
|
||||||
eq(neighB.getAddress()));
|
eq(neighB.getAddress()));
|
||||||
|
reset(mNetd);
|
||||||
|
|
||||||
|
// When the upstream is lost, rules are removed.
|
||||||
|
dispatchTetherConnectionChanged(null, null);
|
||||||
|
verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX2),
|
||||||
|
eq(neighA.getAddress()));
|
||||||
|
verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX2),
|
||||||
|
eq(neighB.getAddress()));
|
||||||
|
reset(mNetd);
|
||||||
|
|
||||||
|
// If the upstream is IPv4-only, no rules are added.
|
||||||
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE);
|
||||||
|
reset(mNetd);
|
||||||
|
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
|
||||||
|
verifyNoMoreInteractions(mNetd);
|
||||||
|
|
||||||
|
// Rules can be added again once upstream IPv6 connectivity is available.
|
||||||
|
lp.setInterfaceName(UPSTREAM_IFACE);
|
||||||
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp);
|
||||||
|
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
|
||||||
|
verify(mNetd).tetherRuleAddDownstreamIpv6(eq(myIfindex), eq(UPSTREAM_IFINDEX),
|
||||||
|
eq(neighB.getAddress()), eq(myMac.toByteArray()), eq(macB.toByteArray()));
|
||||||
|
verify(mNetd, never()).tetherRuleAddDownstreamIpv6(anyInt(), anyInt(),
|
||||||
|
eq(neighA.getAddress()), any(), any());
|
||||||
|
|
||||||
|
// If upstream IPv6 connectivity is lost, rules are removed.
|
||||||
|
reset(mNetd);
|
||||||
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE, null);
|
||||||
|
verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX), eq(neighB.getAddress()));
|
||||||
|
|
||||||
|
// When the interface goes down, rules are removed.
|
||||||
|
lp.setInterfaceName(UPSTREAM_IFACE);
|
||||||
|
dispatchTetherConnectionChanged(UPSTREAM_IFACE, lp);
|
||||||
|
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
|
||||||
|
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
|
||||||
|
verify(mNetd).tetherRuleAddDownstreamIpv6(eq(myIfindex), eq(UPSTREAM_IFINDEX),
|
||||||
|
eq(neighA.getAddress()), eq(myMac.toByteArray()), eq(macA.toByteArray()));
|
||||||
|
verify(mNetd).tetherRuleAddDownstreamIpv6(eq(myIfindex), eq(UPSTREAM_IFINDEX),
|
||||||
|
eq(neighB.getAddress()), eq(myMac.toByteArray()), eq(macB.toByteArray()));
|
||||||
|
reset(mNetd);
|
||||||
|
|
||||||
|
mIpServer.stop();
|
||||||
|
mLooper.dispatchAll();
|
||||||
|
verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX), eq(neighA.getAddress()));
|
||||||
|
verify(mNetd).tetherRuleRemoveDownstreamIpv6(eq(UPSTREAM_IFINDEX), eq(neighB.getAddress()));
|
||||||
|
reset(mNetd);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
|
private void assertDhcpStarted(IpPrefix expectedPrefix) throws Exception {
|
||||||
|
|||||||
Reference in New Issue
Block a user