Skip to content

Commit b0221bb

Browse files
mvduinyuwata
authored andcommitted
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.
1 parent a2e37d5 commit b0221bb

File tree

1 file changed

+18
-9
lines changed

1 file changed

+18
-9
lines changed

src/libsystemd-network/sd-lldp-tx.c

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ static size_t lldp_tx_calculate_maximum_packet_size(sd_lldp_tx *lldp_tx, const c
230230
2 + 1 + (SD_ID128_STRING_MAX - 1) +
231231
/* Port ID */
232232
2 + 1 + strlen_ptr(lldp_tx->ifname) +
233+
/* TTL */
234+
2 + 2 +
233235
/* Port description */
234236
2 + strlen_ptr(lldp_tx->port_description) +
235237
/* System name */
@@ -238,8 +240,6 @@ static size_t lldp_tx_calculate_maximum_packet_size(sd_lldp_tx *lldp_tx, const c
238240
2 + strlen_ptr(pretty_hostname) +
239241
/* MUD URL */
240242
2 + sizeof(SD_LLDP_OUI_IANA_MUD) + strlen_ptr(lldp_tx->mud_url) +
241-
/* TTL */
242-
2 + 2 +
243243
/* System Capabilities */
244244
2 + 4 +
245245
/* End */
@@ -369,6 +369,13 @@ static int lldp_tx_create_packet(sd_lldp_tx *lldp_tx, size_t *ret_packet_size, u
369369
memcpy(header->ether_shost, &lldp_tx->hwaddr, ETH_ALEN);
370370

371371
offset = sizeof(struct ether_header);
372+
373+
/* The three mandatory TLVs must appear first, in this specific order:
374+
* 1. Chassis ID
375+
* 2. Port ID
376+
* 3. Time To Live
377+
*/
378+
372379
r = packet_append_prefixed_string(packet, packet_size, &offset, SD_LLDP_TYPE_CHASSIS_ID,
373380
1, (const uint8_t[]) { SD_LLDP_CHASSIS_SUBTYPE_LOCALLY_ASSIGNED },
374381
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
381388
if (r < 0)
382389
return r;
383390

391+
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_TTL, 2);
392+
if (r < 0)
393+
return r;
394+
395+
unaligned_write_be16(packet + offset, LLDP_TX_TTL);
396+
offset += 2;
397+
398+
/* Optional TLVs follow, in no specific order: */
399+
384400
r = packet_append_string(packet, packet_size, &offset, SD_LLDP_TYPE_PORT_DESCRIPTION,
385401
lldp_tx->port_description);
386402
if (r < 0)
@@ -416,13 +432,6 @@ static int lldp_tx_create_packet(sd_lldp_tx *lldp_tx, size_t *ret_packet_size, u
416432
if (r < 0)
417433
return r;
418434

419-
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_TTL, 2);
420-
if (r < 0)
421-
return r;
422-
423-
unaligned_write_be16(packet + offset, LLDP_TX_TTL);
424-
offset += 2;
425-
426435
r = packet_append_tlv_header(packet, packet_size, &offset, SD_LLDP_TYPE_SYSTEM_CAPABILITIES, 4);
427436
if (r < 0)
428437
return r;

0 commit comments

Comments
 (0)