Remove eBPF-based port listener
Bug: 340126051
Test: TH
Change-Id: I17c822085c0fd53da6228bde91f1945d4afbee0c
diff --git a/guest/port_listener/build.sh b/guest/port_listener/build.sh
deleted file mode 100755
index a1d0205..0000000
--- a/guest/port_listener/build.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-
-set -e
-
-check_sudo() {
- if [ "$EUID" -ne 0 ]; then
- echo "Please run as root."
- exit
- fi
-}
-
-install_prerequisites() {
- apt update
- apt install --no-install-recommends --assume-yes \
- bpftool \
- clang \
- libbpf-dev \
- libgoogle-glog-dev \
- libstdc++-14-dev
-}
-
-build_port_listener() {
- cp $(dirname $0)/src/* ${workdir}
- out_dir=${PWD}
- pushd ${workdir}
- bpftool btf dump file /sys/kernel/btf/vmlinux format c > vmlinux.h
- clang \
- -O2 \
- -Wall \
- -target bpf \
- -g \
- -c listen_tracker.ebpf.c \
- -o listen_tracker.ebpf.o
- bpftool gen skeleton listen_tracker.ebpf.o > listen_tracker.skel.h
- clang++ \
- -O2 \
- -Wall \
- -lbpf \
- -lglog \
- -o port_listener \
- main.cc
- cp port_listener ${out_dir}
- popd
-}
-
-clean_up() {
- rm -rf ${workdir}
-}
-trap clean_up EXIT
-workdir=$(mktemp -d)
-
-check_sudo
-install_prerequisites
-build_port_listener
diff --git a/guest/port_listener/src/common.h b/guest/port_listener/src/common.h
deleted file mode 100644
index d6e507c..0000000
--- a/guest/port_listener/src/common.h
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2024 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.
-
-// Copied from ChromiumOS with relicensing:
-// src/platform2/vm_tools/port_listener/common.h
-
-#ifndef VM_TOOLS_PORT_LISTENER_COMMON_H_
-#define VM_TOOLS_PORT_LISTENER_COMMON_H_
-
-enum State {
- kPortListenerUp,
- kPortListenerDown,
-};
-
-struct event {
- enum State state;
- uint16_t port;
-};
-
-#endif // VM_TOOLS_PORT_LISTENER_COMMON_H_
diff --git a/guest/port_listener/src/listen_tracker.ebpf.c b/guest/port_listener/src/listen_tracker.ebpf.c
deleted file mode 100644
index 9e98aad..0000000
--- a/guest/port_listener/src/listen_tracker.ebpf.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright 2024 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.
-
-// Copied from ChromiumOS with relicensing:
-// src/platform2/vm_tools/port_listener/listen_tracker.ebpf.c
-
-// bpf_helpers.h uses types defined here
-#include <bpf/bpf_helpers.h>
-
-#include "common.h"
-#include "vmlinux.h"
-
-// For some reason 6.1 doesn't include these symbols in the debug build
-// so they don't get included in vmlinux.h. These features have existed since
-// well before 6.1.
-#define BPF_F_NO_PREALLOC (1U << 0)
-#define BPF_ANY 0
-
-struct {
- __uint(type, BPF_MAP_TYPE_RINGBUF);
- __uint(max_entries, 1 << 24);
-} events SEC(".maps");
-
-struct {
- __uint(type, BPF_MAP_TYPE_HASH);
- __type(key, struct sock*);
- __type(value, __u8);
- __uint(max_entries, 65535);
- __uint(map_flags, BPF_F_NO_PREALLOC);
-} sockmap SEC(".maps");
-
-const __u8 set_value = 0;
-
-SEC("tp/sock/inet_sock_set_state")
-int tracepoint_inet_sock_set_state(struct trace_event_raw_inet_sock_set_state* ctx) {
- // We don't support anything other than TCP.
- if (ctx->protocol != IPPROTO_TCP) {
- return 0;
- }
- struct sock* sk = (struct sock*)ctx->skaddr;
- // If we're transitioning away from LISTEN but we don't know about this
- // socket yet then don't report anything.
- if (ctx->oldstate == BPF_TCP_LISTEN && bpf_map_lookup_elem(&sockmap, &sk) == NULL) {
- return 0;
- }
- // If we aren't transitioning to or from TCP_LISTEN then we don't care.
- if (ctx->newstate != BPF_TCP_LISTEN && ctx->oldstate != BPF_TCP_LISTEN) {
- return 0;
- }
-
- struct event* ev;
- ev = bpf_ringbuf_reserve(&events, sizeof(*ev), 0);
- if (!ev) {
- return 0;
- }
- ev->port = ctx->sport;
-
- if (ctx->newstate == BPF_TCP_LISTEN) {
- bpf_map_update_elem(&sockmap, &sk, &set_value, BPF_ANY);
- ev->state = kPortListenerUp;
- }
- if (ctx->oldstate == BPF_TCP_LISTEN) {
- bpf_map_delete_elem(&sockmap, &sk);
- ev->state = kPortListenerDown;
- }
- bpf_ringbuf_submit(ev, 0);
-
- return 0;
-}
diff --git a/guest/port_listener/src/main.cc b/guest/port_listener/src/main.cc
deleted file mode 100644
index 1caceaf..0000000
--- a/guest/port_listener/src/main.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-// Copyright 2024 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.
-
-// Copied from ChromiumOS with relicensing:
-// src/platform2/vm_tools/port_listener/main.cc
-
-#include <bpf/libbpf.h>
-#include <bpf/libbpf_legacy.h>
-#include <glog/logging.h>
-#include <linux/vm_sockets.h> // Needs to come after sys/socket.h
-#include <sys/socket.h>
-
-#include <memory>
-#include <unordered_map>
-
-#include "common.h"
-#include "listen_tracker.skel.h"
-
-typedef std::unordered_map<int, int> port_usage_map;
-
-namespace port_listener {
-namespace {
-
-int HandleEvent(void* ctx, void* const data, size_t size) {
- port_usage_map* map = reinterpret_cast<port_usage_map*>(ctx);
- const struct event* ev = (struct event*)data;
-
- switch (ev->state) {
- case kPortListenerUp:
- (*map)[ev->port]++;
- break;
-
- case kPortListenerDown:
- if ((*map)[ev->port] > 0) {
- (*map)[ev->port]--;
- } else {
- LOG(INFO) << "Received down event while port count was 0; ignoring";
- }
-
- break;
-
- default:
- LOG(ERROR) << "Unknown event state " << ev->state;
- }
-
- LOG(INFO) << "Listen event: port=" << ev->port << " state=" << ev->state;
-
- return 0;
-}
-
-typedef std::unique_ptr<struct ring_buffer, decltype(&ring_buffer__free)> ring_buffer_ptr;
-typedef std::unique_ptr<listen_tracker_ebpf, decltype(&listen_tracker_ebpf__destroy)>
- listen_tracker_ptr;
-
-// BPFProgram tracks the state and resources of the listen_tracker BPF program.
-class BPFProgram {
-public:
- // Default movable but not copyable.
- BPFProgram(BPFProgram&& other) = default;
- BPFProgram(const BPFProgram& other) = delete;
- BPFProgram& operator=(BPFProgram&& other) = default;
- BPFProgram& operator=(const BPFProgram& other) = delete;
-
- // Load loads the listen_tracker BPF program and prepares it for polling. On
- // error nullptr is returned.
- static std::unique_ptr<BPFProgram> Load() {
- auto* skel = listen_tracker_ebpf__open();
- if (!skel) {
- PLOG(ERROR) << "Failed to open listen_tracker BPF skeleton";
- return nullptr;
- }
- listen_tracker_ptr skeleton(skel, listen_tracker_ebpf__destroy);
-
- int err = listen_tracker_ebpf__load(skeleton.get());
- if (err) {
- PLOG(ERROR) << "Failed to load listen_tracker BPF program";
- return nullptr;
- }
-
- auto map = std::make_unique<port_usage_map>();
- auto* rb = ring_buffer__new(bpf_map__fd(skel->maps.events), HandleEvent, map.get(), NULL);
- if (!rb) {
- PLOG(ERROR) << "Failed to open ring buffer for listen_tracker";
- return nullptr;
- }
- ring_buffer_ptr ringbuf(rb, ring_buffer__free);
-
- err = listen_tracker_ebpf__attach(skeleton.get());
- if (err) {
- PLOG(ERROR) << "Failed to attach listen_tracker";
- return nullptr;
- }
-
- return std::unique_ptr<BPFProgram>(
- new BPFProgram(std::move(skeleton), std::move(ringbuf), std::move(map)));
- }
-
- // Poll waits for the listen_tracker BPF program to post a new event to the
- // ring buffer. BPFProgram handles integrating this new event into the
- // port_usage map and callers should consult port_usage() after Poll returns
- // for the latest data.
- const bool Poll() {
- int err = ring_buffer__poll(rb_.get(), -1);
- if (err < 0) {
- LOG(ERROR) << "Error polling ring buffer ret=" << err;
- return false;
- }
-
- return true;
- }
-
- const port_usage_map& port_usage() { return *port_usage_; }
-
-private:
- BPFProgram(listen_tracker_ptr&& skeleton, ring_buffer_ptr&& rb,
- std::unique_ptr<port_usage_map>&& port_usage)
- : skeleton_(std::move(skeleton)),
- rb_(std::move(rb)),
- port_usage_(std::move(port_usage)) {}
-
- listen_tracker_ptr skeleton_;
- ring_buffer_ptr rb_;
- std::unique_ptr<port_usage_map> port_usage_;
-};
-
-} // namespace
-} // namespace port_listener
-
-int main(int argc, char** argv) {
- google::InitGoogleLogging(argv[0]);
- libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
-
- // Load our BPF program.
- auto program = port_listener::BPFProgram::Load();
- if (program == nullptr) {
- LOG(ERROR) << "Failed to load BPF program";
- return EXIT_FAILURE;
- }
-
- // main loop: poll for listen updates
- for (;;) {
- if (!program->Poll()) {
- LOG(ERROR) << "Failure while polling BPF program";
- return EXIT_FAILURE;
- }
- // port_usage will be updated with the latest usage data
-
- for (auto it : program->port_usage()) {
- if (it.second <= 0) {
- continue;
- }
- // TODO(b/340126051): Add listening TCP4 ports.
- }
- // TODO(b/340126051): Notify port information to the guest agent.
- }
-}