On 13 Nov 2025, at 10:36, Changliang Wu wrote:
> Sorry, "After Eelco's review" (⊙ˍ⊙) The plan is to review this after the OVS conference next week. Sorry for the delay. //Eelco > > On Thu, Nov 13, 2025 at 5:30 PM Changliang Wu <[email protected]> > wrote: >> >> Hi, Ilya >> >> >> On Wed, Nov 12, 2025 at 9:18 PM Ilya Maximets <[email protected]> wrote: >>> >>> On 10/31/25 2:09 AM, Changliang Wu wrote: >>>> Add new testsuit for lldp decode. >>> >>> *testsuite >>> >>>> >>>> Signed-off-by: Changliang Wu <[email protected]> >>>> --- >>>> .cirrus.yml | 2 +- >>>> tests/automake.mk | 1 + >>>> tests/ovs-lldp.at | 397 +++++++++++++++++++++++++++++++++++++++++++++ >>>> tests/testsuite.at | 1 + >>>> 4 files changed, 400 insertions(+), 1 deletion(-) >>>> create mode 100644 tests/ovs-lldp.at >>>> >>>> diff --git a/.cirrus.yml b/.cirrus.yml >>>> index d49fbf02e..7031bc092 100644 >>>> --- a/.cirrus.yml >>>> +++ b/.cirrus.yml >>>> @@ -9,7 +9,7 @@ freebsd_build_task: >>>> >>>> env: >>>> DEPENDENCIES: automake libtool gmake gcc openssl python3 >>>> - PY_DEPS: sphinx|netaddr|pyparsing >>>> + PY_DEPS: sphinx|netaddr|pyparsing|scapy >>>> matrix: >>>> COMPILER: gcc >>>> COMPILER: clang >>>> diff --git a/tests/automake.mk b/tests/automake.mk >>>> index 59f538761..a453a0c4b 100644 >>>> --- a/tests/automake.mk >>>> +++ b/tests/automake.mk >>>> @@ -68,6 +68,7 @@ TESTSUITE_AT = \ >>>> tests/tunnel.at \ >>>> tests/tunnel-push-pop.at \ >>>> tests/tunnel-push-pop-ipv6.at \ >>>> + tests/ovs-lldp.at \ >>>> tests/ovs-router.at \ >>>> tests/lockfile.at \ >>>> tests/reconnect.at \ >>>> diff --git a/tests/ovs-lldp.at b/tests/ovs-lldp.at >>>> new file mode 100644 >>>> index 000000000..60998e4e9 >>>> --- /dev/null >>>> +++ b/tests/ovs-lldp.at >>>> @@ -0,0 +1,397 @@ >>>> +AT_BANNER([ovs-lldp]) >>> >>> Can be just 'lldp' or even 'LLDP'. >>> >>>> + >>>> +AT_SETUP([lldp - check lldp neighbor display]) >>>> + >>> >>> We need to skip the test is scapy is not available. >>> Ideally, we shouldn't use scapy for unit tests, unless it is necessary. >>> But I agree that in this particular case it is hard to write a good >>> test without it. So, it's OK. >>> >>> >>>> +OVS_VSWITCHD_START([]) >>>> + >>>> +add_of_ports br0 1 >>>> +AT_CHECK([ >>>> + ovs-vsctl set Interface p1 type=dummy lldp:enable=true >>>> +], [0]) >>> >>> This can be a single line, and the [0] part is not needed, AT_CHECK >>> checks for the zero exit code by default. >>> >>>> + >>>> +AT_CHECK([ovs-appctl netdev-dummy/receive p1 `python3 -c ' >>> >>> nit: Please, use $() instead of ``. >>> >>>> +from scapy.all import * >>>> +from scapy.contrib.lldp import * >>>> +import socket >>>> +packet = Ether(src="aa:aa:aa:aa:aa:aa", dst=LLDP_NEAREST_BRIDGE_MAC)/\ >>>> + LLDPDUChassisID(subtype=LLDPDUChassisID.SUBTYPE_MAC_ADDRESS, >>>> id=b"\x06\x05\x04\x03\x02\x01") /\ >>>> + LLDPDUPortID(subtype=LLDPDUPortID.SUBTYPE_INTERFACE_NAME, >>>> id="GigabitEthernet1/0/1")/\ >>>> + LLDPDUTimeToLive(ttl=121)/\ >>>> + LLDPDUPortDescription(description="FakePortDesc")/\ >>>> + LLDPDUSystemName(system_name="FakeSystemName")/\ >>>> + LLDPDUSystemDescription(description="FakeSystemDesc")/\ >>>> + LLDPDUSystemCapabilities( >>>> + other_available=1, >>>> + repeater_available=1, >>>> + mac_bridge_available=1, >>>> + wlan_access_point_available=1, >>>> + router_available=1, >>>> + telephone_available=1, >>>> + docsis_cable_device_available=1, >>>> + station_only_available=1, >>>> + mac_bridge_enabled=1, >>>> + router_enabled=1 >>> >>> So, these are all enabled here... >>> >>>> + )/\ >>>> + LLDPDUManagementAddress( >>>> + >>>> management_address_subtype=LLDPDUManagementAddress.SUBTYPE_MANAGEMENT_ADDRESS_IPV4, >>>> + management_address=socket.inet_aton("1.2.3.4"), >>>> + >>>> interface_numbering_subtype=LLDPDUManagementAddress.SUBTYPE_INTERFACE_NUMBER_IF_INDEX, >>>> + interface_number=23) /\ >>>> + LLDPDUPowerViaMDI(MDI_power_support="PSE MDI power supported") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_3, >>>> + subtype=4, >>>> + data=int(10240).to_bytes(2,"big")) /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_3, >>>> + subtype=1, >>>> + data=b"\x03\x6c\x01\x00\x1e") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=1, >>>> + data=int(1).to_bytes(2,"big")) /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=2, >>>> + data=b"\x02\x00\x00") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=3, >>>> + data=b"\x00\x01\x05\x56\x4c\x41\x4e\x31") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=3, >>>> + data=b"\x00\x02\x05\x56\x4c\x41\x4e\x32") /\ >>>> + LLDPDUEndOfLLDPDU() >>>> +linehexdump(packet,onlyhex=True)' | tr -d ' '`]) >>>> + >>>> + >>>> +AT_CHECK([ovs-appctl lldp/neighbor p1], [0], [dnl >>>> +[LLDP neighbor: >>>> +Interface: p1 >>>> + ChassisID[mac]: 06:05:04:03:02:01 >>>> + PortID[ifname]: GigabitEthernet1/0/1 >>>> + TTL: 121 >>>> + PortDescr: FakePortDesc >>>> + SysName: FakeSystemName >>>> + SysDescr: FakeSystemDesc >>>> + Capability: Bridge, on >>>> + Capability: Router, on >>>> + Capability: Wlan, off >>>> + Capability: Station, off >>>> + Capability: Repeater, off >>>> + Capability: Telephone, off >>>> + Capability: Docsis, off >>>> + Capability: Other, off >>> >>> But reported as 'off' here. Why? Am I missing something? >> >> AA_available & AA_enable = AA, on >> BB_available = BB, off >> >>> >>>> + MgmtIP: 1.2.3.4 >>>> + MgmtIface: 23 >>>> + MFS: 10240 >>>> + PMD autoneg: supported: yes, enabled: yes >>>> + Adv: 10Base-T, HD: yes, FD: yes >>>> + Adv: 100Base-TX, HD: yes, FD: yes >>>> + Adv: 1000Base-T, HD: no, FD: yes >>>> + MAU oper type: 30 >>>> + MDI Power: supported: yes, enabled: no, pair control: no >>>> + VLAN: 1, pvid: yes, VLAN1 >>>> + VLAN: 2, pvid: no, VLAN2 >>>> + PPVID: 0, supported: yes,enabled no] >>>> +]) >>>> + >>>> +AT_CHECK([ovs-appctl --format json --pretty lldp/neighbor p1 ], [0], [dnl >>>> +[{ >>>> + "lldp": { >>>> + "interface": [ >>>> + { >>>> + "p1": { >>>> + "chassis": { >>>> + "FakeSystemName": { >>>> + "capability": [ >>>> + { >>>> + "enabled": true, >>>> + "type": "Bridge"}, >>>> + { >>>> + "enabled": true, >>>> + "type": "Router"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Wlan"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Station"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Repeater"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Telephone"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Docsis"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Other"}], >>>> + "descr": "FakeSystemDesc", >>>> + "id": { >>>> + "type": "mac", >>>> + "value": "06:05:04:03:02:01"}, >>>> + "mgmt-iface": [ >>>> + 23], >>>> + "mgmt-ip": [ >>>> + "1.2.3.4"]}}, >>>> + "port": { >>>> + "auto-negotiation": { >>>> + "current": 30, >>>> + "enabled": true, >>>> + "supported": true}, >>>> + "desc": "FakePortDesc", >>>> + "id": { >>>> + "type": "ifname", >>>> + "value": "GigabitEthernet1/0/1"}, >>>> + "mfs": 10240, >>>> + "power": { >>>> + "enabled": false, >>>> + "paircontrol": false, >>>> + "supported": true}, >>>> + "ttl": 121}, >>>> + "ppvid": [ >>>> + { >>>> + "enabled": false, >>>> + "supported": true}], >>>> + "vlan": [ >>>> + { >>>> + "pvid": true, >>>> + "value": "VLAN1", >>>> + "vlan-id": 1}, >>>> + { >>>> + "pvid": false, >>>> + "value": "VLAN2", >>>> + "vlan-id": 2}]}}]}}] >>>> +]) >>>> + >>>> +AT_CHECK([ovs-appctl netdev-dummy/receive p1 `python3 -c ' >>>> +from scapy.all import * >>>> +from scapy.contrib.lldp import * >>>> +packet = Ether(src="ee:ee:ee:ee:ee:ee", dst=LLDP_NEAREST_BRIDGE_MAC)/\ >>>> + LLDPDUChassisID(subtype=LLDPDUChassisID.SUBTYPE_NETWORK_ADDRESS, >>>> + family="IPv4", id=b"5.6.7.8") /\ >>>> + LLDPDUPortID(subtype=LLDPDUPortID.SUBTYPE_INTERFACE_NAME, >>>> + id="GigabitEthernet1/0/2")/\ >>>> + LLDPDUTimeToLive(ttl=100)/\ >>>> + LLDPDUPortDescription(description="FakePortDesc1")/\ >>>> + LLDPDUSystemName(system_name="FakeSystemName1")/\ >>>> + LLDPDUSystemDescription(description="FakeSystemDesc1")/\ >>>> + LLDPDUSystemCapabilities( >>>> + mac_bridge_available=1, >>>> + router_available=1, >>>> + mac_bridge_enabled=1 >>>> + )/\ >>>> + LLDPDUManagementAddress( >>>> + >>>> management_address_subtype=LLDPDUManagementAddress.SUBTYPE_MANAGEMENT_ADDRESS_IPV4, >>>> + management_address=socket.inet_aton("11.22.33.44"), >>>> + >>>> interface_numbering_subtype=LLDPDUManagementAddress.SUBTYPE_INTERFACE_NUMBER_IF_INDEX, >>>> + interface_number=100) /\ >>>> + LLDPDUManagementAddress( >>>> + >>>> management_address_subtype=LLDPDUManagementAddress.SUBTYPE_MANAGEMENT_ADDRESS_IPV6, >>>> + management_address=socket.inet_pton(socket.AF_INET6, >>>> "fe00::1"), >>>> + >>>> interface_numbering_subtype=LLDPDUManagementAddress.SUBTYPE_INTERFACE_NUMBER_IF_INDEX, >>>> + interface_number=200) /\ >>>> + LLDPDUPowerViaMDI(MDI_power_support="PSE MDI power supported") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_3, >>>> + subtype=4, >>>> + data=int(10240).to_bytes(2,"big")) /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_3, >>>> + subtype=1, >>>> + data=b"\x03\x6c\x01\x00\x1e") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=1, >>>> + data=int(1).to_bytes(2,"big")) /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=2, >>>> + data=b"\x06\x00\x0f") /\ >>>> + LLDPDUGenericOrganisationSpecific( >>>> + >>>> org_code=LLDPDUGenericOrganisationSpecific.ORG_UNIQUE_CODE_IEEE_802_1, >>>> + subtype=3, >>>> + data=b"\x00\x02\x05\x56\x4c\x41\x4e\x32") /\ >>>> + LLDPDUEndOfLLDPDU() >>>> +linehexdump(packet,onlyhex=True)' | tr -d ' '`]) >>>> + >>>> +AT_CHECK([ovs-appctl lldp/neighbor p1], [0], [dnl >>>> +[LLDP neighbor: >>>> +Interface: p1 >>>> + ChassisID[mac]: 06:05:04:03:02:01 >>>> + PortID[ifname]: GigabitEthernet1/0/1 >>>> + TTL: 121 >>>> + PortDescr: FakePortDesc >>>> + SysName: FakeSystemName >>>> + SysDescr: FakeSystemDesc >>>> + Capability: Bridge, on >>>> + Capability: Router, on >>>> + Capability: Wlan, off >>>> + Capability: Station, off >>>> + Capability: Repeater, off >>>> + Capability: Telephone, off >>>> + Capability: Docsis, off >>>> + Capability: Other, off >>>> + MgmtIP: 1.2.3.4 >>>> + MgmtIface: 23 >>>> + MFS: 10240 >>>> + PMD autoneg: supported: yes, enabled: yes >>>> + Adv: 10Base-T, HD: yes, FD: yes >>>> + Adv: 100Base-TX, HD: yes, FD: yes >>>> + Adv: 1000Base-T, HD: no, FD: yes >>>> + MAU oper type: 30 >>>> + MDI Power: supported: yes, enabled: no, pair control: no >>>> + VLAN: 1, pvid: yes, VLAN1 >>>> + VLAN: 2, pvid: no, VLAN2 >>>> + PPVID: 0, supported: yes,enabled no >>>> + >>>> +Interface: p1 >>>> + ChassisID[ip]: 5.6.7.8 >>>> + PortID[ifname]: GigabitEthernet1/0/2 >>>> + TTL: 100 >>>> + PortDescr: FakePortDesc1 >>>> + SysName: FakeSystemName1 >>>> + SysDescr: FakeSystemDesc1 >>>> + Capability: Bridge, on >>>> + Capability: Router, off >>>> + MgmtIP: 11.22.33.44 >>>> + MgmtIface: 100 >>>> + MgmtIP: fe00::1 >>>> + MgmtIface: 200 >>>> + MFS: 10240 >>>> + PMD autoneg: supported: yes, enabled: yes >>>> + Adv: 10Base-T, HD: yes, FD: yes >>>> + Adv: 100Base-TX, HD: yes, FD: yes >>>> + Adv: 1000Base-T, HD: no, FD: yes >>>> + MAU oper type: 30 >>>> + MDI Power: supported: yes, enabled: no, pair control: no >>>> + VLAN: 2, pvid: no, VLAN2 >>>> + VLAN: 1, pvid: yes >>>> + PPVID: 15, supported: yes,enabled yes] >>>> +]) >>>> + >>>> +AT_CHECK([ovs-appctl --format json --pretty lldp/neighbor p1 ], [0], [dnl >>>> +[{ >>>> + "lldp": { >>>> + "interface": [ >>>> + { >>>> + "p1": { >>>> + "chassis": { >>>> + "FakeSystemName": { >>>> + "capability": [ >>>> + { >>>> + "enabled": true, >>>> + "type": "Bridge"}, >>>> + { >>>> + "enabled": true, >>>> + "type": "Router"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Wlan"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Station"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Repeater"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Telephone"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Docsis"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Other"}], >>>> + "descr": "FakeSystemDesc", >>>> + "id": { >>>> + "type": "mac", >>>> + "value": "06:05:04:03:02:01"}, >>>> + "mgmt-iface": [ >>>> + 23], >>>> + "mgmt-ip": [ >>>> + "1.2.3.4"]}}, >>>> + "port": { >>>> + "auto-negotiation": { >>>> + "current": 30, >>>> + "enabled": true, >>>> + "supported": true}, >>>> + "desc": "FakePortDesc", >>>> + "id": { >>>> + "type": "ifname", >>>> + "value": "GigabitEthernet1/0/1"}, >>>> + "mfs": 10240, >>>> + "power": { >>>> + "enabled": false, >>>> + "paircontrol": false, >>>> + "supported": true}, >>>> + "ttl": 121}, >>>> + "ppvid": [ >>>> + { >>>> + "enabled": false, >>>> + "supported": true}], >>>> + "vlan": [ >>>> + { >>>> + "pvid": true, >>>> + "value": "VLAN1", >>>> + "vlan-id": 1}, >>>> + { >>>> + "pvid": false, >>>> + "value": "VLAN2", >>>> + "vlan-id": 2}]}}, >>>> + { >>>> + "p1": { >>>> + "chassis": { >>>> + "FakeSystemName1": { >>>> + "capability": [ >>>> + { >>>> + "enabled": true, >>>> + "type": "Bridge"}, >>>> + { >>>> + "enabled": false, >>>> + "type": "Router"}], >>>> + "descr": "FakeSystemDesc1", >>>> + "id": { >>>> + "type": "ip", >>>> + "value": "5.6.7.8"}, >>>> + "mgmt-iface": [ >>>> + 100, >>>> + 200], >>>> + "mgmt-ip": [ >>>> + "11.22.33.44", >>>> + "fe00::1"]}}, >>>> + "port": { >>>> + "auto-negotiation": { >>>> + "current": 30, >>>> + "enabled": true, >>>> + "supported": true}, >>>> + "desc": "FakePortDesc1", >>>> + "id": { >>>> + "type": "ifname", >>>> + "value": "GigabitEthernet1/0/2"}, >>>> + "mfs": 10240, >>>> + "power": { >>>> + "enabled": false, >>>> + "paircontrol": false, >>>> + "supported": true}, >>>> + "ttl": 100}, >>>> + "ppvid": [ >>>> + { >>>> + "enabled": true, >>>> + "ppvid": 15, >>>> + "supported": true}], >>>> + "vlan": [ >>>> + { >>>> + "pvid": false, >>>> + "value": "VLAN2", >>>> + "vlan-id": 2}, >>>> + { >>>> + "pvid": true, >>>> + "vlan-id": 1}]}}]}}] >>>> +]) >>>> + >>>> +AT_CLEANUP >>>> \ No newline at end of file >>> >>> Please, add the line break at the end. >> OK, and other small changes will submit together after aaa's review. >> >>> >>>> diff --git a/tests/testsuite.at b/tests/testsuite.at >>>> index 9d77a9f51..f80656076 100644 >>>> --- a/tests/testsuite.at >>>> +++ b/tests/testsuite.at >>>> @@ -66,6 +66,7 @@ m4_include([tests/ofproto-dpif.at]) >>>> m4_include([tests/bridge.at]) >>>> m4_include([tests/netdev-type.at]) >>>> m4_include([tests/ovsdb.at]) >>>> +m4_include([tests/ovs-lldp.at]) >>>> m4_include([tests/ovs-vsctl.at]) >>>> m4_include([tests/stp.at]) >>>> m4_include([tests/rstp.at]) >>> _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
