summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChenbo Feng <fengc@google.com>2018-04-12 19:05:19 -0700
committerChenbo Feng <fengc@google.com>2018-05-01 19:34:43 -0700
commitb905757231225cd2d37cd10aeee1bb16e4a544d2 (patch)
treeed82338f91f44db466dd85abf1648e9d8d3bea74
parent0cef0cdcbefe31fea8a169dfd9aa1089a7bbd652 (diff)
downloadnetd-b905757231225cd2d37cd10aeee1bb16e4a544d2.tar.gz
Merge all bpf programs into one
Multiple bpf program can be stored the same binary and we can extract them one by one according to their function name elf header at run time. Store them in one file can reduce the load time by only open one binary file once. Rewrite the elf parser with Slice support. Test: phone boot and eBPF program is loaded and pinned. Bug: 78132446 Change-Id: I96dba91a69654fcac2c022100e954d8b0c4e0718 Merged-In: I96dba91a69654fcac2c022100e954d8b0c4e0718 (cherry picked from aosp commit dbbc000ae4e450b4b4ac9d545d0d1c3995949f89)
-rw-r--r--bpfloader/Android.bp5
-rw-r--r--bpfloader/Android.mk37
-rw-r--r--bpfloader/BpfLoader.cpp163
-rw-r--r--bpfloader/bpf_egress.c23
-rw-r--r--bpfloader/bpf_ingress.c23
-rw-r--r--bpfloader/bpf_kern.c (renamed from bpfloader/xt_bpf_ingress_prog.c)20
-rw-r--r--bpfloader/bpf_kern.obin0 -> 6232 bytes
-rw-r--r--bpfloader/cgroup_bpf_egress_prog.obin2832 -> 0 bytes
-rw-r--r--bpfloader/cgroup_bpf_ingress_prog.obin2832 -> 0 bytes
-rw-r--r--bpfloader/xt_bpf_egress_prog.c25
-rw-r--r--bpfloader/xt_bpf_egress_prog.obin824 -> 0 bytes
-rw-r--r--bpfloader/xt_bpf_ingress_prog.obin824 -> 0 bytes
-rw-r--r--libbpf/include/bpf/bpf_shared.h5
-rw-r--r--libnetdutils/include/netdutils/Slice.h8
14 files changed, 132 insertions, 177 deletions
diff --git a/bpfloader/Android.bp b/bpfloader/Android.bp
index 9a759d16..46b8a1f0 100644
--- a/bpfloader/Android.bp
+++ b/bpfloader/Android.bp
@@ -41,10 +41,7 @@ cc_binary {
],
required: [
- "cgroup_bpf_ingress_prog.o",
- "cgroup_bpf_egress_prog.o",
- "xt_bpf_ingress_prog.o",
- "xt_bpf_egress_prog.o",
+ "bpf_kern.o",
],
}
diff --git a/bpfloader/Android.mk b/bpfloader/Android.mk
index 005abef8..13933767 100644
--- a/bpfloader/Android.mk
+++ b/bpfloader/Android.mk
@@ -1,43 +1,10 @@
LOCAL_PATH:= $(call my-dir)
#######################################
-# bpf_ingress.o
+# bpf_kern.o
include $(CLEAR_VARS)
-LOCAL_MODULE := cgroup_bpf_ingress_prog.o
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf
-
-include $(BUILD_PREBUILT)
-
-#######################################
-# bpf_egress.o
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := cgroup_bpf_egress_prog.o
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf
-
-include $(BUILD_PREBUILT)
-
-#######################################
-# xt_bpf_ingress_prog.o
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := xt_bpf_ingress_prog.o
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf
-
-include $(BUILD_PREBUILT)
-
-#######################################
-# xt_bpf_egress_prog.o
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := xt_bpf_egress_prog.o
+LOCAL_MODULE := bpf_kern.o
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/bpf
diff --git a/bpfloader/BpfLoader.cpp b/bpfloader/BpfLoader.cpp
index 26fb99dd..4b7f74ae 100644
--- a/bpfloader/BpfLoader.cpp
+++ b/bpfloader/BpfLoader.cpp
@@ -50,11 +50,7 @@ using android::base::unique_fd;
using android::netdutils::Slice;
#define BPF_PROG_PATH "/system/etc/bpf"
-
-#define INGRESS_PROG BPF_PROG_PATH"/cgroup_bpf_ingress_prog.o"
-#define EGRESS_PROG BPF_PROG_PATH"/cgroup_bpf_egress_prog.o"
-#define XT_BPF_INGRESS_PROG BPF_PROG_PATH "/xt_bpf_ingress_prog.o"
-#define XT_BPF_EGRESS_PROG BPF_PROG_PATH "/xt_bpf_egress_prog.o"
+#define BPF_PROG_SRC BPF_PROG_PATH "/bpf_kern.o"
#define MAP_LD_CMD_HEAD 0x18
#define FAIL(...) \
@@ -112,7 +108,24 @@ struct ReplacePattern {
}
};
-int loadProg(const char* path, const std::vector<ReplacePattern> &mapPatterns) {
+Slice cgroupIngressProg;
+Slice cgroupEgressProg;
+Slice xtIngressProg;
+Slice xtEgressProg;
+
+Slice getProgFromMem(Slice buffer, Elf64_Shdr* section) {
+ uint64_t progSize = (uint64_t)section->sh_size;
+ Slice progSection = take(drop(buffer, section->sh_offset), progSize);
+ if (progSection.size() < progSize) FAIL("programSection out of bound\n");
+ char* progArray = new char[progSize];
+ Slice progCopy(progArray, progSize);
+ if (copy(progCopy, progSection) != progSize) {
+ FAIL("program cannot be extracted");
+ }
+ return progCopy;
+}
+
+void parseProgramsFromFile(const char* path) {
int fd = open(path, O_RDONLY);
if (fd == -1) {
FAIL("Failed to open %s program: %s", path, strerror(errno));
@@ -127,86 +140,99 @@ int loadProg(const char* path, const std::vector<ReplacePattern> &mapPatterns) {
if ((uint32_t)fileLen < sizeof(Elf64_Ehdr)) FAIL("file size too small for Elf64_Ehdr");
- Elf64_Ehdr* elf = (Elf64_Ehdr*)baseAddr;
+ Slice buffer(baseAddr, fileLen);
+
+ Slice elfHeader = take(buffer, sizeof(Elf64_Ehdr));
+
+ if (elfHeader.size() < sizeof(Elf64_Ehdr)) FAIL("bpf buffer does not have complete elf header");
+ Elf64_Ehdr* elf = (Elf64_Ehdr*)elfHeader.base();
// Find section names string table. This is the section whose index is e_shstrndx.
- if (elf->e_shstrndx == SHN_UNDEF ||
- elf->e_shoff + (elf->e_shstrndx + 1) * sizeof(Elf64_Shdr) > (uint32_t)fileLen) {
+ if (elf->e_shstrndx == SHN_UNDEF) {
FAIL("cannot locate namesSection\n");
}
+ size_t totalSectionSize = (elf->e_shnum) * sizeof(Elf64_Shdr);
+ Slice sections = take(drop(buffer, elf->e_shoff), totalSectionSize);
+ if (sections.size() < totalSectionSize) {
+ FAIL("sections corrupted");
+ }
- Elf64_Shdr* sections = (Elf64_Shdr*)(baseAddr + elf->e_shoff);
-
- Elf64_Shdr* namesSection = sections + elf->e_shstrndx;
+ Slice namesSection = take(drop(sections, elf->e_shstrndx * sizeof(Elf64_Shdr)),
+ sizeof(Elf64_Shdr));
+ if (namesSection.size() != sizeof(Elf64_Shdr)) {
+ FAIL("namesSection corrupted");
+ }
+ size_t strTabOffset = ((Elf64_Shdr*) namesSection.base())->sh_offset;
+ size_t strTabSize = ((Elf64_Shdr*) namesSection.base())->sh_size;
- if (namesSection->sh_offset + namesSection->sh_size > (uint32_t)fileLen)
- FAIL("namesSection out of bound\n");
+ Slice strTab = take(drop(buffer, strTabOffset), strTabSize);
+ if (strTab.size() < strTabSize) {
+ FAIL("string table out of bound\n");
+ }
- const char* strTab = baseAddr + namesSection->sh_offset;
- void* progSection = nullptr;
- uint64_t progSize = 0;
for (int i = 0; i < elf->e_shnum; i++) {
- Elf64_Shdr* section = sections + i;
- if (((char*)section - baseAddr) + sizeof(Elf64_Shdr) > (uint32_t)fileLen) {
- FAIL("next section is out of bound\n");
+ Slice section = take(drop(sections, i * sizeof(Elf64_Shdr)), sizeof(Elf64_Shdr));
+ if (section.size() < sizeof(Elf64_Shdr)) {
+ FAIL("section %d is out of bound, section size: %zu, header size: %zu, total size: %zu",
+ i, section.size(), sizeof(Elf64_Shdr), sections.size());
}
-
- if (!strcmp(strTab + section->sh_name, BPF_PROG_SEC_NAME)) {
- progSection = baseAddr + section->sh_offset;
- progSize = (uint64_t)section->sh_size;
- break;
+ Elf64_Shdr* sectionPtr = (Elf64_Shdr*)section.base();
+ Slice nameSlice = drop(strTab, sectionPtr->sh_name);
+ if (nameSlice.size() == 0) {
+ FAIL("nameSlice out of bound, i: %d, strTabSize: %zu, sh_name: %u", i, strTabSize,
+ sectionPtr->sh_name);
+ }
+ if (!strcmp((char *)nameSlice.base(), BPF_CGROUP_INGRESS_PROG_NAME)) {
+ cgroupIngressProg = getProgFromMem(buffer, sectionPtr);
+ } else if (!strcmp((char *)nameSlice.base(), BPF_CGROUP_EGRESS_PROG_NAME)) {
+ cgroupEgressProg = getProgFromMem(buffer, sectionPtr);
+ } else if (!strcmp((char *)nameSlice.base(), XT_BPF_INGRESS_PROG_NAME)) {
+ xtIngressProg = getProgFromMem(buffer, sectionPtr);
+ } else if (!strcmp((char *)nameSlice.base(), XT_BPF_EGRESS_PROG_NAME)) {
+ xtEgressProg = getProgFromMem(buffer, sectionPtr);
}
}
+}
- if (!progSection) FAIL("program section not found");
- if ((char*)progSection - baseAddr + progSize > (uint32_t)fileLen)
- FAIL("programSection out of bound\n");
-
- char* prog = new char[progSize]();
- memcpy(prog, progSection, progSize);
-
-
- char* mapHead = prog;
- while ((uint64_t)(mapHead - prog + MAP_CMD_SIZE) < progSize) {
+int loadProg(Slice prog, bpf_prog_type type, const std::vector<ReplacePattern>& mapPatterns) {
+ if (prog.size() == 0) {
+ FAIL("Couldn't find or parse program type %d", type);
+ }
+ Slice remaining = prog;
+ while (remaining.size() >= MAP_CMD_SIZE) {
// Scan the program, examining all possible places that might be the start of a map load
- // operation (i.e., all byes of value MAP_LD_CMD_HEAD).
- //
+ // operation (i.e., all bytes of value MAP_LD_CMD_HEAD).
// In each of these places, check whether it is the start of one of the patterns we want to
// replace, and if so, replace it.
- mapHead = (char*)memchr(mapHead, MAP_LD_CMD_HEAD, progSize);
- if (!mapHead) break;
+ Slice mapHead = findFirstMatching(remaining, MAP_LD_CMD_HEAD);
+ if (mapHead.size() < MAP_CMD_SIZE) break;
+ bool replaced = false;
for (const auto& pattern : mapPatterns) {
- if (!memcmp(mapHead, pattern.search.data(), MAP_CMD_SIZE)) {
- memcpy(mapHead, pattern.replace.data(), MAP_CMD_SIZE);
+ if (!memcmp(mapHead.base(), pattern.search.data(), MAP_CMD_SIZE)) {
+ memcpy(mapHead.base(), pattern.replace.data(), MAP_CMD_SIZE);
+ replaced = true;
+ break;
}
}
- mapHead++;
+ remaining = drop(mapHead, replaced ? MAP_CMD_SIZE : sizeof(uint8_t));
}
- Slice insns = Slice(prog, progSize);
char bpf_log_buf[LOG_BUF_SIZE];
Slice bpfLog = Slice(bpf_log_buf, sizeof(bpf_log_buf));
- if (strcmp(path, XT_BPF_INGRESS_PROG) && strcmp(path, XT_BPF_EGRESS_PROG)) {
- return bpfProgLoad(BPF_PROG_TYPE_CGROUP_SKB, insns, "Apache 2.0", 0, bpfLog);
- }
- return bpfProgLoad(BPF_PROG_TYPE_SOCKET_FILTER, insns, "Apache 2.0", 0, bpfLog);
+ return bpfProgLoad(type, prog, "Apache 2.0", 0, bpfLog);
}
int loadAndAttachProgram(bpf_attach_type type, const char* path, const char* name,
std::vector<ReplacePattern> mapPatterns) {
- unique_fd cg_fd(open(CGROUP_ROOT_PATH, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
- if (cg_fd < 0) {
- FAIL("Failed to open the cgroup directory");
- }
unique_fd fd;
if (type == BPF_CGROUP_INET_INGRESS) {
- fd.reset(loadProg(INGRESS_PROG, mapPatterns));
+ fd.reset(loadProg(cgroupIngressProg, BPF_PROG_TYPE_CGROUP_SKB, mapPatterns));
} else if (type == BPF_CGROUP_INET_EGRESS) {
- fd.reset(loadProg(EGRESS_PROG, mapPatterns));
- } else if (!strcmp(name, "xt_bpf_ingress_prog")) {
- fd.reset(loadProg(XT_BPF_INGRESS_PROG, mapPatterns));
- } else if (!strcmp(name, "xt_bpf_egress_prog")) {
- fd.reset(loadProg(XT_BPF_EGRESS_PROG, mapPatterns));
+ fd.reset(loadProg(cgroupEgressProg, BPF_PROG_TYPE_CGROUP_SKB, mapPatterns));
+ } else if (!strcmp(name, XT_BPF_INGRESS_PROG_NAME)) {
+ fd.reset(loadProg(xtIngressProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
+ } else if (!strcmp(name, XT_BPF_EGRESS_PROG_NAME)) {
+ fd.reset(loadProg(xtEgressProg, BPF_PROG_TYPE_SOCKET_FILTER, mapPatterns));
} else {
FAIL("Unrecognized program type: %s", name);
}
@@ -216,6 +242,10 @@ int loadAndAttachProgram(bpf_attach_type type, const char* path, const char* nam
}
int ret = 0;
if (type == BPF_CGROUP_INET_EGRESS || type == BPF_CGROUP_INET_INGRESS) {
+ unique_fd cg_fd(open(CGROUP_ROOT_PATH, O_DIRECTORY | O_RDONLY | O_CLOEXEC));
+ if (cg_fd < 0) {
+ FAIL("Failed to open the cgroup directory");
+ }
ret = attachProgram(type, fd, cg_fd);
if (ret) {
FAIL("%s attach failed: %s", name, strerror(errno));
@@ -245,6 +275,7 @@ using android::bpf::UID_STATS_MAP_PATH;
using android::bpf::XT_BPF_EGRESS_PROG_PATH;
using android::bpf::XT_BPF_INGRESS_PROG_PATH;
using android::bpf::ReplacePattern;
+using android::bpf::loadAndAttachProgram;
static void usage(void) {
ALOGE( "Usage: ./bpfloader [-i] [-e]\n"
@@ -297,30 +328,32 @@ int main(int argc, char** argv) {
FAIL("unknown argument %c", opt);
}
}
+ android::bpf::parseProgramsFromFile(BPF_PROG_SRC);
+
if (doIngress) {
- ret = android::bpf::loadAndAttachProgram(BPF_CGROUP_INET_INGRESS, BPF_INGRESS_PROG_PATH,
- "ingress_prog", mapPatterns);
+ ret = loadAndAttachProgram(BPF_CGROUP_INET_INGRESS, BPF_INGRESS_PROG_PATH,
+ BPF_CGROUP_INGRESS_PROG_NAME, mapPatterns);
if (ret) {
FAIL("Failed to set up ingress program");
}
}
if (doEgress) {
- ret = android::bpf::loadAndAttachProgram(BPF_CGROUP_INET_EGRESS, BPF_EGRESS_PROG_PATH,
- "egress_prog", mapPatterns);
+ ret = loadAndAttachProgram(BPF_CGROUP_INET_EGRESS, BPF_EGRESS_PROG_PATH,
+ BPF_CGROUP_EGRESS_PROG_NAME, mapPatterns);
if (ret) {
FAIL("Failed to set up ingress program");
}
}
if (doPrerouting) {
- ret = android::bpf::loadAndAttachProgram(
- MAX_BPF_ATTACH_TYPE, XT_BPF_INGRESS_PROG_PATH, "xt_bpf_ingress_prog", mapPatterns);
+ ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_INGRESS_PROG_PATH,
+ XT_BPF_INGRESS_PROG_NAME, mapPatterns);
if (ret) {
FAIL("Failed to set up xt_bpf program");
}
}
if (doMangle) {
- ret = android::bpf::loadAndAttachProgram(
- MAX_BPF_ATTACH_TYPE, XT_BPF_EGRESS_PROG_PATH, "xt_bpf_egress_prog", mapPatterns);
+ ret = loadAndAttachProgram(MAX_BPF_ATTACH_TYPE, XT_BPF_EGRESS_PROG_PATH,
+ XT_BPF_EGRESS_PROG_NAME, mapPatterns);
if (ret) {
FAIL("Failed to set up xt_bpf program");
}
diff --git a/bpfloader/bpf_egress.c b/bpfloader/bpf_egress.c
deleted file mode 100644
index 5cf648cb..00000000
--- a/bpfloader/bpf_egress.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <linux/bpf.h>
-#include "bpf_kern.h"
-
-ELF_SEC(BPF_PROG_SEC_NAME)
-int bpf_cgroup_egress(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_EGRESS);
-}
diff --git a/bpfloader/bpf_ingress.c b/bpfloader/bpf_ingress.c
deleted file mode 100644
index 4bd51704..00000000
--- a/bpfloader/bpf_ingress.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <linux/bpf.h>
-#include "bpf_kern.h"
-
-ELF_SEC(BPF_PROG_SEC_NAME)
-int bpf_cgroup_ingress(struct __sk_buff* skb) {
- return bpf_traffic_account(skb, BPF_INGRESS);
-}
diff --git a/bpfloader/xt_bpf_ingress_prog.c b/bpfloader/bpf_kern.c
index 5f102553..3a1668f9 100644
--- a/bpfloader/xt_bpf_ingress_prog.c
+++ b/bpfloader/bpf_kern.c
@@ -17,7 +17,25 @@
#include <linux/bpf.h>
#include "bpf_kern.h"
-ELF_SEC(BPF_PROG_SEC_NAME)
+
+ELF_SEC(BPF_CGROUP_INGRESS_PROG_NAME)
+int bpf_cgroup_ingress(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, BPF_INGRESS);
+}
+
+ELF_SEC(BPF_CGROUP_EGRESS_PROG_NAME)
+int bpf_cgroup_egress(struct __sk_buff* skb) {
+ return bpf_traffic_account(skb, BPF_EGRESS);
+}
+
+ELF_SEC(XT_BPF_EGRESS_PROG_NAME)
+int xt_bpf_egress_prog(struct __sk_buff* skb) {
+ uint32_t key = skb->ifindex;
+ bpf_update_stats(skb, IFACE_STATS_MAP, BPF_EGRESS, &key);
+ return BPF_PASS;
+}
+
+ELF_SEC(XT_BPF_INGRESS_PROG_NAME)
int xt_bpf_ingress_prog(struct __sk_buff* skb) {
uint32_t key = skb->ifindex;
bpf_update_stats(skb, IFACE_STATS_MAP, BPF_INGRESS, &key);
diff --git a/bpfloader/bpf_kern.o b/bpfloader/bpf_kern.o
new file mode 100644
index 00000000..32d8e876
--- /dev/null
+++ b/bpfloader/bpf_kern.o
Binary files differ
diff --git a/bpfloader/cgroup_bpf_egress_prog.o b/bpfloader/cgroup_bpf_egress_prog.o
deleted file mode 100644
index f68fd025..00000000
--- a/bpfloader/cgroup_bpf_egress_prog.o
+++ /dev/null
Binary files differ
diff --git a/bpfloader/cgroup_bpf_ingress_prog.o b/bpfloader/cgroup_bpf_ingress_prog.o
deleted file mode 100644
index 18cfbbca..00000000
--- a/bpfloader/cgroup_bpf_ingress_prog.o
+++ /dev/null
Binary files differ
diff --git a/bpfloader/xt_bpf_egress_prog.c b/bpfloader/xt_bpf_egress_prog.c
deleted file mode 100644
index 3f4baced..00000000
--- a/bpfloader/xt_bpf_egress_prog.c
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <linux/bpf.h>
-#include "bpf_kern.h"
-
-ELF_SEC(BPF_PROG_SEC_NAME)
-int xt_bpf_egress_prog(struct __sk_buff* skb) {
- uint32_t key = skb->ifindex;
- bpf_update_stats(skb, IFACE_STATS_MAP, BPF_EGRESS, &key);
- return BPF_PASS;
-}
diff --git a/bpfloader/xt_bpf_egress_prog.o b/bpfloader/xt_bpf_egress_prog.o
deleted file mode 100644
index 739b3dab..00000000
--- a/bpfloader/xt_bpf_egress_prog.o
+++ /dev/null
Binary files differ
diff --git a/bpfloader/xt_bpf_ingress_prog.o b/bpfloader/xt_bpf_ingress_prog.o
deleted file mode 100644
index 20e71bc0..00000000
--- a/bpfloader/xt_bpf_ingress_prog.o
+++ /dev/null
Binary files differ
diff --git a/libbpf/include/bpf/bpf_shared.h b/libbpf/include/bpf/bpf_shared.h
index 2c9d3291..4a4904d2 100644
--- a/libbpf/include/bpf/bpf_shared.h
+++ b/libbpf/include/bpf/bpf_shared.h
@@ -16,7 +16,10 @@
// const values shared by both kernel program and userspace bpfloader
-#define BPF_PROG_SEC_NAME "kern_prog"
+#define BPF_CGROUP_INGRESS_PROG_NAME "cgroup_ingress_prog"
+#define BPF_CGROUP_EGRESS_PROG_NAME "cgroup_egress_prog"
+#define XT_BPF_INGRESS_PROG_NAME "xt_ingress_prog"
+#define XT_BPF_EGRESS_PROG_NAME "xt_egress_prog"
#define COOKIE_TAG_MAP 0xbfceaaffffffffff
#define UID_COUNTERSET_MAP 0xbfdceeafffffffff
diff --git a/libnetdutils/include/netdutils/Slice.h b/libnetdutils/include/netdutils/Slice.h
index f3f794be..f194514b 100644
--- a/libnetdutils/include/netdutils/Slice.h
+++ b/libnetdutils/include/netdutils/Slice.h
@@ -147,6 +147,14 @@ inline bool operator!=(const Slice& lhs, const Slice& rhs) {
std::ostream& operator<<(std::ostream& os, const Slice& slice);
+// Return suffix of Slice s starting at the first match of byte c. If no matched
+// byte, return an empty Slice.
+inline const Slice findFirstMatching(const Slice s, uint8_t c) {
+ uint8_t* match = (uint8_t*)memchr(s.base(), c, s.size());
+ if (!match) return Slice();
+ return drop(s, match - s.base());
+}
+
} // namespace netdutils
} // namespace android