add support for marking ebpf programs as being only for some kernel versions

Some ebpf code cannot be loaded on too old kernels.

Sometimes we want a different - more advanced - version of an ebpf program
to be loaded on a newer kernel.

Test: build, atest
Signed-off-by: Maciej Żenczykowski <maze@google.com>
Change-Id: I9e93e7246951916e6d60544575337a7a19c82886
diff --git a/progs/include/bpf_helpers.h b/progs/include/bpf_helpers.h
index fbdcb2f..09c3373 100644
--- a/progs/include/bpf_helpers.h
+++ b/progs/include/bpf_helpers.h
@@ -98,10 +98,25 @@
 static unsigned long long (*bpf_get_current_uid_gid)(void) = (void*) BPF_FUNC_get_current_uid_gid;
 static unsigned long long (*bpf_get_smp_processor_id)(void) = (void*) BPF_FUNC_get_smp_processor_id;
 
-#define DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
-    const struct bpf_prog_def SEC("progs") the_prog##_def = {       \
-            .uid = (prog_uid),                                      \
-            .gid = (prog_gid),                                      \
-    };                                                              \
-    SEC(SECTION_NAME)                                               \
+#define KVER_NONE 0
+#define KVER(a, b, c) ((a)*65536 + (b)*256 + (c))
+#define KVER_INF 0xFFFFFFFF
+
+// programs requiring a kernel version >= min_kv && < max_kv
+#define DEFINE_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, max_kv) \
+    const struct bpf_prog_def SEC("progs") the_prog##_def = {                                  \
+            .uid = (prog_uid),                                                                 \
+            .gid = (prog_gid),                                                                 \
+            .min_kver = (min_kv),                                                              \
+            .max_kver = (max_kv),                                                              \
+    };                                                                                         \
+    SEC(SECTION_NAME)                                                                          \
     int the_prog
+
+// programs requiring a kernel version >= min_kv
+#define DEFINE_BPF_PROG_KVER(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv) \
+    DEFINE_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, min_kv, KVER_INF)
+
+// programs with no kernel version requirements
+#define DEFINE_BPF_PROG(SECTION_NAME, prog_uid, prog_gid, the_prog) \
+    DEFINE_BPF_PROG_KVER_RANGE(SECTION_NAME, prog_uid, prog_gid, the_prog, 0, KVER_INF)
diff --git a/progs/include/bpf_map_def.h b/progs/include/bpf_map_def.h
index 03ca73b..01d9b8e 100644
--- a/progs/include/bpf_map_def.h
+++ b/progs/include/bpf_map_def.h
@@ -57,4 +57,7 @@
 struct bpf_prog_def {
     unsigned int uid;
     unsigned int gid;
+
+    unsigned int min_kver;  // KERNEL_MAJOR * 65536 + KERNEL_MINOR * 256 + KERNEL_SUB
+    unsigned int max_kver;  // ie. 0x40900 for Linux 4.9 - but beware of hexadecimal for >= 10
 };