diff options
| author | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2021-02-11 18:11:46 +0100 |
| commit | 80ec1decc49c72efec2a8b87c06245c92c0ab807 (patch) | |
| tree | e3b229aa94e8dcf0590f2317664176e7b8f7607b /src/core/devices/tests | |
| parent | 65f86e8f56267192d42f2b629fc6b0c99fb9cd0c (diff) | |
New upstream version 1.29.90 upstream/1.29.90
Diffstat (limited to 'src/core/devices/tests')
| -rw-r--r-- | src/core/devices/tests/meson.build | 22 | ||||
| -rw-r--r-- | src/core/devices/tests/test-acd.c | 259 | ||||
| -rw-r--r-- | src/core/devices/tests/test-lldp.c | 1316 |
3 files changed, 1597 insertions, 0 deletions
diff --git a/src/core/devices/tests/meson.build b/src/core/devices/tests/meson.build new file mode 100644 index 00000000..1bc88370 --- /dev/null +++ b/src/core/devices/tests/meson.build @@ -0,0 +1,22 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +test_units = [ + 'test-acd', + 'test-lldp', +] + +foreach test_unit: test_units + exe = executable( + test_unit, + test_unit + '.c', + dependencies: libNetworkManagerTest_dep, + c_args: test_c_flags, + ) + + test( + 'devices/' + test_unit, + test_script, + args: test_args + [exe.full_path()], + timeout: default_test_timeout, + ) +endforeach diff --git a/src/core/devices/tests/test-acd.c b/src/core/devices/tests/test-acd.c new file mode 100644 index 00000000..b0af59db --- /dev/null +++ b/src/core/devices/tests/test-acd.c @@ -0,0 +1,259 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include "n-acd/src/n-acd.h" + +#include <linux/if_ether.h> + +#include "devices/nm-acd-manager.h" +#include "platform/tests/test-common.h" + +#define IFACE_VETH0 "nm-test-veth0" +#define IFACE_VETH1 "nm-test-veth1" + +#define ADDR1 0x01010101 +#define ADDR2 0x02020202 +#define ADDR3 0x03030303 +#define ADDR4 0x04040404 + +/*****************************************************************************/ + +static gboolean +_skip_acd_test_check(void) +{ + NAcd * acd; + NAcdConfig * config; + const guint8 hwaddr[ETH_ALEN] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06}; + int r; + static int skip = -1; + + if (skip == -1) { + r = n_acd_config_new(&config); + g_assert(r == 0); + + n_acd_config_set_ifindex(config, 1); + n_acd_config_set_transport(config, N_ACD_TRANSPORT_ETHERNET); + n_acd_config_set_mac(config, hwaddr, sizeof(hwaddr)); + + r = n_acd_new(&acd, config); + n_acd_config_free(config); + if (r == 0) + n_acd_unref(acd); + + skip = (r != 0); + } + return skip; +} + +#define _skip_acd_test() \ + ({ \ + gboolean _skip = _skip_acd_test_check(); \ + \ + if (_skip) \ + g_test_skip("Cannot create NAcd. Running under valgind?"); \ + _skip; \ + }) + +/*****************************************************************************/ + +typedef struct { + int ifindex0; + int ifindex1; + const guint8 *hwaddr0; + const guint8 *hwaddr1; + size_t hwaddr0_len; + size_t hwaddr1_len; +} test_fixture; + +static void +fixture_setup(test_fixture *fixture, gconstpointer user_data) +{ + /* create veth pair. */ + fixture->ifindex0 = + nmtstp_link_veth_add(NM_PLATFORM_GET, -1, IFACE_VETH0, IFACE_VETH1)->ifindex; + fixture->ifindex1 = + nmtstp_link_get_typed(NM_PLATFORM_GET, -1, IFACE_VETH1, NM_LINK_TYPE_VETH)->ifindex; + + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex0, NULL)); + g_assert(nm_platform_link_set_up(NM_PLATFORM_GET, fixture->ifindex1, NULL)); + + fixture->hwaddr0 = + nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex0, &fixture->hwaddr0_len); + fixture->hwaddr1 = + nm_platform_link_get_address(NM_PLATFORM_GET, fixture->ifindex1, &fixture->hwaddr1_len); +} + +typedef struct { + in_addr_t addresses[8]; + in_addr_t peer_addresses[8]; + gboolean expected_result[8]; +} TestInfo; + +static void +acd_manager_probe_terminated(NMAcdManager *acd_manager, gpointer user_data) +{ + g_main_loop_quit(user_data); +} + +static void +test_acd_common(test_fixture *fixture, TestInfo *info) +{ + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + int i; + const guint WAIT_TIME_OPTIMISTIC = 50; + guint wait_time; + static const NMAcdCallbacks callbacks = { + .probe_terminated_callback = acd_manager_probe_terminated, + .user_data_destroy = (GDestroyNotify) g_main_loop_unref, + }; + int r; + + if (_skip_acd_test()) + return; + + /* first, try with a short waittime. We hope that this is long enough + * to successfully complete the test. Only if that's not the case, we + * assume the computer is currently busy (high load) and we retry with + * a longer timeout. */ + wait_time = WAIT_TIME_OPTIMISTIC; +again: + + nm_clear_pointer(&loop, g_main_loop_unref); + loop = g_main_loop_new(NULL, FALSE); + + nm_clear_pointer(&manager, nm_acd_manager_free); + manager = nm_acd_manager_new(fixture->ifindex0, + fixture->hwaddr0, + fixture->hwaddr0_len, + &callbacks, + g_main_loop_ref(loop)); + g_assert(manager != NULL); + + for (i = 0; info->addresses[i]; i++) + g_assert(nm_acd_manager_add_address(manager, info->addresses[i])); + + for (i = 0; info->peer_addresses[i]; i++) { + nmtstp_ip4_address_add(NULL, + FALSE, + fixture->ifindex1, + info->peer_addresses[i], + 24, + 0, + 3600, + 1800, + 0, + NULL); + } + + r = nm_acd_manager_start_probe(manager, wait_time); + g_assert_cmpint(r, ==, 0); + + g_assert(nmtst_main_loop_run(loop, 2000)); + + for (i = 0; info->addresses[i]; i++) { + gboolean val; + char sbuf[NM_UTILS_INET_ADDRSTRLEN]; + + val = nm_acd_manager_check_address(manager, info->addresses[i]); + if (val == info->expected_result[i]) + continue; + + if (wait_time == WAIT_TIME_OPTIMISTIC) { + /* probably we just had a glitch and the system took longer than + * expected. Re-verify with a large timeout this time. */ + wait_time = 1000; + goto again; + } + + g_error("expected check for address #%d (%s) to %s, but it didn't", + i, + _nm_utils_inet4_ntop(info->addresses[i], sbuf), + info->expected_result[i] ? "detect no duplicated" : "detect a duplicate"); + } +} + +static void +test_acd_probe_1(test_fixture *fixture, gconstpointer user_data) +{ + TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3}, + .peer_addresses = {ADDR4}, + .expected_result = {TRUE, TRUE, TRUE}}; + + test_acd_common(fixture, &info); +} + +static void +test_acd_probe_2(test_fixture *fixture, gconstpointer user_data) +{ + TestInfo info = {.addresses = {ADDR1, ADDR2, ADDR3, ADDR4}, + .peer_addresses = {ADDR3, ADDR2}, + .expected_result = {TRUE, FALSE, FALSE, TRUE}}; + + test_acd_common(fixture, &info); +} + +static void +test_acd_announce(test_fixture *fixture, gconstpointer user_data) +{ + nm_auto_free_acdmgr NMAcdManager *manager = NULL; + nm_auto_unref_gmainloop GMainLoop *loop = NULL; + int r; + + if (_skip_acd_test()) + return; + + manager = + nm_acd_manager_new(fixture->ifindex0, fixture->hwaddr0, fixture->hwaddr0_len, NULL, NULL); + g_assert(manager != NULL); + + g_assert(nm_acd_manager_add_address(manager, ADDR1)); + g_assert(nm_acd_manager_add_address(manager, ADDR2)); + + loop = g_main_loop_new(NULL, FALSE); + r = nm_acd_manager_announce_addresses(manager); + g_assert_cmpint(r, ==, 0); + g_assert(!nmtst_main_loop_run(loop, 200)); +} + +static void +fixture_teardown(test_fixture *fixture, gconstpointer user_data) +{ + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex0); + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex1); +} + +NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup; + +void +_nmtstp_init_tests(int *argc, char ***argv) +{ + nmtst_init_with_logging(argc, argv, NULL, "ALL"); +} + +void +_nmtstp_setup_tests(void) +{ + g_test_add("/acd/probe/1", + test_fixture, + NULL, + fixture_setup, + test_acd_probe_1, + fixture_teardown); + g_test_add("/acd/probe/2", + test_fixture, + NULL, + fixture_setup, + test_acd_probe_2, + fixture_teardown); + g_test_add("/acd/announce", + test_fixture, + NULL, + fixture_setup, + test_acd_announce, + fixture_teardown); +} diff --git a/src/core/devices/tests/test-lldp.c b/src/core/devices/tests/test-lldp.c new file mode 100644 index 00000000..ef0b1549 --- /dev/null +++ b/src/core/devices/tests/test-lldp.c @@ -0,0 +1,1316 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2015 Red Hat, Inc. + */ + +#include "src/core/nm-default-daemon.h" + +#include <fcntl.h> +#include <netinet/if_ether.h> +#include <linux/if_tun.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> + +#include "devices/nm-lldp-listener.h" +#include "systemd/nm-sd.h" + +#include "platform/tests/test-common.h" + +#include "nm-test-utils-core.h" + +/*****************************************************************************/ + +static GVariant * +get_lldp_neighbor(GVariant * neighbors, + int chassis_id_type, + const char *chassis_id, + int port_id_type, + const char *port_id) +{ + GVariantIter iter; + GVariant * variant; + GVariant * result = NULL; + + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + + g_assert(chassis_id_type >= -1 && chassis_id_type <= G_MAXUINT8); + g_assert(port_id_type >= -1 && port_id_type <= G_MAXUINT8); + + g_variant_iter_init(&iter, neighbors); + while (g_variant_iter_next(&iter, "@a{sv}", &variant)) { + gs_unref_variant GVariant *v_chassis_id_type = NULL; + gs_unref_variant GVariant *v_chassis_id = NULL; + gs_unref_variant GVariant *v_port_id_type = NULL; + gs_unref_variant GVariant *v_port_id = NULL; + + v_chassis_id_type = + g_variant_lookup_value(variant, NM_LLDP_ATTR_CHASSIS_ID_TYPE, G_VARIANT_TYPE_UINT32); + g_assert(v_chassis_id_type); + + v_chassis_id = + g_variant_lookup_value(variant, NM_LLDP_ATTR_CHASSIS_ID, G_VARIANT_TYPE_STRING); + g_assert(v_chassis_id); + + v_port_id_type = + g_variant_lookup_value(variant, NM_LLDP_ATTR_PORT_ID_TYPE, G_VARIANT_TYPE_UINT32); + g_assert(v_port_id_type); + + v_port_id = g_variant_lookup_value(variant, NM_LLDP_ATTR_PORT_ID, G_VARIANT_TYPE_STRING); + g_assert(v_port_id); + + if (nm_streq(g_variant_get_string(v_chassis_id, NULL), chassis_id) + && nm_streq(g_variant_get_string(v_port_id, NULL), port_id) + && NM_IN_SET(chassis_id_type, -1, g_variant_get_uint32(v_chassis_id_type)) + && NM_IN_SET(port_id_type, -1, g_variant_get_uint32(v_port_id_type))) { + g_assert(!result); + result = variant; + } else + g_variant_unref(variant); + } + + return result; +} + +typedef struct { + int ifindex; + int fd; + guint8 mac[ETH_ALEN]; +} TestRecvFixture; + +typedef struct { + gsize frame_len; + const uint8_t *frame; + const char * as_variant; +} TestRecvFrame; +#define TEST_RECV_FRAME_DEFINE(name, _as_variant, ...) \ + static const guint8 _##name##_v[] = {__VA_ARGS__}; \ + static const TestRecvFrame name = { \ + .as_variant = _as_variant, \ + .frame_len = sizeof(_##name##_v), \ + .frame = _##name##_v, \ + } + +typedef struct { + guint expected_num_called; + gsize frames_len; + const TestRecvFrame *frames[10]; + void (*check)(GMainLoop *loop, NMLldpListener *listener); +} TestRecvData; +#define TEST_RECV_DATA_DEFINE(name, _expected_num_called, _check, ...) \ + static const TestRecvData name = { \ + .expected_num_called = _expected_num_called, \ + .check = _check, \ + .frames_len = NM_NARG(__VA_ARGS__), \ + .frames = {__VA_ARGS__}, \ + } + +#define TEST_IFNAME "nm-tap-test0" + +TEST_RECV_FRAME_DEFINE( + _test_recv_data0_frame0, + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x33, 0x06, 0x02, 0x00, 0x78, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, " + "0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': <uint32 4>, " + "'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': <uint32 5>, 'port-id': <'1/3'>, " + "'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': " + "<'SYS'>, 'system-description': <'foo'>}", + /* Ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x03, /* Destination MAC */ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, /* Source MAC */ + 0x88, + 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, + 0x04, + 0x05, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x33, /* Port: interface name, "1/3" */ + 0x06, + 0x02, + 0x00, + 0x78, /* TTL: 120 seconds */ + /* LLDP optional TLVs */ + 0x08, + 0x04, + 0x50, + 0x6f, + 0x72, + 0x74, /* Port Description: "Port" */ + 0x0a, + 0x03, + 0x53, + 0x59, + 0x53, /* System Name: "SYS" */ + 0x0c, + 0x04, + 0x66, + 0x6f, + 0x6f, + 0x00, /* System Description: "foo" (NULL-terminated) */ + 0x00, + 0x00 /* End Of LLDPDU */ +); + +static void +_test_recv_data0_check_do(GMainLoop *loop, NMLldpListener *listener, const TestRecvFrame *frame) +{ + GVariant * neighbors, *attr; + gs_unref_variant GVariant *neighbor = NULL; + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 1); + + neighbor = get_lldp_neighbor(neighbors, + SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, + "00:01:02:03:04:05", + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, + "1/3"); + g_assert(neighbor); + g_assert_cmpint(g_variant_n_children(neighbor), ==, 1 + 4 + 4); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, frame->frame, frame->frame_len); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Port"); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "SYS"); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, NM_LLDP_DEST_NEAREST_NON_TPMR_BRIDGE); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "foo"); + nm_clear_g_variant(&attr); +} + +static void +_test_recv_data0_check(GMainLoop *loop, NMLldpListener *listener) +{ + _test_recv_data0_check_do(loop, listener, &_test_recv_data0_frame0); +} + +TEST_RECV_DATA_DEFINE(_test_recv_data0, 1, _test_recv_data0_check, &_test_recv_data0_frame0); +TEST_RECV_DATA_DEFINE(_test_recv_data0_twice, + 1, + _test_recv_data0_check, + &_test_recv_data0_frame0, + &_test_recv_data0_frame0); + +TEST_RECV_FRAME_DEFINE( + _test_recv_data1_frame0, + /* lldp.detailed.pcap from + * https://wiki.wireshark.org/SampleCaptures#Link_Layer_Discovery_Protocol_.28LLDP.29 */ + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x30, 0xf9, 0xad, 0xa0, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x31, 0x06, 0x02, 0x00, 0x78, 0x08, 0x17, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, " + "0x30, 0x2d, 0x34, 0x38, 0x2d, 0x50, 0x6f, 0x72, 0x74, 0x20, 0x31, 0x30, 0x30, 0x31, 0x00, " + "0x0a, 0x0d, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x00, " + "0x0c, 0x4c, 0x53, 0x75, 0x6d, 0x6d, 0x69, 0x74, 0x33, 0x30, 0x30, 0x2d, 0x34, 0x38, 0x20, " + "0x2d, 0x20, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x37, 0x2e, 0x34, 0x65, 0x2e, " + "0x31, 0x20, 0x28, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x20, 0x35, 0x29, 0x20, 0x62, 0x79, 0x20, " + "0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x5f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, " + "0x30, 0x35, 0x2f, 0x32, 0x37, 0x2f, 0x30, 0x35, 0x20, 0x30, 0x34, 0x3a, 0x35, 0x33, 0x3a, " + "0x31, 0x31, 0x00, 0x0e, 0x04, 0x00, 0x14, 0x00, 0x14, 0x10, 0x0e, 0x07, 0x06, 0x00, 0x01, " + "0x30, 0xf9, 0xad, 0xa0, 0x02, 0x00, 0x00, 0x03, 0xe9, 0x00, 0xfe, 0x07, 0x00, 0x12, 0x0f, " + "0x02, 0x07, 0x01, 0x00, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0x6c, 0x00, 0x00, 0x10, " + "0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x00, 0x12, " + "0x0f, 0x04, 0x05, 0xf2, 0xfe, 0x06, 0x00, 0x80, 0xc2, 0x01, 0x01, 0xe8, 0xfe, 0x07, 0x00, " + "0x80, 0xc2, 0x02, 0x01, 0x00, 0x00, 0xfe, 0x16, 0x00, 0x80, 0xc2, 0x03, 0x01, 0xe8, 0x0f, " + "0x76, 0x32, 0x2d, 0x30, 0x34, 0x38, 0x38, 0x2d, 0x30, 0x33, 0x2d, 0x30, 0x35, 0x30, 0x35, " + "0xfe, 0x05, 0x00, 0x80, 0xc2, 0x04, 0x00, 0x00, 0x00]>, 'chassis-id-type': <uint32 4>, " + "'chassis-id': <'00:01:30:F9:AD:A0'>, 'port-id-type': <uint32 5>, 'port-id': <'1/1'>, " + "'destination': <'nearest-bridge'>, 'port-description': <'Summit300-48-Port 1001'>, " + "'system-name': <'Summit300-48'>, 'system-description': <'Summit300-48 - Version 7.4e.1 (Build " + "5) by Release_Master 05/27/05 04:53:11'>, 'system-capabilities': <uint32 20>, " + "'management-addresses': <[{'address-subtype': <uint32 6>, 'address': <[byte 0x00, 0x01, 0x30, " + "0xf9, 0xad, 0xa0]>, 'interface-number-subtype': <uint32 2>, 'interface-number': <uint32 " + "1001>}]>, 'ieee-802-1-pvid': <uint32 488>, 'ieee-802-1-ppvid': <uint32 0>, " + "'ieee-802-1-ppvid-flags': <uint32 1>, 'ieee-802-1-ppvids': <[{'ppvid': <uint32 0>, 'flags': " + "<uint32 1>}]>, 'ieee-802-1-vid': <uint32 488>, 'ieee-802-1-vlan-name': <'v2-0488-03-0505'>, " + "'ieee-802-1-vlans': <[{'vid': <uint32 488>, 'name': <'v2-0488-03-0505'>}]>, " + "'ieee-802-3-mac-phy-conf': <{'autoneg': <uint32 3>, 'pmd-autoneg-cap': <uint32 27648>, " + "'operational-mau-type': <uint32 16>}>, 'ieee-802-3-power-via-mdi': <{'mdi-power-support': " + "<uint32 7>, 'pse-power-pair': <uint32 1>, 'power-class': <uint32 0>}>, " + "'ieee-802-3-max-frame-size': <uint32 1522>}", + /* ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x0e, /* destination mac */ + 0x00, + 0x01, + 0x30, + 0xf9, + 0xad, + 0xa0, /* source mac */ + 0x88, + 0xcc, /* ethernet type */ + + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x30, /* Chassis Subtype */ + 0xf9, + 0xad, + 0xa0, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x31, /* Port Subtype */ + 0x06, + 0x02, + 0x00, + 0x78, /* Time To Live */ + 0x08, + 0x17, + 0x53, + 0x75, + 0x6d, + 0x6d, /* Port Description */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x2d, + 0x50, + 0x6f, + 0x72, + 0x74, + 0x20, + 0x31, + 0x30, + 0x30, + 0x31, + 0x00, + 0x0a, + 0x0d, + 0x53, + 0x75, + 0x6d, + 0x6d, /* System Name */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x00, + 0x0c, + 0x4c, + 0x53, + 0x75, + 0x6d, + 0x6d, /* System Description */ + 0x69, + 0x74, + 0x33, + 0x30, + 0x30, + 0x2d, + 0x34, + 0x38, + 0x20, + 0x2d, + 0x20, + 0x56, + 0x65, + 0x72, + 0x73, + 0x69, + 0x6f, + 0x6e, + 0x20, + 0x37, + 0x2e, + 0x34, + 0x65, + 0x2e, + 0x31, + 0x20, + 0x28, + 0x42, + 0x75, + 0x69, + 0x6c, + 0x64, + 0x20, + 0x35, + 0x29, + 0x20, + 0x62, + 0x79, + 0x20, + 0x52, + 0x65, + 0x6c, + 0x65, + 0x61, + 0x73, + 0x65, + 0x5f, + 0x4d, + 0x61, + 0x73, + 0x74, + 0x65, + 0x72, + 0x20, + 0x30, + 0x35, + 0x2f, + 0x32, + 0x37, + 0x2f, + 0x30, + 0x35, + 0x20, + 0x30, + 0x34, + 0x3a, + 0x35, + 0x33, + 0x3a, + 0x31, + 0x31, + 0x00, + 0x0e, + 0x04, + 0x00, + 0x14, + 0x00, + 0x14, /* Capabilities */ + 0x10, + 0x0e, + 0x07, + 0x06, + 0x00, + 0x01, /* Management Address */ + 0x30, + 0xf9, + 0xad, + 0xa0, + 0x02, + 0x00, + 0x00, + 0x03, + 0xe9, + 0x00, + 0xfe, + 0x07, + 0x00, + 0x12, + 0x0f, + 0x02, /* IEEE 802.3 - Power Via MDI */ + 0x07, + 0x01, + 0x00, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x01, /* IEEE 802.3 - MAC/PHY Configuration/Status */ + 0x03, + 0x6c, + 0x00, + 0x00, + 0x10, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x03, /* IEEE 802.3 - Link Aggregation */ + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfe, + 0x06, + 0x00, + 0x12, + 0x0f, + 0x04, /* IEEE 802.3 - Maximum Frame Size */ + 0x05, + 0xf2, + 0xfe, + 0x06, + 0x00, + 0x80, + 0xc2, + 0x01, /* IEEE 802.1 - Port VLAN ID */ + 0x01, + 0xe8, + 0xfe, + 0x07, + 0x00, + 0x80, + 0xc2, + 0x02, /* IEEE 802.1 - Port and Protocol VLAN ID */ + 0x01, + 0x00, + 0x00, + 0xfe, + 0x16, + 0x00, + 0x80, + 0xc2, + 0x03, /* IEEE 802.1 - VLAN Name */ + 0x01, + 0xe8, + 0x0f, + 0x76, + 0x32, + 0x2d, + 0x30, + 0x34, + 0x38, + 0x38, + 0x2d, + 0x30, + 0x33, + 0x2d, + 0x30, + 0x35, + 0x30, + 0x35, + 0xfe, + 0x05, + 0x00, + 0x80, + 0xc2, + 0x04, /* IEEE 802.1 - Protocol Identity */ + 0x00, + 0x00, + 0x00 /* End of LLDPDU */ +); + +static void +_test_recv_data1_check(GMainLoop *loop, NMLldpListener *listener) +{ + GVariant * neighbors, *attr, *child; + gs_unref_variant GVariant *neighbor = NULL; + guint v_uint = 0; + const char * v_str = NULL; + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 1); + + neighbor = get_lldp_neighbor(neighbors, + SD_LLDP_CHASSIS_SUBTYPE_MAC_ADDRESS, + "00:01:30:F9:AD:A0", + SD_LLDP_PORT_SUBTYPE_INTERFACE_NAME, + "1/1"); + g_assert(neighbor); + g_assert_cmpint(g_variant_n_children(neighbor), ==, 1 + 4 + 16); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, + _test_recv_data1_frame0.frame, + _test_recv_data1_frame0.frame_len); + nm_clear_g_variant(&attr); + + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_DESTINATION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, NM_LLDP_DEST_NEAREST_BRIDGE); + nm_clear_g_variant(&attr); + + /* unsupported: Time To Live */ + + /* Port Description */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_PORT_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Summit300-48-Port 1001"); + nm_clear_g_variant(&attr); + + /* System Name */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "Summit300-48"); + nm_clear_g_variant(&attr); + + /* System Description */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_DESCRIPTION, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string( + attr, + "Summit300-48 - Version 7.4e.1 (Build 5) by Release_Master 05/27/05 04:53:11"); + nm_clear_g_variant(&attr); + + /* Capabilities */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_SYSTEM_CAPABILITIES, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 20); + nm_clear_g_variant(&attr); + + /* Management Address */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_MANAGEMENT_ADDRESSES, + G_VARIANT_TYPE("aa{sv}")); + g_assert(attr); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "interface-number", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1001); + g_assert(g_variant_lookup(child, "interface-number-subtype", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 2); + g_assert(g_variant_lookup(child, "address-subtype", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 6); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* IEEE 802.3 - Power Via MDI */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_POWER_VIA_MDI, + G_VARIANT_TYPE_VARDICT); + g_assert(attr); + g_assert(g_variant_lookup(attr, "mdi-power-support", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 7); + g_assert(g_variant_lookup(attr, "pse-power-pair", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1); + g_assert(g_variant_lookup(attr, "power-class", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0); + nm_clear_g_variant(&attr); + + /* IEEE 802.3 - MAC/PHY Configuration/Status */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_MAC_PHY_CONF, + G_VARIANT_TYPE_VARDICT); + g_assert(attr); + g_assert(g_variant_lookup(attr, "autoneg", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 3); + g_assert(g_variant_lookup(attr, "pmd-autoneg-cap", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0x6c00); + g_assert(g_variant_lookup(attr, "operational-mau-type", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 16); + nm_clear_g_variant(&attr); + + /* unsupported: IEEE 802.3 - Link Aggregation */ + + /* Maximum Frame Size */ + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_3_MAX_FRAME_SIZE, + G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 1522); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - Port VLAN ID */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PVID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 488); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - Port and Protocol VLAN ID */ + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 0); + nm_clear_g_variant(&attr); + attr = g_variant_lookup_value(neighbor, + NM_LLDP_ATTR_IEEE_802_1_PPVID_FLAGS, + G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 1); + nm_clear_g_variant(&attr); + + /* new PPVID attributes */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_PPVIDS, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "ppvid", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 0); + g_assert(g_variant_lookup(child, "flags", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 1); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* IEEE 802.1 - VLAN Name */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VLAN_NAME, G_VARIANT_TYPE_STRING); + nmtst_assert_variant_string(attr, "v2-0488-03-0505"); + nm_clear_g_variant(&attr); + attr = g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VID, G_VARIANT_TYPE_UINT32); + nmtst_assert_variant_uint32(attr, 488); + nm_clear_g_variant(&attr); + + /* new VLAN attributes */ + attr = + g_variant_lookup_value(neighbor, NM_LLDP_ATTR_IEEE_802_1_VLANS, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpuint(g_variant_n_children(attr), ==, 1); + child = g_variant_get_child_value(attr, 0); + g_assert(child); + g_assert(g_variant_lookup(child, "vid", "u", &v_uint)); + g_assert_cmpint(v_uint, ==, 488); + g_assert(g_variant_lookup(child, "name", "&s", &v_str)); + g_assert_cmpstr(v_str, ==, "v2-0488-03-0505"); + nm_clear_g_variant(&child); + nm_clear_g_variant(&attr); + + /* unsupported: IEEE 802.1 - Protocol Identity */ +} + +TEST_RECV_DATA_DEFINE(_test_recv_data1, 1, _test_recv_data1_check, &_test_recv_data1_frame0); + +TEST_RECV_FRAME_DEFINE( + _test_recv_data2_frame0_ttl1, + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x04, 0x04, 0x05, 0x31, 0x2f, " + "0x33, 0x06, 0x02, 0x00, 0x01, 0x08, 0x04, 0x50, 0x6f, 0x72, 0x74, 0x0a, 0x03, 0x53, 0x59, " + "0x53, 0x0c, 0x04, 0x66, 0x6f, 0x6f, 0x00, 0x00, 0x00]>, 'chassis-id-type': <uint32 4>, " + "'chassis-id': <'00:01:02:03:04:05'>, 'port-id-type': <uint32 5>, 'port-id': <'1/3'>, " + "'destination': <'nearest-non-tpmr-bridge'>, 'port-description': <'Port'>, 'system-name': " + "<'SYS'>, 'system-description': <'foo'>}", + /* Ethernet header */ + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x03, /* Destination MAC */ + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, /* Source MAC */ + 0x88, + 0xcc, /* Ethertype */ + /* LLDP mandatory TLVs */ + 0x02, + 0x07, + 0x04, + 0x00, + 0x01, + 0x02, /* Chassis: MAC, 00:01:02:03:04:05 */ + 0x03, + 0x04, + 0x05, + 0x04, + 0x04, + 0x05, + 0x31, + 0x2f, + 0x33, /* Port: interface name, "1/3" */ + 0x06, + 0x02, + 0x00, + 0x01, /* TTL: 1 seconds */ + /* LLDP optional TLVs */ + 0x08, + 0x04, + 0x50, + 0x6f, + 0x72, + 0x74, /* Port Description: "Port" */ + 0x0a, + 0x03, + 0x53, + 0x59, + 0x53, /* System Name: "SYS" */ + 0x0c, + 0x04, + 0x66, + 0x6f, + 0x6f, + 0x00, /* System Description: "foo" (NULL-terminated) */ + 0x00, + 0x00 /* End Of LLDPDU */ +); + +static void +_test_recv_data2_ttl1_check(GMainLoop *loop, NMLldpListener *listener) +{ + gulong notify_id; + GVariant *neighbors; + + _test_recv_data0_check_do(loop, listener, &_test_recv_data2_frame0_ttl1); + + /* wait for signal. */ + notify_id = g_signal_connect(listener, + "notify::" NM_LLDP_LISTENER_NEIGHBORS, + nmtst_main_loop_quit_on_notify, + loop); + if (!nmtst_main_loop_run(loop, 5000)) + g_assert_not_reached(); + nm_clear_g_signal_handler(listener, ¬ify_id); + + neighbors = nm_lldp_listener_get_neighbors(listener); + nmtst_assert_variant_is_of_type(neighbors, G_VARIANT_TYPE("aa{sv}")); + g_assert_cmpint(g_variant_n_children(neighbors), ==, 0); +} + +TEST_RECV_DATA_DEFINE(_test_recv_data2_ttl1, + 1, + _test_recv_data2_ttl1_check, + &_test_recv_data2_frame0_ttl1); + +static void +_test_recv_fixture_setup(TestRecvFixture *fixture, gconstpointer user_data) +{ + const NMPlatformLink *link; + nm_auto_close int fd = -1; + + fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC); + if (fd == -1) { + g_test_skip("Unable to open /dev/net/tun"); + fixture->ifindex = 0; + return; + } + + if (nmtst_get_rand_bool()) { + const NMPlatformLnkTun lnk = { + .type = IFF_TAP, + .pi = FALSE, + .vnet_hdr = FALSE, + .multi_queue = FALSE, + .persist = FALSE, + }; + + nm_close(nm_steal_fd(&fd)); + + link = nmtstp_link_tun_add(NM_PLATFORM_GET, FALSE, TEST_IFNAME, &lnk, &fd); + g_assert(link); + nmtstp_link_set_updown(NM_PLATFORM_GET, -1, link->ifindex, TRUE); + link = nmtstp_assert_wait_for_link(NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 0); + } else { + int s; + struct ifreq ifr; + int r; + int try_cnt = 0; + +again: + memset(&ifr, 0, sizeof(ifr)); + ifr.ifr_flags = IFF_TAP | IFF_NO_PI; + nm_utils_ifname_cpy(ifr.ifr_name, TEST_IFNAME); + + r = ioctl(fd, TUNSETIFF, &ifr); + if (r != 0) { + if (errno == EPERM && try_cnt++ < 10) { + g_usleep(2); + goto again; + } + g_assert_cmpint(errno, ==, 0); + g_assert_cmpint(r, ==, 0); + } + + /* Bring the interface up */ + s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); + g_assert(s >= 0); + + ifr.ifr_flags |= IFF_UP; + r = ioctl(s, SIOCSIFFLAGS, &ifr); + if (r != 0) { + g_assert_cmpint(errno, ==, 0); + g_assert_cmpint(r, ==, 0); + } + + nm_close(s); + + link = nmtstp_assert_wait_for_link(NM_PLATFORM_GET, TEST_IFNAME, NM_LINK_TYPE_TUN, 100); + } + + fixture->ifindex = link->ifindex; + fixture->fd = nm_steal_fd(&fd); + memcpy(fixture->mac, link->l_address.data, ETH_ALEN); +} + +typedef struct { + int num_called; +} TestRecvCallbackInfo; + +static void +lldp_neighbors_changed(NMLldpListener *lldp_listener, GParamSpec *pspec, gpointer user_data) +{ + TestRecvCallbackInfo *info = user_data; + + info->num_called++; +} + +static void +test_recv(TestRecvFixture *fixture, gconstpointer user_data) +{ + const TestRecvData *data = user_data; + gs_unref_object NMLldpListener *listener = NULL; + GMainLoop * loop; + TestRecvCallbackInfo info = {}; + gsize i_frames; + gulong notify_id; + GError * error = NULL; + guint sd_id; + + if (fixture->ifindex == 0) { + g_test_skip("Tun device not available"); + return; + } + + listener = nm_lldp_listener_new(); + g_assert(listener != NULL); + g_assert(nm_lldp_listener_start(listener, fixture->ifindex, &error)); + g_assert_no_error(error); + + notify_id = g_signal_connect(listener, + "notify::" NM_LLDP_LISTENER_NEIGHBORS, + (GCallback) lldp_neighbors_changed, + &info); + loop = g_main_loop_new(NULL, FALSE); + sd_id = nm_sd_event_attach_default(); + + for (i_frames = 0; i_frames < data->frames_len; i_frames++) { + const TestRecvFrame *f = data->frames[i_frames]; + + g_assert(write(fixture->fd, f->frame, f->frame_len) == f->frame_len); + } + + if (nmtst_main_loop_run(loop, 500)) + g_assert_not_reached(); + + g_assert_cmpint(info.num_called, ==, data->expected_num_called); + + nm_clear_g_signal_handler(listener, ¬ify_id); + + data->check(loop, listener); + + nm_clear_g_source(&sd_id); + nm_clear_pointer(&loop, g_main_loop_unref); +} + +static void +_test_recv_fixture_teardown(TestRecvFixture *fixture, gconstpointer user_data) +{ + if (fixture->ifindex) + nm_platform_link_delete(NM_PLATFORM_GET, fixture->ifindex); +} + +/*****************************************************************************/ + +static void +test_parse_frames(gconstpointer test_data) +{ + const TestRecvFrame *frame = test_data; + gs_unref_variant GVariant *v_neighbor = NULL; + gs_unref_variant GVariant *attr = NULL; + gs_free char * as_variant = NULL; + + v_neighbor = nmtst_lldp_parse_from_raw(frame->frame, frame->frame_len); + g_assert(v_neighbor); + + attr = g_variant_lookup_value(v_neighbor, NM_LLDP_ATTR_RAW, G_VARIANT_TYPE_BYTESTRING); + nmtst_assert_variant_bytestring(attr, frame->frame, frame->frame_len); + nm_clear_g_variant(&attr); + + as_variant = g_variant_print(v_neighbor, TRUE); + g_assert(as_variant); + g_assert_cmpstr(frame->as_variant, ==, as_variant); +} + +/*****************************************************************************/ + +TEST_RECV_FRAME_DEFINE( + _test_parse_frames_3, + /* https://github.com/the-tcpdump-group/tcpdump/blob/c4f8796bf8bec740621a360eded236d8991ea00f/tests/lldp_mudurl.pcap */ + "{'raw': <[byte 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x88, " + "0xcc, 0x02, 0x07, 0x04, 0x00, 0x23, 0x54, 0xc2, 0x57, 0x02, 0x04, 0x07, 0x03, 0x00, 0x23, " + "0x54, 0xc2, 0x57, 0x02, 0x06, 0x02, 0x00, 0x78, 0x0a, 0x1c, 0x75, 0x70, 0x73, 0x74, 0x61, " + "0x69, 0x72, 0x73, 0x2e, 0x6f, 0x66, 0x63, 0x6f, 0x75, 0x72, 0x73, 0x65, 0x69, 0x6d, 0x72, " + "0x69, 0x67, 0x68, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x0c, 0x5c, 0x55, 0x62, 0x75, 0x6e, 0x74, " + "0x75, 0x20, 0x31, 0x34, 0x2e, 0x30, 0x34, 0x2e, 0x35, 0x20, 0x4c, 0x54, 0x53, 0x20, 0x4c, " + "0x69, 0x6e, 0x75, 0x78, 0x20, 0x33, 0x2e, 0x31, 0x33, 0x2e, 0x30, 0x2d, 0x31, 0x30, 0x36, " + "0x2d, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x69, 0x63, 0x20, 0x23, 0x31, 0x35, 0x33, 0x2d, 0x55, " + "0x62, 0x75, 0x6e, 0x74, 0x75, 0x20, 0x53, 0x4d, 0x50, 0x20, 0x54, 0x75, 0x65, 0x20, 0x44, " + "0x65, 0x63, 0x20, 0x36, 0x20, 0x31, 0x35, 0x3a, 0x34, 0x35, 0x3a, 0x31, 0x33, 0x20, 0x55, " + "0x54, 0x43, 0x20, 0x32, 0x30, 0x31, 0x36, 0x20, 0x69, 0x36, 0x38, 0x36, 0x0e, 0x04, 0x00, " + "0x9c, 0x00, 0x08, 0x10, 0x0c, 0x05, 0x01, 0x3e, 0x0c, 0xad, 0x72, 0x02, 0x00, 0x00, 0x00, " + "0x02, 0x00, 0x10, 0x18, 0x11, 0x02, 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, 0x00, 0x04, 0x02, " + "0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x08, 0x04, " + "0x65, 0x74, 0x68, 0x30, 0xfe, 0x09, 0x00, 0x12, 0x0f, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, " + "0xfe, 0x09, 0x00, 0x12, 0x0f, 0x01, 0x03, 0xec, 0xc3, 0x00, 0x10, 0xfe, 0x40, 0x00, 0x00, " + "0x5e, 0x01, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x69, 0x6d, 0x72, 0x69, 0x67, " + "0x68, 0x74, 0x2e, 0x6d, 0x75, 0x64, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, " + "0x63, 0x6f, 0x6d, 0x2f, 0x2e, 0x77, 0x65, 0x6c, 0x6c, 0x2d, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, " + "0x2f, 0x6d, 0x75, 0x64, 0x2f, 0x76, 0x31, 0x2f, 0x76, 0x6f, 0x6d, 0x69, 0x74, 0x76, 0x32, " + "0x2e, 0x30, 0x00, 0x00]>, 'chassis-id-type': <uint32 4>, 'chassis-id': <'00:23:54:C2:57:02'>, " + "'port-id-type': <uint32 3>, 'port-id': <'00:23:54:C2:57:02'>, 'destination': " + "<'nearest-bridge'>, 'port-description': <'eth0'>, 'system-name': " + "<'upstairs.ofcourseimright.com'>, 'system-description': <'Ubuntu 14.04.5 LTS Linux " + "3.13.0-106-generic #153-Ubuntu SMP Tue Dec 6 15:45:13 UTC 2016 i686'>, 'system-capabilities': " + "<uint32 156>, 'management-addresses': <[{'address-subtype': <uint32 1>, 'address': <[byte " + "0x3e, 0x0c, 0xad, 0x72]>, 'interface-number-subtype': <uint32 2>, 'interface-number': <uint32 " + "2>}, {'address-subtype': <uint32 2>, 'address': <[byte 0x20, 0x01, 0x08, 0xa8, 0x10, 0x06, " + "0x00, 0x04, 0x02, 0x23, 0x54, 0xff, 0xfe, 0xc2, 0x57, 0x02]>, 'interface-number-subtype': " + "<uint32 2>, 'interface-number': <uint32 2>}]>, 'ieee-802-3-mac-phy-conf': <{'autoneg': " + "<uint32 3>, 'pmd-autoneg-cap': <uint32 60611>, 'operational-mau-type': <uint32 16>}>, " + "'mud-url': <'https://imright.mud.example.com/.well-known/mud/v1/vomitv2.0'>}", + 0x01, + 0x80, + 0xc2, + 0x00, + 0x00, + 0x0e, /* ethernet destination */ + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, /* ethernet source */ + 0x88, + 0xcc, /* ethernet type */ + + 0x02, + 0x07, + 0x04, + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, + 0x04, + 0x07, + 0x03, + 0x00, + 0x23, + 0x54, + 0xc2, + 0x57, + 0x02, + 0x06, + 0x02, + 0x00, + 0x78, + 0x0a, + 0x1c, + 0x75, + 0x70, + 0x73, + 0x74, + 0x61, + 0x69, + 0x72, + 0x73, + 0x2e, + 0x6f, + 0x66, + 0x63, + 0x6f, + 0x75, + 0x72, + 0x73, + 0x65, + 0x69, + 0x6d, + 0x72, + 0x69, + 0x67, + 0x68, + 0x74, + 0x2e, + 0x63, + 0x6f, + 0x6d, + 0x0c, + 0x5c, + 0x55, + 0x62, + 0x75, + 0x6e, + 0x74, + 0x75, + 0x20, + 0x31, + 0x34, + 0x2e, + 0x30, + 0x34, + 0x2e, + 0x35, + 0x20, + 0x4c, + 0x54, + 0x53, + 0x20, + 0x4c, + 0x69, + 0x6e, + 0x75, + 0x78, + 0x20, + 0x33, + 0x2e, + 0x31, + 0x33, + 0x2e, + 0x30, + 0x2d, + 0x31, + 0x30, + 0x36, + 0x2d, + 0x67, + 0x65, + 0x6e, + 0x65, + 0x72, + 0x69, + 0x63, + 0x20, + 0x23, + 0x31, + 0x35, + 0x33, + 0x2d, + 0x55, + 0x62, + 0x75, + 0x6e, + 0x74, + 0x75, + 0x20, + 0x53, + 0x4d, + 0x50, + 0x20, + 0x54, + 0x75, + 0x65, + 0x20, + 0x44, + 0x65, + 0x63, + 0x20, + 0x36, + 0x20, + 0x31, + 0x35, + 0x3a, + 0x34, + 0x35, + 0x3a, + 0x31, + 0x33, + 0x20, + 0x55, + 0x54, + 0x43, + 0x20, + 0x32, + 0x30, + 0x31, + 0x36, + 0x20, + 0x69, + 0x36, + 0x38, + 0x36, + 0x0e, + 0x04, + 0x00, + 0x9c, + 0x00, + 0x08, + 0x10, + 0x0c, + 0x05, + 0x01, + 0x3e, + 0x0c, + 0xad, + 0x72, + 0x02, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x10, + 0x18, + 0x11, + 0x02, + 0x20, + 0x01, + 0x08, + 0xa8, + 0x10, + 0x06, + 0x00, + 0x04, + 0x02, + 0x23, + 0x54, + 0xff, + 0xfe, + 0xc2, + 0x57, + 0x02, + 0x02, + 0x00, + 0x00, + 0x00, + 0x02, + 0x00, + 0x08, + 0x04, + 0x65, + 0x74, + 0x68, + 0x30, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x03, + 0x01, + 0x00, + 0x00, + 0x00, + 0x00, + 0xfe, + 0x09, + 0x00, + 0x12, + 0x0f, + 0x01, + 0x03, + 0xec, + 0xc3, + 0x00, + 0x10, + 0xfe, + 0x40, + 0x00, + 0x00, + 0x5e, + 0x01, + 0x68, + 0x74, + 0x74, + 0x70, + 0x73, + 0x3a, + 0x2f, + 0x2f, + 0x69, + 0x6d, + 0x72, + 0x69, + 0x67, + 0x68, + 0x74, + 0x2e, + 0x6d, + 0x75, + 0x64, + 0x2e, + 0x65, + 0x78, + 0x61, + 0x6d, + 0x70, + 0x6c, + 0x65, + 0x2e, + 0x63, + 0x6f, + 0x6d, + 0x2f, + 0x2e, + 0x77, + 0x65, + 0x6c, + 0x6c, + 0x2d, + 0x6b, + 0x6e, + 0x6f, + 0x77, + 0x6e, + 0x2f, + 0x6d, + 0x75, + 0x64, + 0x2f, + 0x76, + 0x31, + 0x2f, + 0x76, + 0x6f, + 0x6d, + 0x69, + 0x74, + 0x76, + 0x32, + 0x2e, + + 0x30, + 0x00, + 0x00, /* ethernet trailer */ +); + +/*****************************************************************************/ + +NMTstpSetupFunc const _nmtstp_setup_platform_func = nm_linux_platform_setup; + +void +_nmtstp_init_tests(int *argc, char ***argv) +{ + nmtst_init_assert_logging(argc, argv, "WARN", "ALL"); +} + +void +_nmtstp_setup_tests(void) +{ +#define _TEST_ADD_RECV(testpath, testdata) \ + g_test_add(testpath, \ + TestRecvFixture, \ + testdata, \ + _test_recv_fixture_setup, \ + test_recv, \ + _test_recv_fixture_teardown) + _TEST_ADD_RECV("/lldp/recv/0", &_test_recv_data0); + _TEST_ADD_RECV("/lldp/recv/0_twice", &_test_recv_data0_twice); + _TEST_ADD_RECV("/lldp/recv/1", &_test_recv_data1); + _TEST_ADD_RECV("/lldp/recv/2_ttl1", &_test_recv_data2_ttl1); + + g_test_add_data_func("/lldp/parse-frames/0", &_test_recv_data0_frame0, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/1", &_test_recv_data1_frame0, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/2", &_test_recv_data2_frame0_ttl1, test_parse_frames); + g_test_add_data_func("/lldp/parse-frames/3", &_test_parse_frames_3, test_parse_frames); +} |