From fad7f9d8b722c7270e3e3ead31bc43f87101cd9d Mon Sep 17 00:00:00 2001 From: Ken Chen Date: Wed, 10 Nov 2021 22:02:57 +0800 Subject: [PATCH] [NETD-BPF#34] Add a tag for bpf to specify the install folder Currently, the bpf module netd.o (source system/netd/bpf_progs/netd.c) will be built to /system/etc/bpf/netd.o. In Android T, it will be moved to mainline module com.android.tethering. The expected behavior is: - In T device, it uses the netd.o in mainline module. - In pre-T devices, it uses the original netd, built from platform. However, netd.o will be double loaded if the tethering module is installed in Pre-T devices. Because: 1. bpf in apex is packed into /apex/MAINLINE_MODULE/etc/bpf/ 2. bpf in platform is packed into /system/etc/bpf/ 3. bpfloader in pre-T loads ANY bpf modules under /apex/com.android.tethering/etc/bpf/ and /system/etc/bpf/. We can't change the behavior of bpfloader in pre-T devices. We can't delete the /system/etc/bpf/netd.o from pre-T devices. Both of them are not mainline modules. So the mainlined netd.o needs to be packed into a folder other than /apex/com.android.tethering/etc/bpf/ or /system/etc/bpf/. This commit adds a tag 'sub_dir' for bpf module. The installation path of bpf modules will be: - /system/etc/bpf/SUB_DIR/ (for platform code) - /apex/MAINLINE_MODULE/etc/bpf/SUB_DIR/ (for mainline module) Bug: 202086915 Test: add test in apex_test.go and build Change-Id: Icc6619768ab006de9f86620a7df1bb2853eaba13 --- apex/apex.go | 7 ++++--- apex/apex_test.go | 9 ++++++++- bpf/bpf.go | 14 +++++++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/apex/apex.go b/apex/apex.go index 1f0618750..023885ae1 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1574,8 +1574,8 @@ func apexFileForRuntimeResourceOverlay(ctx android.BaseModuleContext, rro java.R return af } -func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, bpfProgram bpf.BpfModule) apexFile { - dirInApex := filepath.Join("etc", "bpf") +func apexFileForBpfProgram(ctx android.BaseModuleContext, builtFile android.Path, apex_sub_dir string, bpfProgram bpf.BpfModule) apexFile { + dirInApex := filepath.Join("etc", "bpf", apex_sub_dir) return newApexFile(ctx, builtFile, builtFile.Base(), dirInApex, etc, bpfProgram) } @@ -1784,8 +1784,9 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { case bpfTag: if bpfProgram, ok := child.(bpf.BpfModule); ok { filesToCopy, _ := bpfProgram.OutputFiles("") + apex_sub_dir := bpfProgram.SubDir() for _, bpfFile := range filesToCopy { - filesInfo = append(filesInfo, apexFileForBpfProgram(ctx, bpfFile, bpfProgram)) + filesInfo = append(filesInfo, apexFileForBpfProgram(ctx, bpfFile, apex_sub_dir, bpfProgram)) } } else { ctx.PropertyErrorf("bpfs", "%q is not a bpf module", depName) diff --git a/apex/apex_test.go b/apex/apex_test.go index 78a6bb8f4..d07c48de5 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -621,7 +621,7 @@ func TestDefaults(t *testing.T) { java_libs: ["myjar"], apps: ["AppFoo"], rros: ["rro"], - bpfs: ["bpf"], + bpfs: ["bpf", "netd_test"], updatable: false, } @@ -674,6 +674,12 @@ func TestDefaults(t *testing.T) { srcs: ["bpf.c", "bpf2.c"], } + bpf { + name: "netd_test", + srcs: ["netd_test.c"], + sub_dir: "netd", + } + `) ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{ "etc/myetc", @@ -683,6 +689,7 @@ func TestDefaults(t *testing.T) { "overlay/blue/rro.apk", "etc/bpf/bpf.o", "etc/bpf/bpf2.o", + "etc/bpf/netd/netd_test.o", }) } diff --git a/bpf/bpf.go b/bpf/bpf.go index fa1a84d04..64d679c80 100644 --- a/bpf/bpf.go +++ b/bpf/bpf.go @@ -54,12 +54,16 @@ type BpfModule interface { android.Module OutputFiles(tag string) (android.Paths, error) + + // Returns the sub install directory if the bpf module is included by apex. + SubDir() string } type BpfProperties struct { Srcs []string `android:"path"` Cflags []string Include_dirs []string + Sub_dir string } type bpf struct { @@ -121,6 +125,10 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { fmt.Fprintln(w) fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) fmt.Fprintln(w) + localModulePath := "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf" + if len(bpf.properties.Sub_dir) > 0 { + localModulePath += "/" + bpf.properties.Sub_dir + } for _, obj := range bpf.objs { objName := name + "_" + obj.Base() names = append(names, objName) @@ -130,7 +138,7 @@ func (bpf *bpf) AndroidMk() android.AndroidMkData { fmt.Fprintln(w, "LOCAL_PREBUILT_MODULE_FILE :=", obj.String()) fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", obj.Base()) fmt.Fprintln(w, "LOCAL_MODULE_CLASS := ETC") - fmt.Fprintln(w, "LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf") + fmt.Fprintln(w, localModulePath) fmt.Fprintln(w, "include $(BUILD_PREBUILT)") fmt.Fprintln(w) } @@ -154,6 +162,10 @@ func (bpf *bpf) OutputFiles(tag string) (android.Paths, error) { } } +func (bpf *bpf) SubDir() string { + return bpf.properties.Sub_dir +} + var _ android.OutputFileProducer = (*bpf)(nil) func BpfFactory() android.Module {