DPDK patches and discussions
 help / color / mirror / Atom feed
From: Jeremy Spewock <jspewock@iol.unh.edu>
To: Nicholas Pratte <npratte@iol.unh.edu>
Cc: juraj.linkes@pantheon.tech, paul.szczepanek@arm.com,
	probb@iol.unh.edu,  Honnappa.Nagarahalli@arm.com,
	yoan.picchi@foss.arm.com, dmarx@iol.unh.edu,
	 luca.vizzarro@arm.com, bruce.richardson@intel.com, dev@dpdk.org
Subject: Re: [PATCH 3/3] dts: mac filter test suite refactored for new dts
Date: Wed, 26 Jun 2024 11:55:23 -0400	[thread overview]
Message-ID: <CAAA20USesU9a2jDb52+Z32VWJnOX_qBdokCGZxCRBXn2UuZ+rA@mail.gmail.com> (raw)
In-Reply-To: <20240621172059.8194-8-npratte@iol.unh.edu>

On Fri, Jun 21, 2024 at 1:24 PM Nicholas Pratte <npratte@iol.unh.edu> wrote:
>
> The mac address filter test suite, whose test cases are based on old
> DTS's test cases, has been refactored to interface with the new DTS
> framework.
>
> In porting over this test suite into the new framework, some
> adjustments were made, namely in the EAL and TestPMD parameter provided
> before executing the application. While the original test plan was
> referenced, by and large, only for the individual test cases, I'll leave
> the parameters the original test plan was asking for below for the sake
> of discussion:
>
> --burst=1 --rxpt=0 --rxht=0 --rxwt=0 --txpt=36 --txht=0 --txwt=0
> --txfreet=32 --rxfreet=64 --mbcache=250 --portmask=0x3
>
> Bugzilla ID: 1454
> Signed-off-by: Nicholas Pratte <npratte@iol.unh.edu>
> ---
<snip>
> +    def send_packet_and_verify(
> +        self,
> +        mac_address: str,
> +        add_vlan: bool = False,
> +        should_receive: bool = True,
> +    ) -> None:
> +        """Generate, send, and verify a packet based on specified parameters.
> +
> +        Test cases within this suite utilize this method to create, send, and verify
> +        packets based on criteria relating to the packet's destination mac address,
> +        vlan tag, and whether or not the packet should be received or not. Packets
> +        are verified using an inserted payload. If the list of received packets
> +        contains this payload within any of its packets, the test case passes. This
> +        implementation does not require a quiet wire, each call with this method

I don't think we need to mention that it doesn't require a quiet wire,
in general this is something we are writing all test cases to assume.

Looking at this though, it would probably be a great thing to add to
the documentation for writing test suites. We never really mention
anywhere that you must write test cases without this assumption, it's
sort of just something we decided. Of course out of scope of this
patch, but something for the future.

> +        sends exactly one packet.
> +
> +        Args:
> +            mac_address: The destination mac address of the packet being sent.
> +            add_vlan: Add a vlan tag to the packet being sent. :data:'2' if the packet
> +                should be received, :data:'1' if the packet should not be received but
> +                requires a vlan tag, and None for any other condition.

This confused me a little because I thought you were saying this
parameter would be 2 if the packet should be received or it would be 1
in another case. I think this parameter is really just denoting if we
should add a VLAN tag at all, and then the should_receive specifies
what the tag will be. We should probably move the information about
either being 2 or 1 to the `should_receive` documentation and specify
that the VLAN tag will be that value based on if it should be
received.

This is a little hard because it relies on both conditions, but you
can just say in the `should_recieve` parameter that, if there is a
vlan tag, this is what it will be.

> +            should_receive: If :data:'True', assert whether or not the sent packet
> +                has been received. If :data:'False', assert that the send packet was not
> +                received. :data:'True' by default
> +        """
> +        packet = (
> +            Ether()
> +            / Dot1Q(vlan=2 if add_vlan and should_receive else 1 if add_vlan else None)

I haven't used the Dot1Q class in scapy very much myself, but it seems
like just setting vlan=None is strange. Does this just make it
completely omit the VLAN tag? Also, if we don't have a VLAN tag,
should we just not include the Dot1Q layer at all? It feels like it
doesn't really do anything if you don't have a VLAN.

> +            / IP()
> +            / Raw(load="P" * 22)
> +        )
> +        packet.dst = mac_address
> +        received_packets = [
> +            packets
> +            for packets in self.send_packet_and_capture(packet, adjust_addresses=False)
> +            if hasattr(packets, "load") and "P" * 22 in str(packets.load)
> +        ]

i think this would be a little easier using the filter() built-in
Python function. It would instead be:
recieved_packets = [filter(lambda x: if hasattr(x, "load") and "P" *
22 in str(x.load),
 self.send_packet_and_capture(packet, adjust_addresses=False)]

It doesn't really save you that much verbosity now that I've written
it out, you kind of trade the "for x in ..." for "filter(lambda x:
..." so maybe it isn't any more valuable. However, this function for
if a packet has a certain payload is becoming more and more common, I
wonder if we could just add a method to test_suite called
packet_has_payload(p: Packet, payload: str) that just checks does the
packet have the load attribute and does that load attribute match the
desired payload. Or, even better, if we made it a high-order function
that just accepts a payload and then returns a function that validates
if a packet has that payload. Something like this:

def packet_has_payload(payload: str) -> Callable[[Packet], bool]:
    def wrap(p: Packet) -> bool:
        return if hasattr(p, "load") and payload in str(p.load)
    return wrap

If we had this high-order function then filtering becomes super easy.
The filter would just become:
recieved_packets = [filter(self.packet_has_payload("P" * 22),
 self.send_packet_and_capture(packet, adjust_addresses=False)]

Maybe this is something that should be addressed in the bugzilla
ticket 1372 however.

> +        if should_receive:
> +            self.verify(len(received_packets) == 1, "Expected packet not received")
> +        else:
> +            self.verify(len(received_packets) == 0, "Expected packet received")
> +
> +    def test_add_remove_mac_addresses(self) -> None:
> +        """Assess basic mac addressing filtering functionalities.
> +
> +        This test cases validates for proper behavior of mac address filtering with both
> +        a port's default, burned-in mac address, as well as additional mac addresses
> +        added to the PMD. Packets should either be received or not received depending on
> +        the properties applied to the PMD at any given time.
> +
> +        Test:
> +            Start TestPMD with promiscuous mode.
> +            Send a packet with the port's default mac address. (Should receive)
> +            Send a packet with fake mac address. (Should not receive)
> +            Add fake mac address to the PMD's address pool.
> +            Send a packet with the fake mac address to the PMD. (Should receive)
> +            Remove the fake mac address from the PMD's address pool.
> +            Sent a packet with the fake mac address to the PMD. (Should not receive)

Typo: Sent a packet.

> +        """
> +        testpmd = TestPmdShell(self.sut_node)
> +        testpmd.set_promisc(0, on=False, verify=False)

Why don't we want to verify this command? If there is a reason we
should probably leave a comment explaining it.

> +        testpmd.start()
> +        mac_address = self._sut_port_ingress.mac_address
> +
> +        # Send a packet with NIC default mac address
> +        self.send_packet_and_verify(mac_address=mac_address, should_receive=True)
> +        # Send a packet with different mac address
> +        fake_address = "00:00:00:00:00:01"
> +        self.send_packet_and_verify(mac_address=fake_address, should_receive=False)
> +
> +        # Add mac address to pool and rerun tests
> +        testpmd.set_mac_addr(0, mac_address=fake_address, verify=True)

verify=True if the default and we generally omit this, we should
probably omit it here as well.

> +        self.send_packet_and_verify(mac_address=fake_address, should_receive=True)
> +        testpmd.set_mac_addr(0, mac_address=fake_address, add=False)
> +        self.send_packet_and_verify(mac_address=fake_address, should_receive=False)
> +
> +    def test_invalid_address(self) -> None:
> +        """Assess the behavior of a NIC mac address pool while binded to the PMD.

Should this be binded or bound? I think it's bound, but I'm not sure
if it's different when referring to drivers.

> +
> +        An assessment of a NIC's behavior when mounted to a PMD as it relates to mac addresses
> +        and address pooling. Devices should not be able to use invalid mac addresses, remove their
> +        built-in hardware address, or exceed their address pools.
> +
> +        Test:
> +            Start TestPMD.
> +            Attempt to set add an invalid mac address. (Should fail)

Typo: Attempt to set add an invalid address.

> +            Attempt to remove the device's hardware address. (Should fail)
> +            Add a fake mac address to the pool twice in succession. (Should not create any errors)
> +            Attempt to remove the device's hardware address. (Should fail)

I assume the reason this is checked again is making sure it still
fails when the device mac is not the only one in the pool, but we
should probably explain that.

> +            Determine the device's mac address pool size, and fill the pool with fake addresses.
> +            Attempt to add another fake mac address, overloading the address pool. (Should not work)

We say "should fail" everywhere else. Doesn't really change anything,
but it would probably flow a little better to keep this consistent.

> +        """
> +        testpmd = TestPmdShell(self.sut_node)
> +        testpmd.start()
> +        mac_address = self._sut_port_ingress.mac_address
> +        try:
> +            testpmd.set_mac_addr(0, "00:00:00:00:00:00")
> +            self.verify(False, "Invalid mac address added.")
> +        except InteractiveCommandExecutionError:
> +            pass
> +        try:
> +            testpmd.set_mac_addr(0, mac_address, False)
> +            self.verify(False, "Default mac address removed.")
> +        except InteractiveCommandExecutionError:
> +            pass
> +        # Should be no errors adding this twice
> +        testpmd.set_mac_addr(0, f"'1' + {mac_address[1:]}")
> +        testpmd.set_mac_addr(0, f"'1' + {mac_address[1:]}")
> +        # Double check to see if default mac address can be removed
> +        try:
> +            testpmd.set_mac_addr(0, mac_address, False)
> +            self.verify(False, "Default mac address removed.")
> +        except InteractiveCommandExecutionError:
> +            pass
> +
> +        for i in range(testpmd.show_port_info(0).max_mac_addresses_num - 1):
> +            number = str(hex(i)[2:].zfill(4))
> +            fake_address = f'{number[:2] + ":" + number[2:] + mac_address[5:]}'.upper()

It's not immediately obvious to me what this is doing, maybe a comment
of an example about what this would look like for iteration 1 vs
iteration 2 would help make it clear.

> +            testpmd.set_mac_addr(0, fake_address, verify=False)
> +        try:
> +            testpmd.set_mac_addr(0, f'{mac_address[:-1] + "1"}')

What happens here if the last character in the MAC address already is
1? This would fail the test case right?

> +            self.verify(False, "Mac address limit exceeded.")
> +        except InteractiveCommandExecutionError:
> +            pass
> +        testpmd.close()
> +
> +    def test_multicast_filter(self) -> None:
> +        """Assess basic multicast address filtering functionalities.
> +
> +        Ensure that multicast filtering performs as intended when a given device is bound
> +        to the PMD, with and without dot1q vlan tagging.
> +
> +        Test:
> +            Start TestPMD with promiscuous mode.
> +            Add a fake multicast address to the PMD's multicast address pool.
> +            Send a packet with the fake multicast address to the PMD. (Should receive)
> +            Set vlan filtering on the PMD, and add vlan ID to the PMD.

This test case seems like it is trying to test the multicast mac
filtering, do we need to worry about VLAN filtering here as well, or
just simply test when the VLAN tag is present? If possible it's
probably better to avoid the testing of VLAN filtering since that is a
different suite and I would assume that the functionality of filtering
based on VLANs isn't directly related to filtering based on MAC
addresses but I could be wrong.

> +            Send a packet with the fake multicast address and vlan ID to the PMD. (Should receive)
> +            Send a packet with the fake multicast address and a different vlan ID to the PMD.
> +                (Should not receive)
> +            Remove the vlan tag from the PMD, and turn vlan filtering off on the PMD.
> +            Send a packet with the fake multicast address and no vlan tag to the PMD.
> +                (Should receive)
> +            Remove the fake multicast address from the PMDs multicast address filter.
> +            Send a packet with the fake multicast address to the PMD. (Should not receive)
> +        """
<snip>

> --
> 2.44.0
>

  reply	other threads:[~2024-06-26 15:55 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-06-21 17:20 [PATCH 0/3] Mac Filter Port to New DTS Nicholas Pratte
2024-06-21 17:20 ` [PATCH 1/3] dts: add boolean to adjust addresses Nicholas Pratte
2024-06-26 15:49   ` Jeremy Spewock
2024-07-02 13:50     ` Nicholas Pratte
2024-06-21 17:21 ` [PATCH 2/3] dts: add testpmd methods for test suite Nicholas Pratte
2024-06-26 15:50   ` Jeremy Spewock
2024-07-02 13:40     ` Nicholas Pratte
2024-06-21 17:21 ` [PATCH 3/3] dts: mac filter test suite refactored for new dts Nicholas Pratte
2024-06-26 15:55   ` Jeremy Spewock [this message]
2024-07-01 16:49     ` Nicholas Pratte
2024-07-02 18:56 ` [PATCH v2 0/3] dts: mac filter port to " Nicholas Pratte
2024-07-02 18:56 ` [PATCH v2 1/3] dts: add boolean to adjust addresses Nicholas Pratte
2024-07-02 18:56 ` [PATCH v2 2/3] dts: add methods for setting mac and multicast addresses Nicholas Pratte
2024-07-02 18:56 ` [PATCH v2 3/3] dts: mac filter test suite refactored for new dts Nicholas Pratte
2024-07-02 18:59 ` [PATCH v2 0/3] dts: mac filter port to " Nicholas Pratte
2024-07-02 18:59   ` [PATCH v2 1/3] dts: add boolean to adjust addresses Nicholas Pratte
2024-07-02 18:59   ` [PATCH v2 2/3] dts: add methods for setting mac and multicast addresses Nicholas Pratte
2024-07-02 19:04 ` [PATCH v2 0/3] Mac Filter Port to New DTS Nicholas Pratte
2024-07-02 19:04 ` [PATCH v2 1/3] dts: add boolean to adjust addresses Nicholas Pratte
2024-07-02 19:04 ` [PATCH v2 2/3] dts: add methods for setting mac and multicast addresses Nicholas Pratte
2024-07-02 19:04 ` [PATCH v2 3/3] dts: mac filter test suite refactored for new dts Nicholas Pratte
2024-07-02 19:11 ` [PATCH v2 0/3] Mac Filter Port to New DTS Nicholas Pratte
2024-07-02 19:11 ` [PATCH v2 1/3] dts: add boolean to adjust addresses Nicholas Pratte
2024-07-02 19:11 ` [PATCH v2 2/3] dts: add testpmd methods for test suite Nicholas Pratte
2024-07-02 19:11 ` [PATCH v2 3/3] dts: mac filter test suite refactored for new dts Nicholas Pratte

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAAA20USesU9a2jDb52+Z32VWJnOX_qBdokCGZxCRBXn2UuZ+rA@mail.gmail.com \
    --to=jspewock@iol.unh.edu \
    --cc=Honnappa.Nagarahalli@arm.com \
    --cc=bruce.richardson@intel.com \
    --cc=dev@dpdk.org \
    --cc=dmarx@iol.unh.edu \
    --cc=juraj.linkes@pantheon.tech \
    --cc=luca.vizzarro@arm.com \
    --cc=npratte@iol.unh.edu \
    --cc=paul.szczepanek@arm.com \
    --cc=probb@iol.unh.edu \
    --cc=yoan.picchi@foss.arm.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).