Populate the key destination mac address
Required because XDP offload needs input interface mac address
to be a part of the key. The mac address is used for checking
packets which are received from exceped input interface.
Test: atest TetheringCoverageTests, TetheringPrivilegedTests
Change-Id: Ied159454b516c0d70efe0a85744d1bb606892f2d
diff --git a/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
index ce71f45..e310fb6 100644
--- a/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/30/com/android/networkstack/tethering/apishim/api30/BpfCoordinatorShimImpl.java
@@ -80,12 +80,14 @@
@Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- MacAddress srcMac, MacAddress dstMac, int mtu) {
+ @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
+ @NonNull MacAddress outDstMac, int mtu) {
return true;
}
@Override
- public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex) {
+ public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex,
+ int upstreamIfindex, @NonNull MacAddress inDstMac) {
return true;
}
diff --git a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
index 2bb9fd7..d7ce139 100644
--- a/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
+++ b/Tethering/apishim/31/com/android/networkstack/tethering/apishim/api31/BpfCoordinatorShimImpl.java
@@ -184,12 +184,13 @@
@Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- MacAddress srcMac, MacAddress dstMac, int mtu) {
+ @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
+ @NonNull MacAddress outDstMac, int mtu) {
if (!isInitialized()) return false;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex);
- final Tether6Value value = new Tether6Value(upstreamIfindex, srcMac,
- dstMac, OsConstants.ETH_P_IPV6, mtu);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac);
+ final Tether6Value value = new Tether6Value(upstreamIfindex, outSrcMac,
+ outDstMac, OsConstants.ETH_P_IPV6, mtu);
try {
mBpfUpstream6Map.insertEntry(key, value);
} catch (ErrnoException | IllegalStateException e) {
@@ -200,10 +201,11 @@
}
@Override
- public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex) {
+ public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
+ @NonNull MacAddress inDstMac) {
if (!isInitialized()) return false;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac);
try {
mBpfUpstream6Map.deleteEntry(key);
} catch (ErrnoException e) {
diff --git a/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
index ccdf78c..79a628b 100644
--- a/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
+++ b/Tethering/apishim/common/com/android/networkstack/tethering/apishim/common/BpfCoordinatorShim.java
@@ -78,21 +78,25 @@
* @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index
- * @param srcMac the source MAC address to use for packets
- * @oaram dstMac the destination MAC address to use for packets
+ * @param inDstMac the destination MAC address to use for XDP
+ * @param outSrcMac the source MAC address to use for packets
+ * @param outDstMac the destination MAC address to use for packets
* @return true if operation succeeded or was a no-op, false otherwise
*/
public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
- MacAddress srcMac, MacAddress dstMac, int mtu);
+ @NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac,
+ @NonNull MacAddress outDstMac, int mtu);
/**
* Stops IPv6 forwarding between the specified interfaces.
* @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index
+ * @param inDstMac the destination MAC address to use for XDP
* @return true if operation succeeded or was a no-op, false otherwise
*/
- public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex);
+ public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex,
+ int upstreamIfindex, @NonNull MacAddress inDstMac);
/**
* Return BPF tethering offload statistics.
diff --git a/Tethering/bpf_progs/bpf_tethering.h b/Tethering/bpf_progs/bpf_tethering.h
index efda228..5fdf8cd 100644
--- a/Tethering/bpf_progs/bpf_tethering.h
+++ b/Tethering/bpf_progs/bpf_tethering.h
@@ -107,11 +107,12 @@
// Ethernet) have 6-byte MAC addresses.
typedef struct {
- uint32_t iif; // The input interface index
- // TODO: extend this to include dstMac
- struct in6_addr neigh6; // The destination IPv6 address
+ uint32_t iif; // The input interface index
+ uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress)
+ uint8_t zero[2]; // zero pad for 8 byte alignment
+ struct in6_addr neigh6; // The destination IPv6 address
} TetherDownstream6Key;
-STRUCT_SIZE(TetherDownstream6Key, 4 + 16); // 20
+STRUCT_SIZE(TetherDownstream6Key, 4 + 6 + 2 + 16); // 28
typedef struct {
uint32_t oif; // The output interface to redirect to
@@ -154,10 +155,12 @@
#define TETHER_UPSTREAM6_MAP_PATH BPF_PATH_TETHER "map_offload_tether_upstream6_map"
typedef struct {
- uint32_t iif; // The input interface index
- // TODO: extend this to include dstMac and src ip /64 subnet
+ uint32_t iif; // The input interface index
+ uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress)
+ uint8_t zero[2]; // zero pad for 8 byte alignment
+ // TODO: extend this to include src ip /64 subnet
} TetherUpstream6Key;
-STRUCT_SIZE(TetherUpstream6Key, 4);
+STRUCT_SIZE(TetherUpstream6Key, 12);
#define TETHER_DOWNSTREAM4_TC_PROG_RAWIP_NAME "prog_offload_schedcls_tether_downstream4_rawip"
#define TETHER_DOWNSTREAM4_TC_PROG_ETHER_NAME "prog_offload_schedcls_tether_downstream4_ether"
diff --git a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
index 6f54d10..27fb581 100644
--- a/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
+++ b/Tethering/src/com/android/networkstack/tethering/BpfCoordinator.java
@@ -485,7 +485,7 @@
final int upstream = rule.upstreamIfindex;
// TODO: support upstream forwarding on non-point-to-point interfaces.
// TODO: get the MTU from LinkProperties and update the rules when it changes.
- if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream,
+ if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream, rule.srcMac,
NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, NetworkStackConstants.ETHER_MTU)) {
mLog.e("Failed to enable upstream IPv6 forwarding from "
+ mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
@@ -526,7 +526,8 @@
if (!isAnyRuleFromDownstreamToUpstream(rule.downstreamIfindex, rule.upstreamIfindex)) {
final int downstream = rule.downstreamIfindex;
final int upstream = rule.upstreamIfindex;
- if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream)) {
+ if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream,
+ rule.srcMac)) {
mLog.e("Failed to disable upstream IPv6 forwarding from "
+ mInterfaceNames.get(downstream) + " to " + mInterfaceNames.get(upstream));
}
@@ -795,8 +796,8 @@
}
private String ipv6UpstreamRuletoString(TetherUpstream6Key key, Tether6Value value) {
- return String.format("%d(%s) -> %d(%s) %04x %s %s",
- key.iif, getIfName(key.iif), value.oif, getIfName(value.oif),
+ return String.format("%d(%s) %s -> %d(%s) %04x %s %s",
+ key.iif, getIfName(key.iif), key.dstMac, value.oif, getIfName(value.oif),
value.ethProto, value.ethSrcMac, value.ethDstMac);
}
@@ -885,6 +886,62 @@
/** IPv6 forwarding rule class. */
public static class Ipv6ForwardingRule {
+ // The upstream6 and downstream6 rules are built as the following tables. Only raw ip
+ // upstream interface is supported.
+ // TODO: support ether ip upstream interface.
+ //
+ // NAT network topology:
+ //
+ // public network (rawip) private network
+ // | UE |
+ // +------------+ V +------------+------------+ V +------------+
+ // | Sever +---------+ Upstream | Downstream +---------+ Client |
+ // +------------+ +------------+------------+ +------------+
+ //
+ // upstream6 key and value:
+ //
+ // +------+-------------+
+ // | TetherUpstream6Key |
+ // +------+------+------+
+ // |field |iif |dstMac|
+ // | | | |
+ // +------+------+------+
+ // |value |downst|downst|
+ // | |ream |ream |
+ // +------+------+------+
+ //
+ // +------+----------------------------------+
+ // | |Tether6Value |
+ // +------+------+------+------+------+------+
+ // |field |oif |ethDst|ethSrc|ethPro|pmtu |
+ // | | |mac |mac |to | |
+ // +------+------+------+------+------+------+
+ // |value |upstre|-- |-- |ETH_P_|1500 |
+ // | |am | | |IP | |
+ // +------+------+------+------+------+------+
+ //
+ // downstream6 key and value:
+ //
+ // +------+--------------------+
+ // | |TetherDownstream6Key|
+ // +------+------+------+------+
+ // |field |iif |dstMac|neigh6|
+ // | | | | |
+ // +------+------+------+------+
+ // |value |upstre|-- |client|
+ // | |am | | |
+ // +------+------+------+------+
+ //
+ // +------+----------------------------------+
+ // | |Tether6Value |
+ // +------+------+------+------+------+------+
+ // |field |oif |ethDst|ethSrc|ethPro|pmtu |
+ // | | |mac |mac |to | |
+ // +------+------+------+------+------+------+
+ // |value |downst|client|downst|ETH_P_|1500 |
+ // | |ream | |ream |IP | |
+ // +------+------+------+------+------+------+
+ //
public final int upstreamIfindex;
public final int downstreamIfindex;
@@ -934,7 +991,8 @@
*/
@NonNull
public TetherDownstream6Key makeTetherDownstream6Key() {
- return new TetherDownstream6Key(upstreamIfindex, address.getAddress());
+ return new TetherDownstream6Key(upstreamIfindex, NULL_MAC_ADDRESS,
+ address.getAddress());
}
/**
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
index 3860cba..a08ad4a 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherDownstream6Key.java
@@ -16,6 +16,10 @@
package com.android.networkstack.tethering;
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
import com.android.net.module.util.Struct;
import com.android.net.module.util.Struct.Field;
import com.android.net.module.util.Struct.Type;
@@ -24,16 +28,23 @@
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
+import java.util.Objects;
/** The key of BpfMap which is used for bpf offload. */
public class TetherDownstream6Key extends Struct {
@Field(order = 0, type = Type.U32)
public final long iif; // The input interface index.
- @Field(order = 1, type = Type.ByteArray, arraysize = 16)
+ @Field(order = 1, type = Type.EUI48, padding = 2)
+ public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
+
+ @Field(order = 2, type = Type.ByteArray, arraysize = 16)
public final byte[] neigh6; // The destination IPv6 address.
- public TetherDownstream6Key(final long iif, final byte[] neigh6) {
+ public TetherDownstream6Key(final long iif, @NonNull final MacAddress dstMac,
+ final byte[] neigh6) {
+ Objects.requireNonNull(dstMac);
+
try {
final Inet6Address unused = (Inet6Address) InetAddress.getByAddress(neigh6);
} catch (ClassCastException | UnknownHostException e) {
@@ -41,29 +52,15 @@
+ Arrays.toString(neigh6));
}
this.iif = iif;
+ this.dstMac = dstMac;
this.neigh6 = neigh6;
}
@Override
- public boolean equals(Object obj) {
- if (this == obj) return true;
-
- if (!(obj instanceof TetherDownstream6Key)) return false;
-
- final TetherDownstream6Key that = (TetherDownstream6Key) obj;
-
- return iif == that.iif && Arrays.equals(neigh6, that.neigh6);
- }
-
- @Override
- public int hashCode() {
- return Long.hashCode(iif) ^ Arrays.hashCode(neigh6);
- }
-
- @Override
public String toString() {
try {
- return String.format("iif: %d, neigh: %s", iif, Inet6Address.getByAddress(neigh6));
+ return String.format("iif: %d, dstMac: %s, neigh: %s", iif, dstMac,
+ Inet6Address.getByAddress(neigh6));
} catch (UnknownHostException e) {
// Should not happen because construtor already verify neigh6.
throw new IllegalStateException("Invalid TetherDownstream6Key");
diff --git a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
index c736f2a..5893885 100644
--- a/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
+++ b/Tethering/src/com/android/networkstack/tethering/TetherUpstream6Key.java
@@ -16,14 +16,26 @@
package com.android.networkstack.tethering;
+import android.net.MacAddress;
+
+import androidx.annotation.NonNull;
+
import com.android.net.module.util.Struct;
+import java.util.Objects;
+
/** Key type for upstream IPv6 forwarding map. */
public class TetherUpstream6Key extends Struct {
@Field(order = 0, type = Type.S32)
public final int iif; // The input interface index.
- public TetherUpstream6Key(int iif) {
+ @Field(order = 1, type = Type.EUI48, padding = 2)
+ public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
+
+ public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac) {
+ Objects.requireNonNull(dstMac);
+
this.iif = iif;
+ this.dstMac = dstMac;
}
}
diff --git a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
index 62302c3..2e79739 100644
--- a/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
+++ b/Tethering/tests/privileged/src/com/android/networkstack/tethering/BpfMapTest.java
@@ -65,13 +65,13 @@
@Before
public void setUp() throws Exception {
mTestData = new ArrayMap<>();
- mTestData.put(createTetherDownstream6Key(101, "2001:db8::1"),
+ mTestData.put(createTetherDownstream6Key(101, "00:00:00:00:00:aa", "2001:db8::1"),
createTether6Value(11, "00:00:00:00:00:0a", "11:11:11:00:00:0b",
ETH_P_IPV6, 1280));
- mTestData.put(createTetherDownstream6Key(102, "2001:db8::2"),
+ mTestData.put(createTetherDownstream6Key(102, "00:00:00:00:00:bb", "2001:db8::2"),
createTether6Value(22, "00:00:00:00:00:0c", "22:22:22:00:00:0d",
ETH_P_IPV6, 1400));
- mTestData.put(createTetherDownstream6Key(103, "2001:db8::3"),
+ mTestData.put(createTetherDownstream6Key(103, "00:00:00:00:00:cc", "2001:db8::3"),
createTether6Value(33, "00:00:00:00:00:0e", "33:33:33:00:00:0f",
ETH_P_IPV6, 1500));
@@ -94,11 +94,12 @@
assertTrue(mTestMap.isEmpty());
}
- private TetherDownstream6Key createTetherDownstream6Key(long iif, String address)
- throws Exception {
+ private TetherDownstream6Key createTetherDownstream6Key(long iif, String mac,
+ String address) throws Exception {
+ final MacAddress dstMac = MacAddress.fromString(mac);
final InetAddress ipv6Address = InetAddress.getByName(address);
- return new TetherDownstream6Key(iif, ipv6Address.getAddress());
+ return new TetherDownstream6Key(iif, dstMac, ipv6Address.getAddress());
}
private Tether6Value createTether6Value(int oif, String src, String dst, int proto, int pmtu) {
@@ -164,7 +165,7 @@
public void testGetNextKey() throws Exception {
// [1] If the passed-in key is not found on empty map, return null.
final TetherDownstream6Key nonexistentKey =
- createTetherDownstream6Key(1234, "2001:db8::10");
+ createTetherDownstream6Key(1234, "00:00:00:00:00:01", "2001:db8::10");
assertNull(mTestMap.getNextKey(nonexistentKey));
// [2] If the passed-in key is null on empty map, throw NullPointerException.
@@ -344,7 +345,8 @@
// Build test data for TEST_MAP_SIZE + 1 entries.
for (int i = 1; i <= TEST_MAP_SIZE + 1; i++) {
- testData.put(createTetherDownstream6Key(i, "2001:db8::1"),
+ testData.put(
+ createTetherDownstream6Key(i, "00:00:00:00:00:01", "2001:db8::1"),
createTether6Value(100, "de:ad:be:ef:00:01", "de:ad:be:ef:00:02",
ETH_P_IPV6, 1500));
}
diff --git a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
index 1380bbf..435cab5 100644
--- a/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
+++ b/Tethering/tests/unit/src/android/net/ip/IpServerTest.java
@@ -838,8 +838,8 @@
@NonNull
private static TetherDownstream6Key makeDownstream6Key(int upstreamIfindex,
- @NonNull final InetAddress dst) {
- return new TetherDownstream6Key(upstreamIfindex, dst.getAddress());
+ @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst) {
+ return new TetherDownstream6Key(upstreamIfindex, upstreamMac, dst.getAddress());
}
@NonNull
@@ -857,10 +857,12 @@
}
private void verifyTetherOffloadRuleAdd(@Nullable InOrder inOrder, int upstreamIfindex,
- @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+ @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
+ @NonNull final MacAddress dstMac) throws Exception {
if (mBpfDeps.isAtLeastS()) {
verifyWithOrder(inOrder, mBpfDownstream6Map).updateEntry(
- makeDownstream6Key(upstreamIfindex, dst), makeDownstream6Value(dstMac));
+ makeDownstream6Key(upstreamIfindex, upstreamMac, dst),
+ makeDownstream6Value(dstMac));
} else {
verifyWithOrder(inOrder, mNetd).tetherOffloadRuleAdd(matches(upstreamIfindex, dst,
dstMac));
@@ -868,10 +870,11 @@
}
private void verifyNeverTetherOffloadRuleAdd(int upstreamIfindex,
- @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+ @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
+ @NonNull final MacAddress dstMac) throws Exception {
if (mBpfDeps.isAtLeastS()) {
verify(mBpfDownstream6Map, never()).updateEntry(
- makeDownstream6Key(upstreamIfindex, dst),
+ makeDownstream6Key(upstreamIfindex, upstreamMac, dst),
makeDownstream6Value(dstMac));
} else {
verify(mNetd, never()).tetherOffloadRuleAdd(matches(upstreamIfindex, dst, dstMac));
@@ -887,10 +890,11 @@
}
private void verifyTetherOffloadRuleRemove(@Nullable InOrder inOrder, int upstreamIfindex,
- @NonNull final InetAddress dst, @NonNull final MacAddress dstMac) throws Exception {
+ @NonNull MacAddress upstreamMac, @NonNull final InetAddress dst,
+ @NonNull final MacAddress dstMac) throws Exception {
if (mBpfDeps.isAtLeastS()) {
verifyWithOrder(inOrder, mBpfDownstream6Map).deleteEntry(makeDownstream6Key(
- upstreamIfindex, dst));
+ upstreamIfindex, upstreamMac, dst));
} else {
// |dstMac| is not required for deleting rules. Used bacause tetherOffloadRuleRemove
// uses a whole rule to be a argument.
@@ -911,7 +915,8 @@
private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int upstreamIfindex)
throws Exception {
if (!mBpfDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index);
+ final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
+ TEST_IFACE_PARAMS.macAddr);
final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
@@ -921,7 +926,8 @@
private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder)
throws Exception {
if (!mBpfDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index);
+ final TetherUpstream6Key key = new TetherUpstream6Key(TEST_IFACE_PARAMS.index,
+ TEST_IFACE_PARAMS.macAddr);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
}
@@ -991,14 +997,16 @@
recvNewNeigh(myIfindex, neighA, NUD_REACHABLE, macA);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighA, macA);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
resetNetdBpfMapAndCoordinator();
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdBpfMapAndCoordinator();
@@ -1013,7 +1021,8 @@
recvNewNeigh(myIfindex, neighA, NUD_FAILED, null);
verify(mBpfCoordinator).tetherOffloadRuleRemove(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macNull));
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighA, macNull);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macNull);
verifyNoUpstreamIpv6ForwardingChange(null);
resetNetdBpfMapAndCoordinator();
@@ -1021,7 +1030,8 @@
recvDelNeigh(myIfindex, neighB, NUD_STALE, macB);
verify(mBpfCoordinator).tetherOffloadRuleRemove(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macNull));
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macNull);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macNull);
verifyStopUpstreamIpv6Forwarding(null);
resetNetdBpfMapAndCoordinator();
@@ -1036,12 +1046,16 @@
lp.setInterfaceName(UPSTREAM_IFACE2);
dispatchTetherConnectionChanged(UPSTREAM_IFACE2, lp, -1);
verify(mBpfCoordinator).tetherOffloadRuleUpdate(mIpServer, UPSTREAM_IFINDEX2);
- verifyTetherOffloadRuleRemove(inOrder, UPSTREAM_IFINDEX, neighA, macA);
- verifyTetherOffloadRuleRemove(inOrder, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleRemove(inOrder,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
+ verifyTetherOffloadRuleRemove(inOrder,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(inOrder);
- verifyTetherOffloadRuleAdd(inOrder, UPSTREAM_IFINDEX2, neighA, macA);
+ verifyTetherOffloadRuleAdd(inOrder,
+ UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
verifyStartUpstreamIpv6Forwarding(inOrder, UPSTREAM_IFINDEX2);
- verifyTetherOffloadRuleAdd(inOrder, UPSTREAM_IFINDEX2, neighB, macB);
+ verifyTetherOffloadRuleAdd(inOrder,
+ UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
verifyNoUpstreamIpv6ForwardingChange(inOrder);
resetNetdBpfMapAndCoordinator();
@@ -1052,8 +1066,10 @@
// - processMessage CMD_IPV6_TETHER_UPDATE for the IPv6 upstream is lost.
// See dispatchTetherConnectionChanged.
verify(mBpfCoordinator, times(2)).tetherOffloadRuleClear(mIpServer);
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX2, neighA, macA);
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX2, neighB, macB);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighA, macA);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX2, UPSTREAM_IFACE_PARAMS2.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(inOrder);
resetNetdBpfMapAndCoordinator();
@@ -1072,17 +1088,20 @@
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
verify(mBpfCoordinator, never()).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verifyNeverTetherOffloadRuleAdd(UPSTREAM_IFINDEX, neighA, macA);
+ verifyNeverTetherOffloadRuleAdd(
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
// If upstream IPv6 connectivity is lost, rules are removed.
resetNetdBpfMapAndCoordinator();
dispatchTetherConnectionChanged(UPSTREAM_IFACE, null, 0);
verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(null);
// When the interface goes down, rules are removed.
@@ -1092,18 +1111,22 @@
recvNewNeigh(myIfindex, neighB, NUD_REACHABLE, macB);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighA, macA));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighA, macA);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neighB, macB));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
resetNetdBpfMapAndCoordinator();
mIpServer.stop();
mLooper.dispatchAll();
verify(mBpfCoordinator).tetherOffloadRuleClear(mIpServer);
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighA, macA);
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neighB, macB);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighA, macA);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neighB, macB);
verifyStopUpstreamIpv6Forwarding(null);
verify(mIpNeighborMonitor).stop();
resetNetdBpfMapAndCoordinator();
@@ -1132,14 +1155,16 @@
recvNewNeigh(myIfindex, neigh, NUD_REACHABLE, macA);
verify(mBpfCoordinator).tetherOffloadRuleAdd(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macA));
- verifyTetherOffloadRuleAdd(null, UPSTREAM_IFINDEX, neigh, macA);
+ verifyTetherOffloadRuleAdd(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macA);
verifyStartUpstreamIpv6Forwarding(null, UPSTREAM_IFINDEX);
resetNetdBpfMapAndCoordinator();
recvDelNeigh(myIfindex, neigh, NUD_STALE, macA);
verify(mBpfCoordinator).tetherOffloadRuleRemove(
mIpServer, makeForwardingRule(UPSTREAM_IFINDEX, neigh, macNull));
- verifyTetherOffloadRuleRemove(null, UPSTREAM_IFINDEX, neigh, macNull);
+ verifyTetherOffloadRuleRemove(null,
+ UPSTREAM_IFINDEX, UPSTREAM_IFACE_PARAMS.macAddr, neigh, macNull);
verifyStopUpstreamIpv6Forwarding(null);
resetNetdBpfMapAndCoordinator();
diff --git a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
index 293d0df..27fdac5 100644
--- a/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
+++ b/Tethering/tests/unit/src/com/android/networkstack/tethering/BpfCoordinatorTest.java
@@ -109,7 +109,7 @@
public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
private static final int DOWNSTREAM_IFINDEX = 10;
- private static final MacAddress DOWNSTREAM_MAC = MacAddress.ALL_ZEROS_ADDRESS;
+ private static final MacAddress DOWNSTREAM_MAC = MacAddress.fromString("12:34:56:78:90:ab");
private static final InetAddress NEIGH_A = InetAddresses.parseNumericAddress("2001:db8::1");
private static final InetAddress NEIGH_B = InetAddresses.parseNumericAddress("2001:db8::2");
private static final MacAddress MAC_A = MacAddress.fromString("00:00:00:00:00:0a");
@@ -383,19 +383,20 @@
}
private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
- int upstreamIfindex) throws Exception {
+ MacAddress downstreamMac, int upstreamIfindex) throws Exception {
if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac);
final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
verifyWithOrder(inOrder, mBpfUpstream6Map).insertEntry(key, value);
}
- private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex)
+ private void verifyStopUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
+ MacAddress downstreamMac)
throws Exception {
if (!mDeps.isAtLeastS()) return;
- final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex);
+ final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
}
@@ -732,9 +733,10 @@
final TetherDownstream6Key key = rule.makeTetherDownstream6Key();
assertEquals(key.iif, (long) mobileIfIndex);
+ assertEquals(key.dstMac, MacAddress.ALL_ZEROS_ADDRESS); // rawip upstream
assertTrue(Arrays.equals(key.neigh6, NEIGH_A.getAddress()));
- // iif (4) + neigh6 (16) = 20.
- assertEquals(20, key.writeToBytes().length);
+ // iif (4) + dstMac(6) + padding(2) + neigh6 (16) = 28.
+ assertEquals(28, key.writeToBytes().length);
}
@Test
@@ -875,7 +877,7 @@
verifyTetherOffloadRuleAdd(inOrder, ethernetRuleA);
verifyTetherOffloadSetInterfaceQuota(inOrder, ethIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
- verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, ethIfIndex);
+ verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC, ethIfIndex);
coordinator.tetherOffloadRuleAdd(mIpServer, ethernetRuleB);
verifyTetherOffloadRuleAdd(inOrder, ethernetRuleB);
@@ -892,12 +894,13 @@
coordinator.tetherOffloadRuleUpdate(mIpServer, mobileIfIndex);
verifyTetherOffloadRuleRemove(inOrder, ethernetRuleA);
verifyTetherOffloadRuleRemove(inOrder, ethernetRuleB);
- verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX);
+ verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
verifyTetherOffloadGetAndClearStats(inOrder, ethIfIndex);
verifyTetherOffloadRuleAdd(inOrder, mobileRuleA);
verifyTetherOffloadSetInterfaceQuota(inOrder, mobileIfIndex, QUOTA_UNLIMITED,
true /* isInit */);
- verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, mobileIfIndex);
+ verifyStartUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC,
+ mobileIfIndex);
verifyTetherOffloadRuleAdd(inOrder, mobileRuleB);
// [3] Clear all rules for a given IpServer.
@@ -906,7 +909,7 @@
coordinator.tetherOffloadRuleClear(mIpServer);
verifyTetherOffloadRuleRemove(inOrder, mobileRuleA);
verifyTetherOffloadRuleRemove(inOrder, mobileRuleB);
- verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX);
+ verifyStopUpstreamIpv6Forwarding(inOrder, DOWNSTREAM_IFINDEX, DOWNSTREAM_MAC);
verifyTetherOffloadGetAndClearStats(inOrder, mobileIfIndex);
// [4] Force pushing stats update to verify that the last diff of stats is reported on all