Test for bpf read/write only map

Add two test to verify the kernel patch of creating and using bpf map in
read only and write only mode.

Test: new test pass on 4.9 kernel and above.
Bug: 30950746
Change-Id: I74e94a9ef4b4e23bb4f9e00340ecf701e1f13060
diff --git a/net/test/bpf.py b/net/test/bpf.py
index a96a95a..ff23d79 100755
--- a/net/test/bpf.py
+++ b/net/test/bpf.py
@@ -144,11 +144,14 @@
 BPF_FUNC_get_socket_cookie = 46
 BPF_FUNC_get_socket_uid = 47
 
+BPF_F_RDONLY = 1 << 3
+BPF_F_WRONLY = 1 << 4
+
 #  These object below belongs to the same kernel union and the types below
 #  (e.g., bpf_attr_create) aren't kernel struct names but just different
 #  variants of the union.
-BpfAttrCreate = cstruct.Struct("bpf_attr_create", "=IIII",
-                               "map_type key_size value_size max_entries")
+BpfAttrCreate = cstruct.Struct("bpf_attr_create", "=IIIII",
+                               "map_type key_size value_size max_entries, map_flags")
 BpfAttrOps = cstruct.Struct("bpf_attr_ops", "=QQQQ",
                             "map_fd key_ptr value_ptr flags")
 BpfAttrProgLoad = cstruct.Struct(
@@ -168,8 +171,8 @@
   csocket.MaybeRaiseSocketError(ret)
   return ret
 
-def CreateMap(map_type, key_size, value_size, max_entries):
-  attr = BpfAttrCreate((map_type, key_size, value_size, max_entries))
+def CreateMap(map_type, key_size, value_size, max_entries, map_flags=0):
+  attr = BpfAttrCreate((map_type, key_size, value_size, max_entries, map_flags))
   return BpfSyscall(BPF_MAP_CREATE, attr)
 
 
diff --git a/net/test/bpf_test.py b/net/test/bpf_test.py
index 7014da4..9da3907 100755
--- a/net/test/bpf_test.py
+++ b/net/test/bpf_test.py
@@ -194,6 +194,27 @@
         self.assertEquals(value, LookupMap(self.map_fd, key).value)
         count += 1
 
+  # TODO: move this check to the begining of the class insdead.
+  @unittest.skipUnless(HAVE_EBPF_ACCOUNTING,
+                       "BPF helper function is not fully supported")
+  def testRdOnlyMap(self):
+    self.map_fd = CreateMap(BPF_MAP_TYPE_HASH, KEY_SIZE, VALUE_SIZE,
+                            TOTAL_ENTRIES, map_flags=BPF_F_RDONLY)
+    value = 1024
+    key = 1
+    self.assertRaisesErrno(errno.EPERM, UpdateMap, self.map_fd, key, value)
+    self.assertRaisesErrno(errno.ENOENT, LookupMap, self.map_fd, key)
+
+  @unittest.skipUnless(HAVE_EBPF_ACCOUNTING,
+                       "BPF helper function is not fully supported")
+  def testWrOnlyMap(self):
+    self.map_fd = CreateMap(BPF_MAP_TYPE_HASH, KEY_SIZE, VALUE_SIZE,
+                            TOTAL_ENTRIES, map_flags=BPF_F_WRONLY)
+    value = 1024
+    key = 1
+    UpdateMap(self.map_fd, key, value)
+    self.assertRaisesErrno(errno.EPERM, LookupMap, self.map_fd, key)
+
   def testProgLoad(self):
     # Move skb to BPF_REG_6 for further usage
     instructions = [