xref: /dpdk/dts/framework/testbed_model/tg_node.py (revision cecfe0aabf585fe49548e19b3b5d7ed98f45783b)
1*cecfe0aaSJuraj Linkeš# SPDX-License-Identifier: BSD-3-Clause
2*cecfe0aaSJuraj Linkeš# Copyright(c) 2010-2014 Intel Corporation
3*cecfe0aaSJuraj Linkeš# Copyright(c) 2022 University of New Hampshire
4*cecfe0aaSJuraj Linkeš# Copyright(c) 2023 PANTHEON.tech s.r.o.
5*cecfe0aaSJuraj Linkeš
6*cecfe0aaSJuraj Linkeš"""Traffic generator node.
7*cecfe0aaSJuraj Linkeš
8*cecfe0aaSJuraj LinkešThis is the node where the traffic generator resides.
9*cecfe0aaSJuraj LinkešThe distinction between a node and a traffic generator is as follows:
10*cecfe0aaSJuraj LinkešA node is a host that DTS connects to. It could be a baremetal server,
11*cecfe0aaSJuraj Linkeša VM or a container.
12*cecfe0aaSJuraj LinkešA traffic generator is software running on the node.
13*cecfe0aaSJuraj LinkešA traffic generator node is a node running a traffic generator.
14*cecfe0aaSJuraj LinkešA node can be a traffic generator node as well as system under test node.
15*cecfe0aaSJuraj Linkeš"""
16*cecfe0aaSJuraj Linkeš
17*cecfe0aaSJuraj Linkešfrom scapy.packet import Packet  # type: ignore[import]
18*cecfe0aaSJuraj Linkeš
19*cecfe0aaSJuraj Linkešfrom framework.config import (
20*cecfe0aaSJuraj Linkeš    ScapyTrafficGeneratorConfig,
21*cecfe0aaSJuraj Linkeš    TGNodeConfiguration,
22*cecfe0aaSJuraj Linkeš    TrafficGeneratorType,
23*cecfe0aaSJuraj Linkeš)
24*cecfe0aaSJuraj Linkešfrom framework.exception import ConfigurationError
25*cecfe0aaSJuraj Linkeš
26*cecfe0aaSJuraj Linkešfrom .capturing_traffic_generator import CapturingTrafficGenerator
27*cecfe0aaSJuraj Linkešfrom .hw.port import Port
28*cecfe0aaSJuraj Linkešfrom .node import Node
29*cecfe0aaSJuraj Linkeš
30*cecfe0aaSJuraj Linkeš
31*cecfe0aaSJuraj Linkešclass TGNode(Node):
32*cecfe0aaSJuraj Linkeš    """Manage connections to a node with a traffic generator.
33*cecfe0aaSJuraj Linkeš
34*cecfe0aaSJuraj Linkeš    Apart from basic node management capabilities, the Traffic Generator node has
35*cecfe0aaSJuraj Linkeš    specialized methods for handling the traffic generator running on it.
36*cecfe0aaSJuraj Linkeš
37*cecfe0aaSJuraj Linkeš    Arguments:
38*cecfe0aaSJuraj Linkeš        node_config: The user configuration of the traffic generator node.
39*cecfe0aaSJuraj Linkeš
40*cecfe0aaSJuraj Linkeš    Attributes:
41*cecfe0aaSJuraj Linkeš        traffic_generator: The traffic generator running on the node.
42*cecfe0aaSJuraj Linkeš    """
43*cecfe0aaSJuraj Linkeš
44*cecfe0aaSJuraj Linkeš    traffic_generator: CapturingTrafficGenerator
45*cecfe0aaSJuraj Linkeš
46*cecfe0aaSJuraj Linkeš    def __init__(self, node_config: TGNodeConfiguration):
47*cecfe0aaSJuraj Linkeš        super(TGNode, self).__init__(node_config)
48*cecfe0aaSJuraj Linkeš        self.traffic_generator = create_traffic_generator(
49*cecfe0aaSJuraj Linkeš            self, node_config.traffic_generator
50*cecfe0aaSJuraj Linkeš        )
51*cecfe0aaSJuraj Linkeš        self._logger.info(f"Created node: {self.name}")
52*cecfe0aaSJuraj Linkeš
53*cecfe0aaSJuraj Linkeš    def send_packet_and_capture(
54*cecfe0aaSJuraj Linkeš        self,
55*cecfe0aaSJuraj Linkeš        packet: Packet,
56*cecfe0aaSJuraj Linkeš        send_port: Port,
57*cecfe0aaSJuraj Linkeš        receive_port: Port,
58*cecfe0aaSJuraj Linkeš        duration: float = 1,
59*cecfe0aaSJuraj Linkeš    ) -> list[Packet]:
60*cecfe0aaSJuraj Linkeš        """Send a packet, return received traffic.
61*cecfe0aaSJuraj Linkeš
62*cecfe0aaSJuraj Linkeš        Send a packet on the send_port and then return all traffic captured
63*cecfe0aaSJuraj Linkeš        on the receive_port for the given duration. Also record the captured traffic
64*cecfe0aaSJuraj Linkeš        in a pcap file.
65*cecfe0aaSJuraj Linkeš
66*cecfe0aaSJuraj Linkeš        Args:
67*cecfe0aaSJuraj Linkeš            packet: The packet to send.
68*cecfe0aaSJuraj Linkeš            send_port: The egress port on the TG node.
69*cecfe0aaSJuraj Linkeš            receive_port: The ingress port in the TG node.
70*cecfe0aaSJuraj Linkeš            duration: Capture traffic for this amount of time after sending the packet.
71*cecfe0aaSJuraj Linkeš
72*cecfe0aaSJuraj Linkeš        Returns:
73*cecfe0aaSJuraj Linkeš             A list of received packets. May be empty if no packets are captured.
74*cecfe0aaSJuraj Linkeš        """
75*cecfe0aaSJuraj Linkeš        return self.traffic_generator.send_packet_and_capture(
76*cecfe0aaSJuraj Linkeš            packet, send_port, receive_port, duration
77*cecfe0aaSJuraj Linkeš        )
78*cecfe0aaSJuraj Linkeš
79*cecfe0aaSJuraj Linkeš    def close(self) -> None:
80*cecfe0aaSJuraj Linkeš        """Free all resources used by the node"""
81*cecfe0aaSJuraj Linkeš        self.traffic_generator.close()
82*cecfe0aaSJuraj Linkeš        super(TGNode, self).close()
83*cecfe0aaSJuraj Linkeš
84*cecfe0aaSJuraj Linkeš
85*cecfe0aaSJuraj Linkešdef create_traffic_generator(
86*cecfe0aaSJuraj Linkeš    tg_node: TGNode, traffic_generator_config: ScapyTrafficGeneratorConfig
87*cecfe0aaSJuraj Linkeš) -> CapturingTrafficGenerator:
88*cecfe0aaSJuraj Linkeš    """A factory function for creating traffic generator object from user config."""
89*cecfe0aaSJuraj Linkeš
90*cecfe0aaSJuraj Linkeš    from .scapy import ScapyTrafficGenerator
91*cecfe0aaSJuraj Linkeš
92*cecfe0aaSJuraj Linkeš    match traffic_generator_config.traffic_generator_type:
93*cecfe0aaSJuraj Linkeš        case TrafficGeneratorType.SCAPY:
94*cecfe0aaSJuraj Linkeš            return ScapyTrafficGenerator(tg_node, traffic_generator_config)
95*cecfe0aaSJuraj Linkeš        case _:
96*cecfe0aaSJuraj Linkeš            raise ConfigurationError(
97*cecfe0aaSJuraj Linkeš                "Unknown traffic generator: "
98*cecfe0aaSJuraj Linkeš                f"{traffic_generator_config.traffic_generator_type}"
99*cecfe0aaSJuraj Linkeš            )
100