Support learning the NAT64 prefix from two different sources.
The NAT64 prefix from the RA always takes precedence over the NAT64 prefix from DNS discovery, because it is detected faster, and detecting it does not require sending any packets. Bug: 150648313 Test: new unit test Change-Id: Ic7452431d2d9aea1ae59b67a9d8383c6cc5b3902
This commit is contained in:
@@ -5880,6 +5880,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
||||
|
||||
private void processLinkPropertiesFromAgent(NetworkAgentInfo nai, LinkProperties lp) {
|
||||
lp.ensureDirectlyConnectedRoutes();
|
||||
nai.clatd.setNat64PrefixFromRa(lp.getNat64Prefix());
|
||||
}
|
||||
|
||||
private void updateLinkProperties(NetworkAgentInfo networkAgent, LinkProperties newLp,
|
||||
|
||||
@@ -81,15 +81,23 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
RUNNING, // start() called, and the stacked iface is known to be up.
|
||||
}
|
||||
|
||||
/** NAT64 prefix currently in use. Only valid in STARTING or RUNNING states. */
|
||||
/**
|
||||
* NAT64 prefix currently in use. Only valid in STARTING or RUNNING states.
|
||||
* Used, among other things, to avoid updates when switching from a prefix learned from one
|
||||
* source (e.g., RA) to the same prefix learned from another source (e.g., RA).
|
||||
*/
|
||||
private IpPrefix mNat64PrefixInUse;
|
||||
/** NAT64 prefix (if any) discovered from DNS via RFC 7050. */
|
||||
private IpPrefix mNat64PrefixFromDns;
|
||||
/** NAT64 prefix (if any) learned from the network via RA. */
|
||||
private IpPrefix mNat64PrefixFromRa;
|
||||
private String mBaseIface;
|
||||
private String mIface;
|
||||
private Inet6Address mIPv6Address;
|
||||
private State mState = State.IDLE;
|
||||
|
||||
private boolean mPrefixDiscoveryRunning;
|
||||
|
||||
public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
|
||||
INetworkManagementService nmService) {
|
||||
mDnsResolver = dnsResolver;
|
||||
@@ -138,15 +146,6 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
return requiresClat(nai) && lp != null && lp.getNat64Prefix() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if we have started prefix discovery and not yet stopped it (regardless of
|
||||
* whether it is still running or has succeeded).
|
||||
* A true result corresponds to internal states DISCOVERING, STARTING and RUNNING.
|
||||
*/
|
||||
public boolean isPrefixDiscoveryStarted() {
|
||||
return mState == State.DISCOVERING || isStarted();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if clatd has been started and has not yet stopped.
|
||||
* A true result corresponds to internal states STARTING and RUNNING.
|
||||
@@ -181,7 +180,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
return;
|
||||
}
|
||||
|
||||
mNat64PrefixInUse = getNat64Prefix();
|
||||
mNat64PrefixInUse = selectNat64Prefix();
|
||||
String addrStr = null;
|
||||
try {
|
||||
addrStr = mNetd.clatdStart(baseIface, mNat64PrefixInUse.toString());
|
||||
@@ -218,8 +217,14 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
mNat64PrefixInUse = null;
|
||||
mIface = null;
|
||||
mBaseIface = null;
|
||||
if (requiresClat(mNetwork)) {
|
||||
mState = State.DISCOVERING;
|
||||
|
||||
if (isPrefixDiscoveryNeeded()) {
|
||||
if (!mPrefixDiscoveryRunning) {
|
||||
startPrefixDiscovery();
|
||||
} else {
|
||||
// Prefix discovery is already running. Nothing to do.
|
||||
mState = State.DISCOVERING;
|
||||
}
|
||||
} else {
|
||||
stopPrefixDiscovery(); // Enters IDLE state.
|
||||
}
|
||||
@@ -283,6 +288,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
Slog.e(TAG, "Error starting prefix discovery on netId " + getNetId() + ": " + e);
|
||||
}
|
||||
mState = State.DISCOVERING;
|
||||
mPrefixDiscoveryRunning = true;
|
||||
}
|
||||
|
||||
private void stopPrefixDiscovery() {
|
||||
@@ -292,10 +298,18 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
Slog.e(TAG, "Error stopping prefix discovery on netId " + getNetId() + ": " + e);
|
||||
}
|
||||
mState = State.IDLE;
|
||||
mPrefixDiscoveryRunning = false;
|
||||
}
|
||||
|
||||
private boolean isPrefixDiscoveryNeeded() {
|
||||
// If there is no NAT64 prefix in the RA, prefix discovery is always needed. It cannot be
|
||||
// stopped after it succeeds, because stopping it will cause netd to report that the prefix
|
||||
// has been removed, and that will cause us to stop clatd.
|
||||
return requiresClat(mNetwork) && mNat64PrefixFromRa == null;
|
||||
}
|
||||
|
||||
private void maybeHandleNat64PrefixChange() {
|
||||
final IpPrefix newPrefix = getNat64Prefix();
|
||||
final IpPrefix newPrefix = selectNat64Prefix();
|
||||
if (!Objects.equals(mNat64PrefixInUse, newPrefix)) {
|
||||
Slog.d(TAG, "NAT64 prefix changed from " + mNat64PrefixInUse + " to "
|
||||
+ newPrefix);
|
||||
@@ -314,13 +328,10 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
// TODO: turn this class into a proper StateMachine. http://b/126113090
|
||||
switch (mState) {
|
||||
case IDLE:
|
||||
if (requiresClat(mNetwork)) {
|
||||
// Network is detected to be IPv6-only.
|
||||
// TODO: consider going to STARTING directly if the NAT64 prefix is already
|
||||
// known. This would however result in clatd running without prefix discovery
|
||||
// running, which might be a surprising combination.
|
||||
if (isPrefixDiscoveryNeeded()) {
|
||||
startPrefixDiscovery(); // Enters DISCOVERING state.
|
||||
return;
|
||||
} else if (requiresClat(mNetwork)) {
|
||||
start(); // Enters STARTING state.
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -351,8 +362,20 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
}
|
||||
}
|
||||
|
||||
private IpPrefix getNat64Prefix() {
|
||||
return mNat64PrefixFromDns;
|
||||
/**
|
||||
* Picks a NAT64 prefix to use. Always prefers the prefix from the RA if one is received from
|
||||
* both RA and DNS, because the prefix in the RA has better security and updatability, and will
|
||||
* almost always be received first anyway.
|
||||
*
|
||||
* Any network that supports legacy hosts will support discovering the DNS64 prefix via DNS as
|
||||
* well. If the prefix from the RA is withdrawn, fall back to that for reliability purposes.
|
||||
*/
|
||||
private IpPrefix selectNat64Prefix() {
|
||||
return mNat64PrefixFromRa != null ? mNat64PrefixFromRa : mNat64PrefixFromDns;
|
||||
}
|
||||
|
||||
public void setNat64PrefixFromRa(IpPrefix prefix) {
|
||||
mNat64PrefixFromRa = prefix;
|
||||
}
|
||||
|
||||
public void setNat64PrefixFromDns(IpPrefix prefix) {
|
||||
@@ -367,7 +390,7 @@ public class Nat464Xlat extends BaseNetworkObserver {
|
||||
public void fixupLinkProperties(@NonNull LinkProperties oldLp, @NonNull LinkProperties lp) {
|
||||
// This must be done even if clatd is not running, because otherwise shouldStartClat would
|
||||
// never return true.
|
||||
lp.setNat64Prefix(getNat64Prefix());
|
||||
lp.setNat64Prefix(selectNat64Prefix());
|
||||
|
||||
if (!isRunning()) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user