Loading services/net/java/android/net/apf/ApfFilter.java +4 −5 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ public class ApfFilter { ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN); } // Note that this parses RA and may throw IllegalArgumentException (from // Note that this parses RA and may throw InvalidRaException (from // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with // specifications. Loading Loading @@ -986,9 +986,8 @@ public class ApfFilter { */ @GuardedBy("this") private ApfGenerator beginProgramLocked() throws IllegalInstructionException { ApfGenerator gen = new ApfGenerator(); // This is guaranteed to return true because of the check in maybeCreate. gen.setApfVersion(mApfCapabilities.apfVersionSupported); // This is guaranteed to succeed because of the check in maybeCreate. ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported); // Here's a basic summary of what the initial program does: // Loading Loading @@ -1216,7 +1215,7 @@ public class ApfFilter { // 1. the program generator will need its offsets adjusted. // 2. the packet filter attached to our packet socket will need its offset adjusted. if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null; if (!new ApfGenerator().setApfVersion(apfCapabilities.apfVersionSupported)) { if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) { Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported); return null; } Loading services/net/java/android/net/apf/ApfGenerator.java +57 −6 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ public class ApfGenerator { JLT(18), // Compare less than and branch, e.g. "jlt R0,5,label" JSET(19), // Compare any bits set and branch, e.g. "jset R0,5,label" JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455" EXT(21); // Followed by immediate indicating ExtendedOpcodes. EXT(21), // Followed by immediate indicating ExtendedOpcodes. LDDW(22), // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1" STDW(23); // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1" final int value; Loading Loading @@ -355,19 +357,38 @@ public class ApfGenerator { */ public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT; // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h private static final int MIN_APF_VERSION = 2; private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>(); private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>(); private final Instruction mDropLabel = new Instruction(Opcodes.LABEL); private final Instruction mPassLabel = new Instruction(Opcodes.LABEL); private final int mVersion; private boolean mGenerated; /** * Set version of APF instruction set to generate instructions for. Returns {@code true} * if generating for this version is supported, {@code false} otherwise. * Creates an ApfGenerator instance which is able to emit instructions for the specified * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if * the requested version is unsupported. */ public boolean setApfVersion(int version) { // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h return version >= 2; ApfGenerator(int version) throws IllegalInstructionException { mVersion = version; requireApfVersion(MIN_APF_VERSION); } /** * Returns true if the specified {@code version} is supported by the ApfGenerator, otherwise * false. */ public static boolean supportsVersion(int version) { return version >= MIN_APF_VERSION; } private void requireApfVersion(int minimumVersion) throws IllegalInstructionException { if (mVersion < minimumVersion) { throw new IllegalInstructionException("Requires APF >= " + minimumVersion); } } private void addInstruction(Instruction instruction) { Loading Loading @@ -818,6 +839,36 @@ public class ApfGenerator { return this; } /** * Add an instruction to the end of the program to load 32 bits from the data memory into * {@code register}. The source address is computed by adding @{code offset} to the other * register. * Requires APF v3 or greater. */ public ApfGenerator addLoadData(Register destinationRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister); instruction.setUnsignedImm(offset); addInstruction(instruction); return this; } /** * Add an instruction to the end of the program to store 32 bits from {@code register} into the * data memory. The destination address is computed by adding @{code offset} to the other * register. * Requires APF v3 or greater. */ public ApfGenerator addStoreData(Register sourceRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister); instruction.setUnsignedImm(offset); addInstruction(instruction); return this; } /** * Updates instruction offset fields using latest instruction sizes. * @return current program length in bytes. Loading tests/net/java/android/net/apf/ApfTest.java +223 −84 File changed.Preview size limit exceeded, changes collapsed. Show changes tests/net/java/android/net/apf/Bpf2Apf.java +2 −2 Original line number Diff line number Diff line Loading @@ -307,7 +307,7 @@ public class Bpf2Apf { * program and return it. */ public static byte[] convert(String bpf) throws IllegalInstructionException { ApfGenerator gen = new ApfGenerator(); ApfGenerator gen = new ApfGenerator(3); for (String line : bpf.split("\\n")) convertLine(line, gen); return gen.generate(); } Loading @@ -320,7 +320,7 @@ public class Bpf2Apf { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String line = null; StringBuilder responseData = new StringBuilder(); ApfGenerator gen = new ApfGenerator(); ApfGenerator gen = new ApfGenerator(3); while ((line = in.readLine()) != null) convertLine(line, gen); System.out.write(gen.generate()); } Loading tests/net/jni/apf_jni.cpp +18 −11 Original line number Diff line number Diff line /* * Copyright 2016, The Android Open Source Project * Copyright 2018, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -28,15 +28,22 @@ // JNI function acting as simply call-through to native APF interpreter. static jint com_android_server_ApfTest_apfSimulate( JNIEnv* env, jclass, jbyteArray program, jbyteArray packet, jint filter_age) { return accept_packet( (uint8_t*)env->GetByteArrayElements(program, NULL), env->GetArrayLength(program), (uint8_t*)env->GetByteArrayElements(packet, NULL), env->GetArrayLength(packet), nullptr, 0, filter_age); JNIEnv* env, jclass, jbyteArray program, jbyteArray packet, jbyteArray data, jint filter_age) { uint8_t* program_raw = (uint8_t*)env->GetByteArrayElements(program, nullptr); uint8_t* packet_raw = (uint8_t*)env->GetByteArrayElements(packet, nullptr); uint8_t* data_raw = (uint8_t*)(data ? env->GetByteArrayElements(data, nullptr) : nullptr); uint32_t program_len = env->GetArrayLength(program); uint32_t packet_len = env->GetArrayLength(packet); uint32_t data_len = data ? env->GetArrayLength(data) : 0; jint result = accept_packet(program_raw, program_len, packet_raw, packet_len, data_raw, data_len, filter_age); if (data) { env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */); } env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT); env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT); return result; } class ScopedPcap { Loading Loading @@ -170,7 +177,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { } static JNINativeMethod gMethods[] = { { "apfSimulate", "([B[BI)I", { "apfSimulate", "([B[B[BI)I", (void*)com_android_server_ApfTest_apfSimulate }, { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;", (void*)com_android_server_ApfTest_compileToBpf }, Loading Loading
services/net/java/android/net/apf/ApfFilter.java +4 −5 Original line number Diff line number Diff line Loading @@ -522,7 +522,7 @@ public class ApfFilter { ICMP6_4_BYTE_LIFETIME_OFFSET, ICMP6_4_BYTE_LIFETIME_LEN); } // Note that this parses RA and may throw IllegalArgumentException (from // Note that this parses RA and may throw InvalidRaException (from // Buffer.position(int) or due to an invalid-length option) or IndexOutOfBoundsException // (from ByteBuffer.get(int) ) if parsing encounters something non-compliant with // specifications. Loading Loading @@ -986,9 +986,8 @@ public class ApfFilter { */ @GuardedBy("this") private ApfGenerator beginProgramLocked() throws IllegalInstructionException { ApfGenerator gen = new ApfGenerator(); // This is guaranteed to return true because of the check in maybeCreate. gen.setApfVersion(mApfCapabilities.apfVersionSupported); // This is guaranteed to succeed because of the check in maybeCreate. ApfGenerator gen = new ApfGenerator(mApfCapabilities.apfVersionSupported); // Here's a basic summary of what the initial program does: // Loading Loading @@ -1216,7 +1215,7 @@ public class ApfFilter { // 1. the program generator will need its offsets adjusted. // 2. the packet filter attached to our packet socket will need its offset adjusted. if (apfCapabilities.apfPacketFormat != ARPHRD_ETHER) return null; if (!new ApfGenerator().setApfVersion(apfCapabilities.apfVersionSupported)) { if (!ApfGenerator.supportsVersion(apfCapabilities.apfVersionSupported)) { Log.e(TAG, "Unsupported APF version: " + apfCapabilities.apfVersionSupported); return null; } Loading
services/net/java/android/net/apf/ApfGenerator.java +57 −6 Original line number Diff line number Diff line Loading @@ -58,7 +58,9 @@ public class ApfGenerator { JLT(18), // Compare less than and branch, e.g. "jlt R0,5,label" JSET(19), // Compare any bits set and branch, e.g. "jset R0,5,label" JNEBS(20), // Compare not equal byte sequence, e.g. "jnebs R0,5,label,0x1122334455" EXT(21); // Followed by immediate indicating ExtendedOpcodes. EXT(21), // Followed by immediate indicating ExtendedOpcodes. LDDW(22), // Load 4 bytes from data memory address (register + immediate): "lddw R0, [5]R1" STDW(23); // Store 4 bytes to data memory address (register + immediate): "stdw R0, [5]R1" final int value; Loading Loading @@ -355,19 +357,38 @@ public class ApfGenerator { */ public static final int LAST_PREFILLED_MEMORY_SLOT = FILTER_AGE_MEMORY_SLOT; // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h private static final int MIN_APF_VERSION = 2; private final ArrayList<Instruction> mInstructions = new ArrayList<Instruction>(); private final HashMap<String, Instruction> mLabels = new HashMap<String, Instruction>(); private final Instruction mDropLabel = new Instruction(Opcodes.LABEL); private final Instruction mPassLabel = new Instruction(Opcodes.LABEL); private final int mVersion; private boolean mGenerated; /** * Set version of APF instruction set to generate instructions for. Returns {@code true} * if generating for this version is supported, {@code false} otherwise. * Creates an ApfGenerator instance which is able to emit instructions for the specified * {@code version} of the APF interpreter. Throws {@code IllegalInstructionException} if * the requested version is unsupported. */ public boolean setApfVersion(int version) { // This version number syncs up with APF_VERSION in hardware/google/apf/apf_interpreter.h return version >= 2; ApfGenerator(int version) throws IllegalInstructionException { mVersion = version; requireApfVersion(MIN_APF_VERSION); } /** * Returns true if the specified {@code version} is supported by the ApfGenerator, otherwise * false. */ public static boolean supportsVersion(int version) { return version >= MIN_APF_VERSION; } private void requireApfVersion(int minimumVersion) throws IllegalInstructionException { if (mVersion < minimumVersion) { throw new IllegalInstructionException("Requires APF >= " + minimumVersion); } } private void addInstruction(Instruction instruction) { Loading Loading @@ -818,6 +839,36 @@ public class ApfGenerator { return this; } /** * Add an instruction to the end of the program to load 32 bits from the data memory into * {@code register}. The source address is computed by adding @{code offset} to the other * register. * Requires APF v3 or greater. */ public ApfGenerator addLoadData(Register destinationRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.LDDW, destinationRegister); instruction.setUnsignedImm(offset); addInstruction(instruction); return this; } /** * Add an instruction to the end of the program to store 32 bits from {@code register} into the * data memory. The destination address is computed by adding @{code offset} to the other * register. * Requires APF v3 or greater. */ public ApfGenerator addStoreData(Register sourceRegister, int offset) throws IllegalInstructionException { requireApfVersion(3); Instruction instruction = new Instruction(Opcodes.STDW, sourceRegister); instruction.setUnsignedImm(offset); addInstruction(instruction); return this; } /** * Updates instruction offset fields using latest instruction sizes. * @return current program length in bytes. Loading
tests/net/java/android/net/apf/ApfTest.java +223 −84 File changed.Preview size limit exceeded, changes collapsed. Show changes
tests/net/java/android/net/apf/Bpf2Apf.java +2 −2 Original line number Diff line number Diff line Loading @@ -307,7 +307,7 @@ public class Bpf2Apf { * program and return it. */ public static byte[] convert(String bpf) throws IllegalInstructionException { ApfGenerator gen = new ApfGenerator(); ApfGenerator gen = new ApfGenerator(3); for (String line : bpf.split("\\n")) convertLine(line, gen); return gen.generate(); } Loading @@ -320,7 +320,7 @@ public class Bpf2Apf { BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); String line = null; StringBuilder responseData = new StringBuilder(); ApfGenerator gen = new ApfGenerator(); ApfGenerator gen = new ApfGenerator(3); while ((line = in.readLine()) != null) convertLine(line, gen); System.out.write(gen.generate()); } Loading
tests/net/jni/apf_jni.cpp +18 −11 Original line number Diff line number Diff line /* * Copyright 2016, The Android Open Source Project * Copyright 2018, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading Loading @@ -28,15 +28,22 @@ // JNI function acting as simply call-through to native APF interpreter. static jint com_android_server_ApfTest_apfSimulate( JNIEnv* env, jclass, jbyteArray program, jbyteArray packet, jint filter_age) { return accept_packet( (uint8_t*)env->GetByteArrayElements(program, NULL), env->GetArrayLength(program), (uint8_t*)env->GetByteArrayElements(packet, NULL), env->GetArrayLength(packet), nullptr, 0, filter_age); JNIEnv* env, jclass, jbyteArray program, jbyteArray packet, jbyteArray data, jint filter_age) { uint8_t* program_raw = (uint8_t*)env->GetByteArrayElements(program, nullptr); uint8_t* packet_raw = (uint8_t*)env->GetByteArrayElements(packet, nullptr); uint8_t* data_raw = (uint8_t*)(data ? env->GetByteArrayElements(data, nullptr) : nullptr); uint32_t program_len = env->GetArrayLength(program); uint32_t packet_len = env->GetArrayLength(packet); uint32_t data_len = data ? env->GetArrayLength(data) : 0; jint result = accept_packet(program_raw, program_len, packet_raw, packet_len, data_raw, data_len, filter_age); if (data) { env->ReleaseByteArrayElements(data, (jbyte*)data_raw, 0 /* copy back */); } env->ReleaseByteArrayElements(packet, (jbyte*)packet_raw, JNI_ABORT); env->ReleaseByteArrayElements(program, (jbyte*)program_raw, JNI_ABORT); return result; } class ScopedPcap { Loading Loading @@ -170,7 +177,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void*) { } static JNINativeMethod gMethods[] = { { "apfSimulate", "([B[BI)I", { "apfSimulate", "([B[B[BI)I", (void*)com_android_server_ApfTest_apfSimulate }, { "compileToBpf", "(Ljava/lang/String;)Ljava/lang/String;", (void*)com_android_server_ApfTest_compileToBpf }, Loading