xref: /aosp_15_r20/kernel/tests/net/test/tcp_metrics.py (revision 2f2c4c7ab4226c71756b9c31670392fdd6887c4f)
1*2f2c4c7aSAndroid Build Coastguard Worker#!/usr/bin/python3
2*2f2c4c7aSAndroid Build Coastguard Worker#
3*2f2c4c7aSAndroid Build Coastguard Worker# Copyright 2017 The Android Open Source Project
4*2f2c4c7aSAndroid Build Coastguard Worker#
5*2f2c4c7aSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*2f2c4c7aSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*2f2c4c7aSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*2f2c4c7aSAndroid Build Coastguard Worker#
9*2f2c4c7aSAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0
10*2f2c4c7aSAndroid Build Coastguard Worker#
11*2f2c4c7aSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*2f2c4c7aSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*2f2c4c7aSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*2f2c4c7aSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*2f2c4c7aSAndroid Build Coastguard Worker# limitations under the License.
16*2f2c4c7aSAndroid Build Coastguard Worker
17*2f2c4c7aSAndroid Build Coastguard Worker"""Generic netlink interface to TCP metrics."""
18*2f2c4c7aSAndroid Build Coastguard Worker
19*2f2c4c7aSAndroid Build Coastguard Workerfrom socket import *  # pylint: disable=wildcard-import
20*2f2c4c7aSAndroid Build Coastguard Workerimport struct
21*2f2c4c7aSAndroid Build Coastguard Worker
22*2f2c4c7aSAndroid Build Coastguard Workerimport binascii
23*2f2c4c7aSAndroid Build Coastguard Workerimport cstruct
24*2f2c4c7aSAndroid Build Coastguard Workerimport genetlink
25*2f2c4c7aSAndroid Build Coastguard Workerimport net_test
26*2f2c4c7aSAndroid Build Coastguard Workerimport netlink
27*2f2c4c7aSAndroid Build Coastguard Worker
28*2f2c4c7aSAndroid Build Coastguard Worker
29*2f2c4c7aSAndroid Build Coastguard Worker### TCP metrics constants. See include/uapi/linux/tcp_metrics.h.
30*2f2c4c7aSAndroid Build Coastguard Worker# Family name and version
31*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_GENL_NAME = "tcp_metrics"
32*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_GENL_VERSION = 1
33*2f2c4c7aSAndroid Build Coastguard Worker
34*2f2c4c7aSAndroid Build Coastguard Worker# Message types.
35*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_CMD_GET = 1
36*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_CMD_DEL = 2
37*2f2c4c7aSAndroid Build Coastguard Worker
38*2f2c4c7aSAndroid Build Coastguard Worker# Attributes.
39*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_UNSPEC = 0
40*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_ADDR_IPV4 = 1
41*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_ADDR_IPV6 = 2
42*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_AGE = 3
43*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_TW_TSVAL = 4
44*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_TW_TS_STAMP = 5
45*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_VALS = 6
46*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_FOPEN_MSS = 7
47*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_FOPEN_SYN_DROPS = 8
48*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_FOPEN_SYN_DROP_TS = 9
49*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_FOPEN_COOKIE = 10
50*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_SADDR_IPV4 = 11
51*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_SADDR_IPV6 = 12
52*2f2c4c7aSAndroid Build Coastguard WorkerTCP_METRICS_ATTR_PAD = 13
53*2f2c4c7aSAndroid Build Coastguard Worker
54*2f2c4c7aSAndroid Build Coastguard Worker
55*2f2c4c7aSAndroid Build Coastguard Workerclass TcpMetrics(genetlink.GenericNetlink):
56*2f2c4c7aSAndroid Build Coastguard Worker
57*2f2c4c7aSAndroid Build Coastguard Worker  NL_DEBUG = ["ALL"]
58*2f2c4c7aSAndroid Build Coastguard Worker
59*2f2c4c7aSAndroid Build Coastguard Worker  def __init__(self):
60*2f2c4c7aSAndroid Build Coastguard Worker    super(TcpMetrics, self).__init__()
61*2f2c4c7aSAndroid Build Coastguard Worker    # Generic netlink family IDs are dynamically assigned. Find ours.
62*2f2c4c7aSAndroid Build Coastguard Worker    ctrl = genetlink.GenericNetlinkControl()
63*2f2c4c7aSAndroid Build Coastguard Worker    self.family = ctrl.GetFamily(TCP_METRICS_GENL_NAME)
64*2f2c4c7aSAndroid Build Coastguard Worker
65*2f2c4c7aSAndroid Build Coastguard Worker  def _Decode(self, command, msg, nla_type, nla_data, nested):
66*2f2c4c7aSAndroid Build Coastguard Worker    """Decodes TCP metrics netlink attributes to human-readable format."""
67*2f2c4c7aSAndroid Build Coastguard Worker
68*2f2c4c7aSAndroid Build Coastguard Worker    name = self._GetConstantName(__name__, nla_type, "TCP_METRICS_ATTR_")
69*2f2c4c7aSAndroid Build Coastguard Worker
70*2f2c4c7aSAndroid Build Coastguard Worker    if name in ["TCP_METRICS_ATTR_ADDR_IPV4", "TCP_METRICS_ATTR_SADDR_IPV4"]:
71*2f2c4c7aSAndroid Build Coastguard Worker      data = inet_ntop(AF_INET, nla_data)
72*2f2c4c7aSAndroid Build Coastguard Worker    elif name in ["TCP_METRICS_ATTR_ADDR_IPV6", "TCP_METRICS_ATTR_SADDR_IPV6"]:
73*2f2c4c7aSAndroid Build Coastguard Worker      data = inet_ntop(AF_INET6, nla_data)
74*2f2c4c7aSAndroid Build Coastguard Worker    elif name in ["TCP_METRICS_ATTR_AGE"]:
75*2f2c4c7aSAndroid Build Coastguard Worker      data = struct.unpack("=Q", nla_data)[0]
76*2f2c4c7aSAndroid Build Coastguard Worker    elif name in ["TCP_METRICS_ATTR_TW_TSVAL", "TCP_METRICS_ATTR_TW_TS_STAMP"]:
77*2f2c4c7aSAndroid Build Coastguard Worker      data = struct.unpack("=I", nla_data)[0]
78*2f2c4c7aSAndroid Build Coastguard Worker    elif name == "TCP_METRICS_ATTR_FOPEN_MSS":
79*2f2c4c7aSAndroid Build Coastguard Worker      data = struct.unpack("=H", nla_data)[0]
80*2f2c4c7aSAndroid Build Coastguard Worker    elif name == "TCP_METRICS_ATTR_FOPEN_COOKIE":
81*2f2c4c7aSAndroid Build Coastguard Worker      data = nla_data
82*2f2c4c7aSAndroid Build Coastguard Worker    else:
83*2f2c4c7aSAndroid Build Coastguard Worker      data = binascii.hexlify(nla_data)
84*2f2c4c7aSAndroid Build Coastguard Worker
85*2f2c4c7aSAndroid Build Coastguard Worker    return name, data
86*2f2c4c7aSAndroid Build Coastguard Worker
87*2f2c4c7aSAndroid Build Coastguard Worker  def MaybeDebugCommand(self, command, unused_flags, data):
88*2f2c4c7aSAndroid Build Coastguard Worker    if "ALL" not in self.NL_DEBUG and command not in self.NL_DEBUG:
89*2f2c4c7aSAndroid Build Coastguard Worker      return
90*2f2c4c7aSAndroid Build Coastguard Worker    parsed = self._ParseNLMsg(data, genetlink.Genlmsghdr)
91*2f2c4c7aSAndroid Build Coastguard Worker
92*2f2c4c7aSAndroid Build Coastguard Worker  def _NlAttrSaddr(self, address):
93*2f2c4c7aSAndroid Build Coastguard Worker    if ":" not in address:
94*2f2c4c7aSAndroid Build Coastguard Worker      family = AF_INET
95*2f2c4c7aSAndroid Build Coastguard Worker      nla_type = TCP_METRICS_ATTR_SADDR_IPV4
96*2f2c4c7aSAndroid Build Coastguard Worker    else:
97*2f2c4c7aSAndroid Build Coastguard Worker      family = AF_INET6
98*2f2c4c7aSAndroid Build Coastguard Worker      nla_type = TCP_METRICS_ATTR_SADDR_IPV6
99*2f2c4c7aSAndroid Build Coastguard Worker    return self._NlAttrIPAddress(nla_type, family, address)
100*2f2c4c7aSAndroid Build Coastguard Worker
101*2f2c4c7aSAndroid Build Coastguard Worker  def _NlAttrTcpMetricsAddr(self, address, is_source):
102*2f2c4c7aSAndroid Build Coastguard Worker    version = net_test.GetAddressVersion(address)
103*2f2c4c7aSAndroid Build Coastguard Worker    family = net_test.GetAddressFamily(version)
104*2f2c4c7aSAndroid Build Coastguard Worker    if version == 5:
105*2f2c4c7aSAndroid Build Coastguard Worker      address = address.replace("::ffff:", "")
106*2f2c4c7aSAndroid Build Coastguard Worker    nla_name = "TCP_METRICS_ATTR_%s_IPV%d" % (
107*2f2c4c7aSAndroid Build Coastguard Worker        "SADDR" if is_source else "ADDR", version)
108*2f2c4c7aSAndroid Build Coastguard Worker    nla_type = globals()[nla_name]
109*2f2c4c7aSAndroid Build Coastguard Worker    return self._NlAttrIPAddress(nla_type, family, address)
110*2f2c4c7aSAndroid Build Coastguard Worker
111*2f2c4c7aSAndroid Build Coastguard Worker  def _NlAttrAddr(self, address):
112*2f2c4c7aSAndroid Build Coastguard Worker    return self._NlAttrTcpMetricsAddr(address, False)
113*2f2c4c7aSAndroid Build Coastguard Worker
114*2f2c4c7aSAndroid Build Coastguard Worker  def _NlAttrSaddr(self, address):
115*2f2c4c7aSAndroid Build Coastguard Worker    return self._NlAttrTcpMetricsAddr(address, True)
116*2f2c4c7aSAndroid Build Coastguard Worker
117*2f2c4c7aSAndroid Build Coastguard Worker  def DumpMetrics(self):
118*2f2c4c7aSAndroid Build Coastguard Worker    """Dumps all TCP metrics."""
119*2f2c4c7aSAndroid Build Coastguard Worker    return self._Dump(self.family, TCP_METRICS_CMD_GET, 1)
120*2f2c4c7aSAndroid Build Coastguard Worker
121*2f2c4c7aSAndroid Build Coastguard Worker  def GetMetrics(self, saddr, daddr):
122*2f2c4c7aSAndroid Build Coastguard Worker    """Returns TCP metrics for the specified src/dst pair."""
123*2f2c4c7aSAndroid Build Coastguard Worker    data = self._NlAttrSaddr(saddr) + self._NlAttrAddr(daddr)
124*2f2c4c7aSAndroid Build Coastguard Worker    self._SendCommand(self.family, TCP_METRICS_CMD_GET, 1, data,
125*2f2c4c7aSAndroid Build Coastguard Worker                      netlink.NLM_F_REQUEST)
126*2f2c4c7aSAndroid Build Coastguard Worker    hdr, attrs = self._GetMsg(genetlink.Genlmsghdr)
127*2f2c4c7aSAndroid Build Coastguard Worker    return attrs
128*2f2c4c7aSAndroid Build Coastguard Worker
129*2f2c4c7aSAndroid Build Coastguard Worker  def DelMetrics(self, saddr, daddr):
130*2f2c4c7aSAndroid Build Coastguard Worker    """Deletes TCP metrics for the specified src/dst pair."""
131*2f2c4c7aSAndroid Build Coastguard Worker    data = self._NlAttrSaddr(saddr) + self._NlAttrAddr(daddr)
132*2f2c4c7aSAndroid Build Coastguard Worker    self._SendCommand(self.family, TCP_METRICS_CMD_DEL, 1, data,
133*2f2c4c7aSAndroid Build Coastguard Worker                      netlink.NLM_F_REQUEST)
134*2f2c4c7aSAndroid Build Coastguard Worker
135*2f2c4c7aSAndroid Build Coastguard Worker
136*2f2c4c7aSAndroid Build Coastguard Workerif __name__ == "__main__":
137*2f2c4c7aSAndroid Build Coastguard Worker  t = TcpMetrics()
138*2f2c4c7aSAndroid Build Coastguard Worker  print(t.DumpMetrics())
139