1 /** 2 * Copyright (c) 2023, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <perfetto/base/task_runner.h> 20 #include <perfetto/tracing.h> 21 22 #include <string> 23 #include <unordered_map> 24 25 #include "android-base/thread_annotations.h" 26 #include "bpf/BpfMap.h" 27 #include "bpf/BpfRingbuf.h" 28 29 // For PacketTrace struct definition 30 #include "netd.h" 31 32 namespace android { 33 namespace bpf { 34 namespace internal { 35 36 // NetworkTracePoller is responsible for interactions with the BPF ring buffer 37 // including polling. This class is an internal helper for NetworkTraceHandler, 38 // it is not meant to be used elsewhere. 39 class NetworkTracePoller { 40 public: 41 using EventSink = std::function<void(const std::vector<PacketTrace>&)>; 42 43 // Testonly: initialize with a callback capable of intercepting data. NetworkTracePoller(EventSink callback)44 NetworkTracePoller(EventSink callback) : mCallback(std::move(callback)) {} 45 46 // Starts tracing with the given poll interval. 47 bool Start(uint32_t pollMs) EXCLUDES(mMutex); 48 49 // Stops tracing and release any held state. 50 bool Stop() EXCLUDES(mMutex); 51 52 // Consumes all available events from the ringbuffer. 53 bool ConsumeAll() EXCLUDES(mMutex); 54 55 private: 56 // Poll the ring buffer for new data and schedule another run of ourselves 57 // after poll_ms (essentially polling periodically until stopped). This takes 58 // in the runner and poll duration to prevent a hard requirement on the lock 59 // and thus a deadlock while resetting the TaskRunner. The runner pointer is 60 // always valid within tasks run by that runner. 61 void PollAndSchedule(perfetto::base::TaskRunner* runner, uint32_t poll_ms); 62 bool ConsumeAllLocked() REQUIRES(mMutex); 63 64 // Record sparse iface stats via atrace. This queries the per-iface stats maps 65 // for any iface present in the vector of packets. This is inexact, but should 66 // have sufficient coverage given these are cumulative counters. 67 void TraceIfaces(const std::vector<PacketTrace>& packets) REQUIRES(mMutex); 68 69 std::mutex mMutex; 70 71 // Records the number of successfully started active sessions so that only the 72 // first active session attempts setup and only the last cleans up. Note that 73 // the session count will remain zero if Start fails. It is expected that Stop 74 // will not be called for any trace session where Start fails. 75 int mSessionCount GUARDED_BY(mMutex); 76 77 // How often to poll the ring buffer, defined by the trace config. 78 uint32_t mPollMs GUARDED_BY(mMutex); 79 80 // The function to process PacketTrace, typically a Perfetto sink. 81 EventSink mCallback GUARDED_BY(mMutex); 82 83 // The BPF ring buffer handle. 84 std::unique_ptr<BpfRingbuf<PacketTrace>> mRingBuffer GUARDED_BY(mMutex); 85 86 // The packet tracing config map (really a 1-element array). 87 BpfMap<uint32_t, bool> mConfigurationMap GUARDED_BY(mMutex); 88 89 // This must be the last member, causing it to be the first deleted. If it is 90 // not, members required for callbacks can be deleted before it's stopped. 91 std::unique_ptr<perfetto::base::TaskRunner> mTaskRunner GUARDED_BY(mMutex); 92 }; 93 94 } // namespace internal 95 } // namespace bpf 96 } // namespace android 97