make java maps grab locks

The java bpfmap fd cache has some implications:
- this won't protect against two SingleWriterBpfMap instantiations
  for the same map (path) in the same process
- we don't release any locks on BpfMap destruction.

Test: TreeHugger
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: Ibb0b1f57974c307ea5e0fa699ce8d598c59f456e
diff --git a/staticlibs/device/com/android/net/module/util/BpfMap.java b/staticlibs/device/com/android/net/module/util/BpfMap.java
index da77ae8..dafff20 100644
--- a/staticlibs/device/com/android/net/module/util/BpfMap.java
+++ b/staticlibs/device/com/android/net/module/util/BpfMap.java
@@ -52,6 +52,9 @@
     public static final int BPF_F_RDONLY = 1 << 3;
     public static final int BPF_F_WRONLY = 1 << 4;
 
+    // magic value for jni consumption, invalid from kernel point of view
+    public static final int BPF_F_RDWR_EXCLUSIVE = BPF_F_RDONLY | BPF_F_WRONLY;
+
     public static final int BPF_MAP_TYPE_HASH = 1;
 
     private static final int BPF_F_NO_PREALLOC = 1;
diff --git a/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java b/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java
index 254995f..bbd921d 100644
--- a/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java
+++ b/staticlibs/device/com/android/net/module/util/SingleWriterBpfMap.java
@@ -63,7 +63,7 @@
 
     public SingleWriterBpfMap(@NonNull final String path, final Class<K> key,
             final Class<V> value) throws ErrnoException, NullPointerException {
-        super(path, BPF_F_RDWR, key, value);
+        super(path, BPF_F_RDWR_EXCLUSIVE, key, value);
 
         // Populate cache with the current map contents.
         K currentKey = super.getFirstKey();
diff --git a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp
index b92f107..1923ceb 100644
--- a/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp
+++ b/staticlibs/native/bpfmapjni/com_android_net_module_util_BpfMap.cpp
@@ -35,7 +35,24 @@
         jstring path, jint mode, jint keySize, jint valueSize) {
     ScopedUtfChars pathname(env, path);
 
-    jint fd = bpf::bpfFdGet(pathname.c_str(), static_cast<unsigned>(mode));
+    jint fd = -1;
+    switch (mode) {
+      case 0:
+        fd = bpf::mapRetrieveRW(pathname.c_str());
+        break;
+      case BPF_F_RDONLY:
+        fd = bpf::mapRetrieveRO(pathname.c_str());
+        break;
+      case BPF_F_WRONLY:
+        fd = bpf::mapRetrieveWO(pathname.c_str());
+        break;
+      case BPF_F_RDONLY|BPF_F_WRONLY:
+        fd = bpf::mapRetrieveExclusiveRW(pathname.c_str());
+        break;
+      default:
+        errno = EINVAL;
+        break;
+    }
 
     if (fd < 0) {
         jniThrowErrnoException(env, "nativeBpfFdGet", errno);