Skip to content
Snippets Groups Projects
Commit d932cd82 authored by KH Shi's avatar KH Shi Committed by Gerrit Code Review
Browse files

Merge "bpf tethering offload - add src subnet to upstream ipv6 direction" into main

parents 6f1da9b4 c8fb1a25
No related branches found
No related tags found
No related merge requests found
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
package com.android.networkstack.tethering.apishim.api30; package com.android.networkstack.tethering.apishim.api30;
import android.net.INetd; import android.net.INetd;
import android.net.IpPrefix;
import android.net.MacAddress; import android.net.MacAddress;
import android.net.TetherStatsParcel; import android.net.TetherStatsParcel;
import android.os.RemoteException; import android.os.RemoteException;
...@@ -81,14 +82,14 @@ public class BpfCoordinatorShimImpl ...@@ -81,14 +82,14 @@ public class BpfCoordinatorShimImpl
@Override @Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
@NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac, @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
@NonNull MacAddress outDstMac, int mtu) { @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu) {
return true; return true;
} }
@Override @Override
public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
int upstreamIfindex, @NonNull MacAddress inDstMac) { @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac) {
return true; return true;
} }
......
...@@ -17,7 +17,9 @@ ...@@ -17,7 +17,9 @@
package com.android.networkstack.tethering.apishim.api31; package com.android.networkstack.tethering.apishim.api31;
import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED; import static android.net.netstats.provider.NetworkStatsProvider.QUOTA_UNLIMITED;
import static android.net.util.NetworkConstants.RFC7421_PREFIX_LENGTH;
import android.net.IpPrefix;
import android.net.MacAddress; import android.net.MacAddress;
import android.system.ErrnoException; import android.system.ErrnoException;
import android.system.Os; import android.system.Os;
...@@ -48,6 +50,9 @@ import com.android.networkstack.tethering.TetherUpstream6Key; ...@@ -48,6 +50,9 @@ import com.android.networkstack.tethering.TetherUpstream6Key;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Arrays;
/** /**
* Bpf coordinator class for API shims. * Bpf coordinator class for API shims.
...@@ -196,13 +201,23 @@ public class BpfCoordinatorShimImpl ...@@ -196,13 +201,23 @@ public class BpfCoordinatorShimImpl
return true; return true;
} }
@NonNull
private TetherUpstream6Key makeUpstream6Key(int downstreamIfindex, @NonNull MacAddress inDstMac,
@NonNull IpPrefix sourcePrefix) {
byte[] prefixBytes = Arrays.copyOf(sourcePrefix.getRawAddress(), 8);
long prefix64 = ByteBuffer.wrap(prefixBytes).order(ByteOrder.BIG_ENDIAN).getLong();
return new TetherUpstream6Key(downstreamIfindex, inDstMac, prefix64);
}
@Override @Override
public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, public boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
@NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac, @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
@NonNull MacAddress outDstMac, int mtu) { @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu) {
if (!isInitialized()) return false; if (!isInitialized()) return false;
// RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
if (sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac); final TetherUpstream6Key key = makeUpstream6Key(downstreamIfindex, inDstMac, sourcePrefix);
final Tether6Value value = new Tether6Value(upstreamIfindex, outSrcMac, final Tether6Value value = new Tether6Value(upstreamIfindex, outSrcMac,
outDstMac, OsConstants.ETH_P_IPV6, mtu); outDstMac, OsConstants.ETH_P_IPV6, mtu);
try { try {
...@@ -216,10 +231,12 @@ public class BpfCoordinatorShimImpl ...@@ -216,10 +231,12 @@ public class BpfCoordinatorShimImpl
@Override @Override
public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, public boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
@NonNull MacAddress inDstMac) { @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac) {
if (!isInitialized()) return false; if (!isInitialized()) return false;
// RFC7421_PREFIX_LENGTH = 64 which is the most commonly used IPv6 subnet prefix length.
if (sourcePrefix.getPrefixLength() != RFC7421_PREFIX_LENGTH) return false;
final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfindex, inDstMac); final TetherUpstream6Key key = makeUpstream6Key(downstreamIfindex, inDstMac, sourcePrefix);
try { try {
mBpfUpstream6Map.deleteEntry(key); mBpfUpstream6Map.deleteEntry(key);
} catch (ErrnoException e) { } catch (ErrnoException e) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package com.android.networkstack.tethering.apishim.common; package com.android.networkstack.tethering.apishim.common;
import android.net.IpPrefix;
import android.net.MacAddress; import android.net.MacAddress;
import android.util.SparseArray; import android.util.SparseArray;
...@@ -79,25 +80,27 @@ public abstract class BpfCoordinatorShim { ...@@ -79,25 +80,27 @@ public abstract class BpfCoordinatorShim {
* @param downstreamIfindex the downstream interface index * @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index * @param upstreamIfindex the upstream interface index
* @param sourcePrefix the source IPv6 prefix
* @param inDstMac the destination MAC address to use for XDP * @param inDstMac the destination MAC address to use for XDP
* @param outSrcMac the source MAC address to use for packets * @param outSrcMac the source MAC address to use for packets
* @param outDstMac the destination 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 * @return true if operation succeeded or was a no-op, false otherwise
*/ */
public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex, public abstract boolean startUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
@NonNull MacAddress inDstMac, @NonNull MacAddress outSrcMac, @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac,
@NonNull MacAddress outDstMac, int mtu); @NonNull MacAddress outSrcMac, @NonNull MacAddress outDstMac, int mtu);
/** /**
* Stops IPv6 forwarding between the specified interfaces. * Stops IPv6 forwarding between the specified interfaces.
* @param downstreamIfindex the downstream interface index * @param downstreamIfindex the downstream interface index
* @param upstreamIfindex the upstream interface index * @param upstreamIfindex the upstream interface index
* @param sourcePrefix the valid source IPv6 prefix
* @param inDstMac the destination MAC address to use for XDP * @param inDstMac the destination MAC address to use for XDP
* @return true if operation succeeded or was a no-op, false otherwise * @return true if operation succeeded or was a no-op, false otherwise
*/ */
public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, public abstract boolean stopUpstreamIpv6Forwarding(int downstreamIfindex, int upstreamIfindex,
int upstreamIfindex, @NonNull MacAddress inDstMac); @NonNull IpPrefix sourcePrefix, @NonNull MacAddress inDstMac);
/** /**
* Return BPF tethering offload statistics. * Return BPF tethering offload statistics.
......
...@@ -37,6 +37,7 @@ import static com.android.networkstack.tethering.util.TetheringUtils.getTetherin ...@@ -37,6 +37,7 @@ import static com.android.networkstack.tethering.util.TetheringUtils.getTetherin
import android.app.usage.NetworkStatsManager; import android.app.usage.NetworkStatsManager;
import android.net.INetd; import android.net.INetd;
import android.net.IpPrefix;
import android.net.LinkProperties; import android.net.LinkProperties;
import android.net.MacAddress; import android.net.MacAddress;
import android.net.NetworkStats; import android.net.NetworkStats;
...@@ -119,6 +120,7 @@ public class BpfCoordinator { ...@@ -119,6 +120,7 @@ public class BpfCoordinator {
private static final int DUMP_TIMEOUT_MS = 10_000; private static final int DUMP_TIMEOUT_MS = 10_000;
private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString( private static final MacAddress NULL_MAC_ADDRESS = MacAddress.fromString(
"00:00:00:00:00:00"); "00:00:00:00:00:00");
private static final IpPrefix IPV6_ZERO_PREFIX64 = new IpPrefix("::/64");
private static final String TETHER_DOWNSTREAM4_MAP_PATH = makeMapPath(DOWNSTREAM, 4); private static final String TETHER_DOWNSTREAM4_MAP_PATH = makeMapPath(DOWNSTREAM, 4);
private static final String TETHER_UPSTREAM4_MAP_PATH = makeMapPath(UPSTREAM, 4); private static final String TETHER_UPSTREAM4_MAP_PATH = makeMapPath(UPSTREAM, 4);
private static final String TETHER_DOWNSTREAM6_FS_PATH = makeMapPath(DOWNSTREAM, 6); private static final String TETHER_DOWNSTREAM6_FS_PATH = makeMapPath(DOWNSTREAM, 6);
...@@ -615,8 +617,9 @@ public class BpfCoordinator { ...@@ -615,8 +617,9 @@ public class BpfCoordinator {
final int upstream = rule.upstreamIfindex; final int upstream = rule.upstreamIfindex;
// TODO: support upstream forwarding on non-point-to-point interfaces. // TODO: support upstream forwarding on non-point-to-point interfaces.
// TODO: get the MTU from LinkProperties and update the rules when it changes. // TODO: get the MTU from LinkProperties and update the rules when it changes.
if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream, rule.srcMac, if (!mBpfCoordinatorShim.startUpstreamIpv6Forwarding(downstream, upstream,
NULL_MAC_ADDRESS, NULL_MAC_ADDRESS, NetworkStackConstants.ETHER_MTU)) { IPV6_ZERO_PREFIX64, rule.srcMac, NULL_MAC_ADDRESS, NULL_MAC_ADDRESS,
NetworkStackConstants.ETHER_MTU)) {
mLog.e("Failed to enable upstream IPv6 forwarding from " mLog.e("Failed to enable upstream IPv6 forwarding from "
+ getIfName(downstream) + " to " + getIfName(upstream)); + getIfName(downstream) + " to " + getIfName(upstream));
} }
...@@ -657,7 +660,7 @@ public class BpfCoordinator { ...@@ -657,7 +660,7 @@ public class BpfCoordinator {
final int downstream = rule.downstreamIfindex; final int downstream = rule.downstreamIfindex;
final int upstream = rule.upstreamIfindex; final int upstream = rule.upstreamIfindex;
if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream, if (!mBpfCoordinatorShim.stopUpstreamIpv6Forwarding(downstream, upstream,
rule.srcMac)) { IPV6_ZERO_PREFIX64, rule.srcMac)) {
mLog.e("Failed to disable upstream IPv6 forwarding from " mLog.e("Failed to disable upstream IPv6 forwarding from "
+ getIfName(downstream) + " to " + getIfName(upstream)); + getIfName(downstream) + " to " + getIfName(upstream));
} }
......
...@@ -29,13 +29,17 @@ public class TetherUpstream6Key extends Struct { ...@@ -29,13 +29,17 @@ public class TetherUpstream6Key extends Struct {
@Field(order = 0, type = Type.S32) @Field(order = 0, type = Type.S32)
public final int iif; // The input interface index. public final int iif; // The input interface index.
@Field(order = 1, type = Type.EUI48, padding = 2) @Field(order = 1, type = Type.EUI48, padding = 6)
public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress). public final MacAddress dstMac; // Destination ethernet mac address (zeroed iff rawip ingress).
public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac) { @Field(order = 2, type = Type.S64)
public final long src64; // The top 64-bits of the source ip.
public TetherUpstream6Key(int iif, @NonNull final MacAddress dstMac, long src64) {
Objects.requireNonNull(dstMac); Objects.requireNonNull(dstMac);
this.iif = iif; this.iif = iif;
this.dstMac = dstMac; this.dstMac = dstMac;
this.src64 = src64;
} }
} }
...@@ -985,7 +985,7 @@ public class IpServerTest { ...@@ -985,7 +985,7 @@ public class IpServerTest {
throws Exception { throws Exception {
if (!mBpfDeps.isAtLeastS()) return; 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); TEST_IFACE_PARAMS.macAddr, 0);
final Tether6Value value = new Tether6Value(upstreamIfindex, final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU); ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
...@@ -996,7 +996,7 @@ public class IpServerTest { ...@@ -996,7 +996,7 @@ public class IpServerTest {
throws Exception { throws Exception {
if (!mBpfDeps.isAtLeastS()) return; 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); TEST_IFACE_PARAMS.macAddr, 0);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key); verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
} }
......
...@@ -641,7 +641,7 @@ public class BpfCoordinatorTest { ...@@ -641,7 +641,7 @@ public class BpfCoordinatorTest {
private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex, private void verifyStartUpstreamIpv6Forwarding(@Nullable InOrder inOrder, int downstreamIfIndex,
MacAddress downstreamMac, int upstreamIfindex) throws Exception { MacAddress downstreamMac, int upstreamIfindex) throws Exception {
if (!mDeps.isAtLeastS()) return; if (!mDeps.isAtLeastS()) return;
final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac); final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
final Tether6Value value = new Tether6Value(upstreamIfindex, final Tether6Value value = new Tether6Value(upstreamIfindex,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU); ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
...@@ -652,7 +652,7 @@ public class BpfCoordinatorTest { ...@@ -652,7 +652,7 @@ public class BpfCoordinatorTest {
MacAddress downstreamMac) MacAddress downstreamMac)
throws Exception { throws Exception {
if (!mDeps.isAtLeastS()) return; if (!mDeps.isAtLeastS()) return;
final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac); final TetherUpstream6Key key = new TetherUpstream6Key(downstreamIfIndex, downstreamMac, 0);
verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key); verifyWithOrder(inOrder, mBpfUpstream6Map).deleteEntry(key);
} }
...@@ -2192,7 +2192,7 @@ public class BpfCoordinatorTest { ...@@ -2192,7 +2192,7 @@ public class BpfCoordinatorTest {
mBpfDownstream6Map.insertEntry(rule.makeTetherDownstream6Key(), rule.makeTether6Value()); mBpfDownstream6Map.insertEntry(rule.makeTetherDownstream6Key(), rule.makeTether6Value());
final TetherUpstream6Key upstream6Key = new TetherUpstream6Key(DOWNSTREAM_IFINDEX, final TetherUpstream6Key upstream6Key = new TetherUpstream6Key(DOWNSTREAM_IFINDEX,
DOWNSTREAM_MAC); DOWNSTREAM_MAC, 0);
final Tether6Value upstream6Value = new Tether6Value(UPSTREAM_IFINDEX, final Tether6Value upstream6Value = new Tether6Value(UPSTREAM_IFINDEX,
MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS,
ETH_P_IPV6, NetworkStackConstants.ETHER_MTU); ETH_P_IPV6, NetworkStackConstants.ETHER_MTU);
......
...@@ -194,6 +194,7 @@ static inline __always_inline int do_forward6(struct __sk_buff* skb, const bool ...@@ -194,6 +194,7 @@ static inline __always_inline int do_forward6(struct __sk_buff* skb, const bool
TetherUpstream6Key ku = { TetherUpstream6Key ku = {
.iif = skb->ifindex, .iif = skb->ifindex,
.src64 = 0,
}; };
if (is_ethernet) __builtin_memcpy(downstream ? kd.dstMac : ku.dstMac, eth->h_dest, ETH_ALEN); if (is_ethernet) __builtin_memcpy(downstream ? kd.dstMac : ku.dstMac, eth->h_dest, ETH_ALEN);
......
...@@ -135,10 +135,10 @@ STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8); // 40 ...@@ -135,10 +135,10 @@ STRUCT_SIZE(TetherDownstream64Value, 4 + 14 + 2 + 4 + 4 + 2 + 2 + 8); // 40
typedef struct { typedef struct {
uint32_t iif; // The input interface index uint32_t iif; // The input interface index
uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress) uint8_t dstMac[ETH_ALEN]; // destination ethernet mac address (zeroed iff rawip ingress)
uint8_t zero[2]; // zero pad for 8 byte alignment uint8_t zero[6]; // zero pad for 8 byte alignment
// TODO: extend this to include src ip /64 subnet uint64_t src64; // Top 64-bits of the src ip
} TetherUpstream6Key; } TetherUpstream6Key;
STRUCT_SIZE(TetherUpstream6Key, 12); STRUCT_SIZE(TetherUpstream6Key, 4 + 6 + 6 + 8); // 24
typedef struct { typedef struct {
uint32_t iif; // The input interface index uint32_t iif; // The input interface index
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment