aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorAkeel Ali <akeelapi@gmail.com>2025-01-09 12:01:13 -0500
committerMatthew Smith <mgsmith@netgate.com>2025-02-26 15:39:58 +0000
commit9543e29708524accce591eab3aa23270ab44ae1a (patch)
treef56465c95800058c98b210a5653db23b6c385fae /test
parent1cdebd8ca18bdf38af95047b1e9daf520e03030c (diff)
linux-cp: Add support for LACP packets
This patch adds support to mirror LACP packets between host and phy. It is needed for the Sonic-VPP project to support LAG and allow Sonic to run LACP in the control plane. The change has 3 parts: (1) Converted lip_punt_node to lip_punt_xc_inline, which now supports the creation of two distinct nodes: lip_punt_node and lip_punt_xc_node. lip_punt_node retains its original punt functionality. lip_punt_xc_node supports both punt and x-connect between host & phy. (2) Add 2 new API (and corresponding CLI) to the linux-cp plugin: (A) lcp_ethertype_enable ("lcp ethertype enable <ethertype>") (B) lcp_ethertype_get ("show lcp ethertype") (3) Add UT to test the new functionality and API/CLI for LACP and LLDP. Type: improvement Change-Id: Iab66e3b29351dcf2c471babd4f1ef4bdd19da46e Signed-off-by: Akeel Ali <akeelapi@gmail.com>
Diffstat (limited to 'test')
-rw-r--r--test/test_linux_cp.py134
1 files changed, 134 insertions, 0 deletions
diff --git a/test/test_linux_cp.py b/test/test_linux_cp.py
index ff6023cea26..d7116233236 100644
--- a/test/test_linux_cp.py
+++ b/test/test_linux_cp.py
@@ -6,6 +6,14 @@ import socket
from scapy.layers.inet import IP, UDP
from scapy.layers.inet6 import IPv6, Raw
from scapy.layers.l2 import Ether, ARP
+from scapy.contrib.lacp import LACP
+from scapy.contrib.lldp import (
+ LLDPDUChassisID,
+ LLDPDUPortID,
+ LLDPDUTimeToLive,
+ LLDPDUEndOfLLDPDU,
+ LLDPDU,
+)
from util import reassemble4
from vpp_object import VppObject
@@ -427,5 +435,131 @@ class TestLinuxCPIpsec(TemplateIpsec, TemplateIpsecItf4, IpsecTun4):
self.unconfig_network(p)
+@unittest.skipIf("linux-cp" in config.excluded_plugins, "Exclude linux-cp plugin tests")
+class TestLinuxCPEthertype(VppTestCase):
+ """Linux CP Ethertype"""
+
+ extra_vpp_plugin_config = [
+ "plugin",
+ "linux_cp_plugin.so",
+ "{",
+ "enable",
+ "}",
+ "plugin",
+ "linux_cp_unittest_plugin.so",
+ "{",
+ "enable",
+ "}",
+ "plugin",
+ "lldp_plugin.so",
+ "{",
+ "disable",
+ "}",
+ ]
+
+ LACP_ETHERTYPE = 0x8809
+ LLDP_ETHERTYPE = 0x88CC
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestLinuxCPEthertype, cls).setUpClass()
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestLinuxCPEthertype, cls).tearDownClass()
+
+ def setUp(self):
+ super(TestLinuxCPEthertype, self).setUp()
+ self.create_pg_interfaces(range(2))
+ for i in self.pg_interfaces:
+ i.admin_up()
+
+ self.host = self.pg0
+ self.phy = self.pg1
+
+ self.pair = VppLcpPair(self, self.phy, self.host).add_vpp_config()
+ self.logger.info(self.vapi.cli("sh lcp"))
+
+ def tearDown(self):
+ self.pair.remove_vpp_config()
+
+ for i in self.pg_interfaces:
+ i.admin_down()
+ super(TestLinuxCPEthertype, self).tearDown()
+
+ def send_packet(self, sender, receiver, ethertype, dst, data, expect_copy=True):
+ packet = Ether(src=sender.remote_mac, dst=dst, type=ethertype) / data
+ if expect_copy:
+ rxs = self.send_and_expect(sender, [packet], receiver)
+ for rx in rxs:
+ self.assertEqual(packet.show2(True), rx.show2(True))
+ else:
+ self.send_and_assert_no_replies(sender, [packet])
+
+ def send_lacp_packet(self, sender, receiver, expect_copy=True):
+ data = LACP(
+ actor_system="00:00:00:00:00:01", partner_system="00:00:00:00:00:02"
+ )
+ self.send_packet(
+ sender,
+ receiver,
+ self.LACP_ETHERTYPE,
+ "01:80:c2:00:00:02",
+ data,
+ expect_copy,
+ )
+
+ def send_lldp_packet(self, sender, receiver, expect_copy=True):
+ data = (
+ LLDPDUChassisID(subtype=4, id="01:02:03:04:05:06")
+ / LLDPDUPortID(subtype=3, id="07:08:09:0a:0b:0c")
+ / LLDPDUTimeToLive(ttl=120)
+ / LLDPDUEndOfLLDPDU()
+ )
+ self.send_packet(
+ sender,
+ receiver,
+ self.LLDP_ETHERTYPE,
+ "01:80:c2:00:00:0e",
+ data,
+ expect_copy,
+ )
+
+ def check_ethertype_enabled(self, ethertype, enabled=True):
+ reply = self.vapi.lcp_ethertype_get()
+ output = self.vapi.cli("show lcp ethertype")
+
+ if enabled:
+ self.assertIn(ethertype, reply.ethertypes)
+ self.assertIn(hex(ethertype), output)
+ else:
+ self.assertNotIn(ethertype, reply.ethertypes)
+ self.assertNotIn(hex(ethertype), output)
+
+ def test_linux_cp_lacp(self):
+ """Linux CP LACP Test"""
+ self.check_ethertype_enabled(self.LACP_ETHERTYPE, enabled=False)
+ self.send_lacp_packet(self.phy, self.host, expect_copy=False)
+ self.send_lacp_packet(self.host, self.phy, expect_copy=False)
+
+ self.vapi.cli("lcp ethertype enable " + str(self.LACP_ETHERTYPE))
+
+ self.check_ethertype_enabled(self.LACP_ETHERTYPE, enabled=True)
+ self.send_lacp_packet(self.phy, self.host, expect_copy=True)
+ self.send_lacp_packet(self.host, self.phy, expect_copy=True)
+
+ def test_linux_cp_lldp(self):
+ """Linux CP LLDP Test"""
+ self.check_ethertype_enabled(self.LLDP_ETHERTYPE, enabled=False)
+ self.send_lldp_packet(self.phy, self.host, expect_copy=False)
+ self.send_lldp_packet(self.host, self.phy, expect_copy=False)
+
+ self.vapi.cli("lcp ethertype enable " + str(self.LLDP_ETHERTYPE))
+
+ self.check_ethertype_enabled(self.LLDP_ETHERTYPE, enabled=True)
+ self.send_lldp_packet(self.phy, self.host, expect_copy=True)
+ self.send_lldp_packet(self.host, self.phy, expect_copy=True)
+
+
if __name__ == "__main__":
unittest.main(testRunner=VppTestRunner)