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/libbpf_android/Loader.cpp b/libbpf_android/Loader.cpp
index 8f139a3..ce710a4 100644
--- a/libbpf_android/Loader.cpp
+++ b/libbpf_android/Loader.cpp
@@ -30,6 +30,7 @@
 
 #include "../progs/include/bpf_map_def.h"
 #include "LoaderUtils.h"
+#include "bpf/BpfUtils.h"
 #include "include/libbpf_android.h"
 
 #include <cstdlib>
@@ -531,9 +532,10 @@
 }
 
 static int loadCodeSections(const char* elfPath, vector<codeSection>& cs, const string& license) {
-    int ret, fd, kvers;
+    unsigned kvers = kernelVersion();
+    int ret, fd;
 
-    if ((kvers = getMachineKvers()) < 0) return -1;
+    if (!kvers) return -1;
 
     string fname = pathToFilename(string(elfPath), true);
 
@@ -541,6 +543,11 @@
         string progPinLoc;
         bool reuse = false;
 
+        if (cs[i].prog_def.has_value()) {
+            if (kvers < cs[i].prog_def->min_kver) continue;
+            if (kvers >= cs[i].prog_def->max_kver) continue;
+        }
+
         // Format of pin location is
         // /sys/fs/bpf/prog_<filename>_<mapname>
         progPinLoc = string(BPF_FS_PATH) + "prog_" + fname + "_" + cs[i].name;