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(mBufferMutex); 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 63 // Record sparse iface stats via atrace. This queries the per-iface stats maps 64 // for any iface present in the vector of packets. This is inexact, but should 65 // have sufficient coverage given these are cumulative counters. 66 static void TraceIfaces(const std::vector<PacketTrace>& packets); 67 68 std::mutex mMutex; 69 70 // The mBufferMutex protects the ring buffer. This allows separate protected 71 // access of mTaskRunner in Stop (to terminate) and mRingBuffer in ConsumeAll. 72 // Without this separation, Stop() can deadlock. 73 std::mutex mBufferMutex; 74 75 // Records the number of successfully started active sessions so that only the 76 // first active session attempts setup and only the last cleans up. Note that 77 // the session count will remain zero if Start fails. It is expected that Stop 78 // will not be called for any trace session where Start fails. 79 int mSessionCount GUARDED_BY(mMutex); 80 81 // How often to poll the ring buffer, defined by the trace config. 82 uint32_t mPollMs GUARDED_BY(mMutex); 83 84 // The function to process PacketTrace, typically a Perfetto sink. 85 const EventSink mCallback; 86 87 // The BPF ring buffer handle. 88 std::unique_ptr<BpfRingbuf<PacketTrace>> mRingBuffer GUARDED_BY(mBufferMutex); 89 90 // The packet tracing config map (really a 1-element array). 91 BpfMap<uint32_t, bool> mConfigurationMap GUARDED_BY(mMutex); 92 93 // This must be the last member, causing it to be the first deleted. If it is 94 // not, members required for callbacks can be deleted before it's stopped. 95 std::unique_ptr<perfetto::base::TaskRunner> mTaskRunner GUARDED_BY(mMutex); 96 }; 97 98 } // namespace internal 99 } // namespace bpf 100 } // namespace android 101