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