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