<div dir="ltr"><div dir="ltr"><div class="gmail_default" style="font-family:arial,sans-serif"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jan 8, 2024 at 7:01 AM Juraj Linkeš <juraj.linkes@pantheon.tech> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Wed, Jan 3, 2024 at 11:33 PM <<a href="mailto:jspewock@iol.unh.edu" target="_blank">jspewock@iol.unh.edu</a>> wrote:<br>
><br>
> From: Jeremy Spewock <<a href="mailto:jspewock@iol.unh.edu" target="_blank">jspewock@iol.unh.edu</a>><br>
><br>
> Added the options to filter out LLDP and ARP packets when<br>
> sniffing for packets with scapy. This was done using BPF filters to<br>
> ensure that the noise these packets provide does not interfere with test<br>
> cases.<br>
><br>
> Signed-off-by: Jeremy Spewock <<a href="mailto:jspewock@iol.unh.edu" target="_blank">jspewock@iol.unh.edu</a>><br>
> ---<br>
>  dts/framework/test_suite.py                   | 15 +++++++++--<br>
>  dts/framework/testbed_model/tg_node.py        | 14 ++++++++--<br>
>  .../traffic_generator/__init__.py             |  7 ++++-<br>
>  .../capturing_traffic_generator.py            | 22 ++++++++++++++-<br>
>  .../testbed_model/traffic_generator/scapy.py  | 27 +++++++++++++++++++<br>
>  5 files changed, 79 insertions(+), 6 deletions(-)<br>
><br>
<br>
<snip><br>
<br>
> diff --git a/dts/framework/testbed_model/traffic_generator/capturing_traffic_generator.py b/dts/framework/testbed_model/traffic_generator/capturing_traffic_generator.py<br>
> index 0246590333..c1c9facedd 100644<br>
> --- a/dts/framework/testbed_model/traffic_generator/capturing_traffic_generator.py<br>
> +++ b/dts/framework/testbed_model/traffic_generator/capturing_traffic_generator.py<br>
<snip><br>
> @@ -26,6 +27,19 @@ def _get_default_capture_name() -> str:<br>
>      return str(uuid.uuid4())<br>
><br>
><br>
> +@dataclass(slots=True)<br>
<br>
This should also be frozen. If we need a different filter, it's better<br>
to create a new object I think.<br>
<br>
> +class PacketFilteringConfig:<br>
> +    """The supported filtering options for :class:`CapturingTrafficGenerator`.<br>
> +<br>
> +    Attributes:<br>
> +        no_lldp: If :data:`True`, LLDP packets will be filtered out when capturing.<br>
> +        no_arp: If :data:`True`, ARP packets will be filtered out when capturing.<br>
> +    """<br>
> +<br>
> +    no_lldp: bool = True<br>
> +    no_arp: bool = True<br>
> +<br>
> +<br>
>  class CapturingTrafficGenerator(TrafficGenerator):<br>
>      """Capture packets after sending traffic.<br>
><br>
<snip><br>
> diff --git a/dts/framework/testbed_model/traffic_generator/scapy.py b/dts/framework/testbed_model/traffic_generator/scapy.py<br>
> index 5b60f66237..505de0be94 100644<br>
> --- a/dts/framework/testbed_model/traffic_generator/scapy.py<br>
> +++ b/dts/framework/testbed_model/traffic_generator/scapy.py<br>
<snip><br>
> @@ -260,11 +263,34 @@ def _send_packets(self, packets: list[Packet], port: Port) -> None:<br>
>          packets = [packet.build() for packet in packets]<br>
>          self.rpc_server_proxy.scapy_send_packets(packets, port.logical_name)<br>
><br>
> +    def _create_packet_filter(self, filter_config: PacketFilteringConfig) -> str:<br>
> +        """Combines filter settings from `filter_config` into a BPF that scapy can use.<br>
> +<br>
> +        Scapy allows for the use of Berkeley Packet Filters (BPFs) to filter what packets are<br>
> +        collected based on various attributes of the packet.<br>
> +<br>
> +        Args:<br>
> +            filter_config: Config class that specifies which filters should be applied.<br>
> +<br>
> +        Returns:<br>
> +            A string representing the combination of BPF filters to be passed to scapy. For<br>
> +            example:<br>
> +<br>
> +            "ether[12:2] != 0x88cc && ether[12:2] != 0x0806"<br>
> +        """<br>
> +        bpf_filter: list[str] = []<br>
<br>
The type hint here is not needed, so let's make this consistent with<br>
the rest of the code - we don't specify local type hints if they're<br>
not necessary.<br></blockquote><div><br></div><div><div style="font-family:arial,sans-serif" class="gmail_default">Good catch, this might have been left over from when I was experimenting with formatting the filters, I'll remove it.<br></div></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
> +        if filter_config.no_arp:<br>
> +            bpf_filter.append("ether[12:2] != 0x0806")<br>
> +        if filter_config.no_lldp:<br>
> +            bpf_filter.append("ether[12:2] != 0x88cc")<br>
> +        return " && ".join(bpf_filter)<br>
> +<br>
>      def _send_packets_and_capture(<br>
>          self,<br>
>          packets: list[Packet],<br>
>          send_port: Port,<br>
>          receive_port: Port,<br>
> +        filter_config: PacketFilteringConfig,<br>
>          duration: float,<br>
>          capture_name: str = _get_default_capture_name(),<br>
>      ) -> list[Packet]:<br>
</blockquote></div></div>