diff options
Diffstat (limited to 'src/devices/tests/test-lldp.c')
| -rw-r--r-- | src/devices/tests/test-lldp.c | 1296 |
1 files changed, 0 insertions, 1296 deletions
diff --git a/src/devices/tests/test-lldp.c b/src/devices/tests/test-lldp.c deleted file mode 100644 index 5c912b7d..00000000 --- a/src/devices/tests/test-lldp.c +++ /dev/null @@ -1,1296 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2015 Red Hat, Inc. - */ - -#include "nm-default.h" - -#include <fcntl.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 = {}; - - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - nm_utils_ifname_cpy(ifr.ifr_name, TEST_IFNAME); - g_assert(ioctl(fd, TUNSETIFF, &ifr) >= 0); - - /* Bring the interface up */ - s = socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0); - g_assert(s >= 0); - ifr.ifr_flags |= IFF_UP; - g_assert(ioctl(s, SIOCSIFFLAGS, &ifr) >= 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); -} |