1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-22 13:33:56 +03:00

Fix placement of TTL TLV in LLDP transmit

The LLDP spec (IEEE 802.1AB) requires the three mandatory TLVs (Chassis
ID, Port ID, and TTL) to be the first three TLVs in the packet, in that
specific order, whereas systemd put the TTL near the end of the packet.

This violation caused the ethernet switch in our office to discard these
packets as malformed, and Wireshark's packet parser also chokes on them.

(cherry picked from commit b0221bb6a4)
This commit is contained in:
Matthijs van Duin 2022-05-04 15:18:55 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent 71d2356edf
commit 0aaceca2d0

View File

@ -230,6 +230,8 @@ static size_t lldp_tx_calculate_maximum_packet_size(sd_lldp_tx *lldp_tx, const c
2 + 1 + (SD_ID128_STRING_MAX - 1) + 2 + 1 + (SD_ID128_STRING_MAX - 1) +
/* Port ID */ /* Port ID */
2 + 1 + strlen_ptr(lldp_tx->ifname) + 2 + 1 + strlen_ptr(lldp_tx->ifname) +
/* TTL */
2 + 2 +
/* Port description */ /* Port description */
2 + strlen_ptr(lldp_tx->port_description) + 2 + strlen_ptr(lldp_tx->port_description) +
/* System name */ /* System name */
@ -238,8 +240,6 @@ static size_t lldp_tx_calculate_maximum_packet_size(sd_lldp_tx *lldp_tx, const c
2 + strlen_ptr(pretty_hostname) + 2 + strlen_ptr(pretty_hostname) +
/* MUD URL */ /* MUD URL */
2 + sizeof(SD_LLDP_OUI_IANA_MUD) + strlen_ptr(lldp_tx->mud_url) + 2 + sizeof(SD_LLDP_OUI_IANA_MUD) + strlen_ptr(lldp_tx->mud_url) +
/* TTL */
2 + 2 +
/* System Capabilities */ /* System Capabilities */
2 + 4 + 2 + 4 +
/* End */ /* End */
@ -369,6 +369,13 @@ static int lldp_tx_create_packet(sd_lldp_tx *lldp_tx, size_t *ret_packet_size, u
memcpy(header->ether_shost, &lldp_tx->hwaddr, ETH_ALEN); memcpy(header->ether_shost, &lldp_tx->hwaddr, ETH_ALEN);
offset = sizeof(struct ether_header); offset = sizeof(struct ether_header);
/* The three mandatory TLVs must appear first, in this specific order:
* 1. Chassis ID
* 2. Port ID
* 3. Time To Live
*/
r = packet_append_prefixed_string(packet, packet_size, &offset, SD_LLDP_TYPE_CHASSIS_ID, r = packet_append_prefixed_string(packet, packet_size, &offset, SD_LLDP_TYPE_CHASSIS_ID,
1, (const uint8_t[]) { SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED }, 1, (const uint8_t[]) { SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED },
SD_ID128_TO_STRING(machine_id)); SD_ID128_TO_STRING(machine_id));
@ -381,6 +388,15 @@ static int lldp_tx_create_packet(sd_lldp_tx *lldp_tx, size_t *ret_packet_size, u
if (r < 0) if (r < 0)
return r; return r;
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_TTL, 2);
if (r < 0)
return r;
unaligned_write_be16(packet + offset, LLDP_TX_TTL);
offset += 2;
/* Optional TLVs follow, in no specific order: */
r = packet_append_string(packet, packet_size, &offset, SD_LLDP_TYPE_PORT_DESCRIPTION, r = packet_append_string(packet, packet_size, &offset, SD_LLDP_TYPE_PORT_DESCRIPTION,
lldp_tx->port_description); lldp_tx->port_description);
if (r < 0) if (r < 0)
@ -416,13 +432,6 @@ static int lldp_tx_create_packet(sd_lldp_tx *lldp_tx, size_t *ret_packet_size, u
if (r < 0) if (r < 0)
return r; return r;
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_TTL, 2);
if (r < 0)
return r;
unaligned_write_be16(packet + offset, LLDP_TX_TTL);
offset += 2;
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4); r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
if (r < 0) if (r < 0)
return r; return r;