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