• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 package com.android.networkstack.metrics;
18 
19 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_802_3_FRAME;
20 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_NON_IPV4;
21 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_OTHER_HOST;
22 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_REPLY_SPA_NO_HOST;
23 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_REQUEST_REPLIED;
24 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_UNKNOWN;
25 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ARP_V6_ONLY;
26 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ETHERTYPE_NOT_ALLOWED;
27 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ETHER_OUR_SRC_MAC;
28 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_ETH_BROADCAST;
29 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_GARP_REPLY;
30 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IGMP_INVALID;
31 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IGMP_REPORT;
32 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IGMP_V2_GENERAL_QUERY_REPLIED;
33 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IGMP_V3_GENERAL_QUERY_REPLIED;
34 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_BROADCAST_ADDR;
35 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_BROADCAST_NET;
36 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_ICMP_INVALID;
37 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_KEEPALIVE_ACK;
38 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_L2_BROADCAST;
39 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_MULTICAST;
40 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_NATT_KEEPALIVE;
41 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_NON_DHCP4;
42 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_PING_REQUEST_REPLIED;
43 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV4_TCP_PORT7_UNICAST;
44 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_ICMP6_ECHO_REQUEST_INVALID;
45 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_ICMP6_ECHO_REQUEST_REPLIED;
46 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_MLD_INVALID;
47 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_MLD_REPORT;
48 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_MLD_V1_GENERAL_QUERY_REPLIED;
49 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_MLD_V2_GENERAL_QUERY_REPLIED;
50 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_MULTICAST_NA;
51 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_NON_ICMP_MULTICAST;
52 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_NS_INVALID;
53 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_NS_OTHER_HOST;
54 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_NS_REPLIED_NON_DAD;
55 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_IPV6_ROUTER_SOLICITATION;
56 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_MDNS;
57 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_MDNS_REPLIED;
58 import static android.net.apf.ApfCounterTracker.Counter.DROPPED_RA;
59 import static android.net.apf.ApfCounterTracker.Counter.PASSED_ARP_BROADCAST_REPLY;
60 import static android.net.apf.ApfCounterTracker.Counter.PASSED_ARP_REQUEST;
61 import static android.net.apf.ApfCounterTracker.Counter.PASSED_ARP_UNICAST_REPLY;
62 import static android.net.apf.ApfCounterTracker.Counter.PASSED_DHCP;
63 import static android.net.apf.ApfCounterTracker.Counter.PASSED_ETHER_OUR_SRC_MAC;
64 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV4;
65 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV4_FROM_DHCPV4_SERVER;
66 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV4_UNICAST;
67 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV6_HOPOPTS;
68 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV6_ICMP;
69 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV6_NON_ICMP;
70 import static android.net.apf.ApfCounterTracker.Counter.PASSED_IPV6_UNICAST_NON_ICMP;
71 import static android.net.apf.ApfCounterTracker.Counter.PASSED_NON_IP_UNICAST;
72 import static android.net.apf.ApfCounterTracker.Counter.RESERVED_OOB;
73 import static android.net.apf.ApfCounterTracker.Counter.TOTAL_PACKETS;
74 import static android.stats.connectivity.CounterName.CN_DROPPED_802_3_FRAME;
75 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_NON_IPV4;
76 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_OTHER_HOST;
77 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_REPLY_SPA_NO_HOST;
78 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_REQUEST_REPLIED;
79 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_UNKNOWN;
80 import static android.stats.connectivity.CounterName.CN_DROPPED_ARP_V6_ONLY;
81 import static android.stats.connectivity.CounterName.CN_DROPPED_ETHERTYPE_NOT_ALLOWED;
82 import static android.stats.connectivity.CounterName.CN_DROPPED_ETHER_OUR_SRC_MAC;
83 import static android.stats.connectivity.CounterName.CN_DROPPED_ETH_BROADCAST;
84 import static android.stats.connectivity.CounterName.CN_DROPPED_GARP_REPLY;
85 import static android.stats.connectivity.CounterName.CN_DROPPED_IGMP_INVALID;
86 import static android.stats.connectivity.CounterName.CN_DROPPED_IGMP_REPORT;
87 import static android.stats.connectivity.CounterName.CN_DROPPED_IGMP_V2_GENERAL_QUERY_REPLIED;
88 import static android.stats.connectivity.CounterName.CN_DROPPED_IGMP_V3_GENERAL_QUERY_REPLIED;
89 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_BROADCAST_ADDR;
90 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_BROADCAST_NET;
91 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_ICMP_INVALID;
92 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_KEEPALIVE_ACK;
93 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_L2_BROADCAST;
94 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_MULTICAST;
95 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_NATT_KEEPALIVE;
96 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_NON_DHCP4;
97 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_PING_REQUEST_REPLIED;
98 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV4_TCP_PORT7_UNICAST;
99 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_ICMP6_ECHO_REQUEST_INVALID;
100 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_ICMP6_ECHO_REQUEST_REPLIED;
101 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_MLD_INVALID;
102 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_MLD_REPORT;
103 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_MLD_V1_GENERAL_QUERY_REPLIED;
104 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_MLD_V2_GENERAL_QUERY_REPLIED;
105 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_MULTICAST_NA;
106 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_NON_ICMP_MULTICAST;
107 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_NS_INVALID;
108 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_NS_OTHER_HOST;
109 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_NS_REPLIED_NON_DAD;
110 import static android.stats.connectivity.CounterName.CN_DROPPED_IPV6_ROUTER_SOLICITATION;
111 import static android.stats.connectivity.CounterName.CN_DROPPED_MDNS;
112 import static android.stats.connectivity.CounterName.CN_DROPPED_MDNS_REPLIED;
113 import static android.stats.connectivity.CounterName.CN_DROPPED_RA;
114 import static android.stats.connectivity.CounterName.CN_PASSED_ARP_BROADCAST_REPLY;
115 import static android.stats.connectivity.CounterName.CN_PASSED_ARP_REQUEST;
116 import static android.stats.connectivity.CounterName.CN_PASSED_ARP_UNICAST_REPLY;
117 import static android.stats.connectivity.CounterName.CN_PASSED_DHCP;
118 import static android.stats.connectivity.CounterName.CN_PASSED_IPV4;
119 import static android.stats.connectivity.CounterName.CN_PASSED_IPV4_FROM_DHCPV4_SERVER;
120 import static android.stats.connectivity.CounterName.CN_PASSED_IPV4_UNICAST;
121 import static android.stats.connectivity.CounterName.CN_PASSED_IPV6_HOPOPTS;
122 import static android.stats.connectivity.CounterName.CN_PASSED_IPV6_ICMP;
123 import static android.stats.connectivity.CounterName.CN_PASSED_IPV6_NON_ICMP;
124 import static android.stats.connectivity.CounterName.CN_PASSED_IPV6_UNICAST_NON_ICMP;
125 import static android.stats.connectivity.CounterName.CN_PASSED_NON_IP_UNICAST;
126 import static android.stats.connectivity.CounterName.CN_PASSED_OUR_SRC_MAC;
127 import static android.stats.connectivity.CounterName.CN_TOTAL_PACKETS;
128 import static android.stats.connectivity.CounterName.CN_UNKNOWN;
129 
130 import android.net.apf.ApfCounterTracker.Counter;
131 import android.stats.connectivity.CounterName;
132 
133 import androidx.annotation.VisibleForTesting;
134 
135 import java.util.EnumMap;
136 import java.util.Map;
137 
138 /**
139  * Class to record the network stack ApfSessionInfo metrics into statsd.
140  *
141  * This class is not thread-safe, and should always be accessed from the same thread.
142  *
143  * @hide
144  */
145 public class ApfSessionInfoMetrics {
146     // Define the maximum size of the counter list
147     public static final int MAX_NUM_OF_COUNTERS = Counter.class.getEnumConstants().length - 1;
148     private static final EnumMap<Counter, CounterName> apfCounterMetricsMap = new EnumMap<>(
149             Map.ofEntries(
150                 Map.entry(RESERVED_OOB, CN_UNKNOWN),
151                 Map.entry(TOTAL_PACKETS, CN_TOTAL_PACKETS),
152                 // The counter sequence should be keep the same in ApfCounterTracker.java
153                 Map.entry(PASSED_ARP_BROADCAST_REPLY, CN_PASSED_ARP_BROADCAST_REPLY),
154                 Map.entry(PASSED_ARP_REQUEST, CN_PASSED_ARP_REQUEST),
155                 Map.entry(PASSED_ARP_UNICAST_REPLY, CN_PASSED_ARP_UNICAST_REPLY),
156                 Map.entry(PASSED_DHCP, CN_PASSED_DHCP),
157                 Map.entry(PASSED_ETHER_OUR_SRC_MAC, CN_PASSED_OUR_SRC_MAC),
158                 Map.entry(PASSED_IPV4, CN_PASSED_IPV4),
159                 Map.entry(PASSED_IPV4_FROM_DHCPV4_SERVER, CN_PASSED_IPV4_FROM_DHCPV4_SERVER),
160                 Map.entry(PASSED_IPV4_UNICAST, CN_PASSED_IPV4_UNICAST),
161                 Map.entry(PASSED_IPV6_HOPOPTS, CN_PASSED_IPV6_HOPOPTS),
162                 Map.entry(PASSED_IPV6_ICMP, CN_PASSED_IPV6_ICMP),
163                 Map.entry(PASSED_IPV6_NON_ICMP, CN_PASSED_IPV6_NON_ICMP),
164                 Map.entry(PASSED_IPV6_UNICAST_NON_ICMP, CN_PASSED_IPV6_UNICAST_NON_ICMP),
165                 Map.entry(PASSED_NON_IP_UNICAST, CN_PASSED_NON_IP_UNICAST),
166                 Map.entry(DROPPED_ETH_BROADCAST, CN_DROPPED_ETH_BROADCAST),
167                 Map.entry(DROPPED_ETHER_OUR_SRC_MAC, CN_DROPPED_ETHER_OUR_SRC_MAC),
168                 Map.entry(DROPPED_RA, CN_DROPPED_RA),
169                 Map.entry(DROPPED_IPV4_L2_BROADCAST, CN_DROPPED_IPV4_L2_BROADCAST),
170                 Map.entry(DROPPED_IPV4_BROADCAST_ADDR, CN_DROPPED_IPV4_BROADCAST_ADDR),
171                 Map.entry(DROPPED_IPV4_BROADCAST_NET, CN_DROPPED_IPV4_BROADCAST_NET),
172                 Map.entry(DROPPED_IPV4_ICMP_INVALID, CN_DROPPED_IPV4_ICMP_INVALID),
173                 Map.entry(DROPPED_IPV4_MULTICAST, CN_DROPPED_IPV4_MULTICAST),
174                 Map.entry(DROPPED_IPV4_NON_DHCP4, CN_DROPPED_IPV4_NON_DHCP4),
175                 Map.entry(DROPPED_IPV4_PING_REQUEST_REPLIED, CN_DROPPED_IPV4_PING_REQUEST_REPLIED),
176                 Map.entry(DROPPED_IPV6_ICMP6_ECHO_REQUEST_INVALID,
177                     CN_DROPPED_IPV6_ICMP6_ECHO_REQUEST_INVALID),
178                 Map.entry(DROPPED_IPV6_ICMP6_ECHO_REQUEST_REPLIED,
179                     CN_DROPPED_IPV6_ICMP6_ECHO_REQUEST_REPLIED),
180                 Map.entry(DROPPED_IPV6_ROUTER_SOLICITATION, CN_DROPPED_IPV6_ROUTER_SOLICITATION),
181                 Map.entry(DROPPED_IPV6_MLD_INVALID, CN_DROPPED_IPV6_MLD_INVALID),
182                 Map.entry(DROPPED_IPV6_MLD_REPORT, CN_DROPPED_IPV6_MLD_REPORT),
183                 Map.entry(DROPPED_IPV6_MLD_V1_GENERAL_QUERY_REPLIED,
184                     CN_DROPPED_IPV6_MLD_V1_GENERAL_QUERY_REPLIED),
185                 Map.entry(DROPPED_IPV6_MLD_V2_GENERAL_QUERY_REPLIED,
186                     CN_DROPPED_IPV6_MLD_V2_GENERAL_QUERY_REPLIED),
187                 Map.entry(DROPPED_IPV6_MULTICAST_NA, CN_DROPPED_IPV6_MULTICAST_NA),
188                 Map.entry(DROPPED_IPV6_NON_ICMP_MULTICAST, CN_DROPPED_IPV6_NON_ICMP_MULTICAST),
189                 Map.entry(DROPPED_IPV6_NS_INVALID, CN_DROPPED_IPV6_NS_INVALID),
190                 Map.entry(DROPPED_IPV6_NS_OTHER_HOST, CN_DROPPED_IPV6_NS_OTHER_HOST),
191                 Map.entry(DROPPED_IPV6_NS_REPLIED_NON_DAD, CN_DROPPED_IPV6_NS_REPLIED_NON_DAD),
192                 Map.entry(DROPPED_802_3_FRAME, CN_DROPPED_802_3_FRAME),
193                 Map.entry(DROPPED_ETHERTYPE_NOT_ALLOWED, CN_DROPPED_ETHERTYPE_NOT_ALLOWED),
194                 Map.entry(DROPPED_IPV4_KEEPALIVE_ACK, CN_DROPPED_IPV4_KEEPALIVE_ACK),
195                 Map.entry(DROPPED_IPV4_NATT_KEEPALIVE, CN_DROPPED_IPV4_NATT_KEEPALIVE),
196                 Map.entry(DROPPED_MDNS, CN_DROPPED_MDNS),
197                 Map.entry(DROPPED_MDNS_REPLIED, CN_DROPPED_MDNS_REPLIED),
198                 Map.entry(DROPPED_IPV4_TCP_PORT7_UNICAST, CN_DROPPED_IPV4_TCP_PORT7_UNICAST),
199                 Map.entry(DROPPED_ARP_NON_IPV4, CN_DROPPED_ARP_NON_IPV4),
200                 Map.entry(DROPPED_ARP_OTHER_HOST, CN_DROPPED_ARP_OTHER_HOST),
201                 Map.entry(DROPPED_ARP_REPLY_SPA_NO_HOST, CN_DROPPED_ARP_REPLY_SPA_NO_HOST),
202                 Map.entry(DROPPED_ARP_REQUEST_REPLIED, CN_DROPPED_ARP_REQUEST_REPLIED),
203                 Map.entry(DROPPED_ARP_UNKNOWN, CN_DROPPED_ARP_UNKNOWN),
204                 Map.entry(DROPPED_ARP_V6_ONLY, CN_DROPPED_ARP_V6_ONLY),
205                 Map.entry(DROPPED_IGMP_V2_GENERAL_QUERY_REPLIED,
206                     CN_DROPPED_IGMP_V2_GENERAL_QUERY_REPLIED),
207                 Map.entry(DROPPED_IGMP_V3_GENERAL_QUERY_REPLIED,
208                     CN_DROPPED_IGMP_V3_GENERAL_QUERY_REPLIED),
209                 Map.entry(DROPPED_IGMP_INVALID, CN_DROPPED_IGMP_INVALID),
210                 Map.entry(DROPPED_IGMP_REPORT, CN_DROPPED_IGMP_REPORT),
211                 Map.entry(DROPPED_GARP_REPLY, CN_DROPPED_GARP_REPLY)
212             )
213     );
214     private final ApfSessionInfoReported.Builder mStatsBuilder =
215             ApfSessionInfoReported.newBuilder();
216     private final ApfCounterList.Builder mApfCounterListBuilder = ApfCounterList.newBuilder();
217 
218     /**
219      * Write the version to mStatsBuilder.
220      */
setVersion(final int version)221     public void setVersion(final int version) {
222         mStatsBuilder.setVersion(version);
223     }
224 
225     /**
226      * Write the memory size to mStatsBuilder.
227      */
setMemorySize(final int memorySize)228     public void setMemorySize(final int memorySize) {
229         mStatsBuilder.setMemorySize(memorySize);
230     }
231 
232     /**
233      * Add an APF counter to the metrics builder.
234      */
addApfCounter(final Counter counter, final long value)235     public void addApfCounter(final Counter counter, final long value) {
236         if (mApfCounterListBuilder.getApfCounterCount() >= MAX_NUM_OF_COUNTERS) return;
237         final ApfCounter.Builder apfCounterBuilder = ApfCounter.newBuilder()
238                 .setCounterName(apfFilterCounterToEnum(counter))
239                 .setCounterValue(value);
240 
241         mApfCounterListBuilder.addApfCounter(apfCounterBuilder);
242     }
243 
244     /**
245      * Write the session duration to mStatsBuilder.
246      */
setApfSessionDurationSeconds(final int durationSeconds)247     public void setApfSessionDurationSeconds(final int durationSeconds) {
248         mStatsBuilder.setApfSessionDurationSeconds(durationSeconds);
249     }
250 
251     /**
252      * Write the number of times APF program updated to mStatsBuilder.
253      */
setNumOfTimesApfProgramUpdated(final int updatedTimes)254     public void setNumOfTimesApfProgramUpdated(final int updatedTimes) {
255         mStatsBuilder.setNumOfTimesApfProgramUpdated(updatedTimes);
256     }
257 
258     /**
259      * Write the maximum program size to mStatsBuilder.
260      */
setMaxProgramSize(final int programSize)261     public void setMaxProgramSize(final int programSize) {
262         mStatsBuilder.setMaxProgramSize(programSize);
263     }
264 
265     /**
266      * Write the ApfSessionInfoReported proto into statsd.
267      */
statsWrite()268     public ApfSessionInfoReported statsWrite() {
269         mStatsBuilder.setApfCounterList(mApfCounterListBuilder);
270         final ApfSessionInfoReported stats = mStatsBuilder.build();
271         final byte[] apfCounterList = stats.getApfCounterList().toByteArray();
272         NetworkStackStatsLog.write(NetworkStackStatsLog.APF_SESSION_INFO_REPORTED,
273                 stats.getVersion(),
274                 stats.getMemorySize(),
275                 apfCounterList,
276                 stats.getApfSessionDurationSeconds(),
277                 stats.getNumOfTimesApfProgramUpdated(),
278                 stats.getMaxProgramSize());
279         return stats;
280     }
281 
282     /**
283      *  Map ApfCounterTracker.Counter to {@link CounterName}.
284      */
285     @VisibleForTesting
apfFilterCounterToEnum(final Counter counter)286     public static CounterName apfFilterCounterToEnum(final Counter counter) {
287         return apfCounterMetricsMap.getOrDefault(counter, CN_UNKNOWN);
288     }
289 }
290