From: Vincent Bernat Date: Sun, 15 Oct 2023 17:40:37 +0000 (+0200) Subject: daemon/protocols: fix some 802.3bt stuff X-Git-Tag: 1.0.18~32 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e750474a7766907a1c7a6c10144b207d1ec1ed1;p=thirdparty%2Flldpd.git daemon/protocols: fix some 802.3bt stuff And add some tests. --- diff --git a/NEWS b/NEWS index ea6afcae..ceb9bee5 100644 --- a/NEWS +++ b/NEWS @@ -1,4 +1,6 @@ lldpd (1.0.18) + * Changes: + + Add support for 802.3bt in lldpcli. * Fix: + Fix memory leaks in EDP/FDP decoding when receiving some TLVs twice. diff --git a/src/daemon/protocols/lldp.c b/src/daemon/protocols/lldp.c index 23211f8e..3a93b96d 100644 --- a/src/daemon/protocols/lldp.c +++ b/src/daemon/protocols/lldp.c @@ -278,9 +278,7 @@ _lldp_send(struct lldpd *global, struct lldpd_hardware *hardware, u_int8_t c_id_ } /* Power */ if (port->p_power.devicetype) { - if (!((port->p_power.type_ext != LLDP_DOT3_POWER_8023BT_OFF ? - (tlv = pos, POKE_UINT16((LLDP_TLV_ORG << 9) | (0x1d))) : - POKE_START_LLDP_TLV(LLDP_TLV_ORG)) && + if (!((POKE_START_LLDP_TLV(LLDP_TLV_ORG)) && POKE_BYTES(dot3, sizeof(dot3)) && POKE_UINT8(LLDP_TLV_DOT3_POWER) && POKE_UINT8(((((2 - port->p_power.devicetype) % (1 << 1)) << 0) | @@ -291,7 +289,8 @@ _lldp_send(struct lldpd *global, struct lldpd_hardware *hardware, u_int8_t c_id_ POKE_UINT8(port->p_power.class))) goto toobig; /* 802.3at */ - if (port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF) { + if (port->p_power.powertype != LLDP_DOT3_POWER_8023AT_OFF || + port->p_power.type_ext != LLDP_DOT3_POWER_8023BT_OFF) { if (!(POKE_UINT8(((((port->p_power.powertype == LLDP_DOT3_POWER_8023AT_TYPE1) ? 1 : @@ -308,6 +307,7 @@ _lldp_send(struct lldpd *global, struct lldpd_hardware *hardware, u_int8_t c_id_ POKE_UINT16(port->p_power.allocated))) goto toobig; } + /* 802.3bt */ if (port->p_power.type_ext != LLDP_DOT3_POWER_8023BT_OFF) { if (!(POKE_UINT16(port->p_power.requested_a) && POKE_UINT16(port->p_power.requested_b) && @@ -347,13 +347,14 @@ _lldp_send(struct lldpd *global, struct lldpd_hardware *hardware, u_int8_t c_id_ /* LLDP-MED inventory */ # define LLDP_INVENTORY(value, subtype) \ - if (value) { \ - if (!(POKE_START_LLDP_TLV(LLDP_TLV_ORG) && POKE_BYTES(med, sizeof(med)) && \ - POKE_UINT8(subtype) && \ - POKE_BYTES(value, (strlen(value) > 32) ? 32 : strlen(value)) && \ - POKE_END_LLDP_TLV)) \ - goto toobig; \ - } + if (value) { \ + if (!(POKE_START_LLDP_TLV(LLDP_TLV_ORG) && \ + POKE_BYTES(med, sizeof(med)) && POKE_UINT8(subtype) && \ + POKE_BYTES(value, \ + (strlen(value) > 32) ? 32 : strlen(value)) && \ + POKE_END_LLDP_TLV)) \ + goto toobig; \ + } if (port->p_med_cap_enabled & LLDP_MED_CAP_IV) { LLDP_INVENTORY(chassis->c_med_hw, LLDP_TLV_MED_IV_HW); @@ -575,20 +576,22 @@ lldp_send(struct lldpd *global, struct lldpd_hardware *hardware) return 0; } -#define CHECK_TLV_SIZE(x, name) \ - do { \ - if (tlv_size < (x)) { \ - log_warnx("lldp", name " TLV too short received on %s", hardware->h_ifname); \ - goto malformed; \ - } \ - } while (0) -#define CHECK_TLV_MAX_SIZE(x, name) \ - do { \ - if (tlv_size > (x)) { \ - log_warnx("lldp", name " TLV too large received on %s", hardware->h_ifname); \ - goto malformed; \ - } \ - } while (0) +#define CHECK_TLV_SIZE(x, name) \ + do { \ + if (tlv_size < (x)) { \ + log_warnx("lldp", name " TLV too short received on %s", \ + hardware->h_ifname); \ + goto malformed; \ + } \ + } while (0) +#define CHECK_TLV_MAX_SIZE(x, name) \ + do { \ + if (tlv_size > (x)) { \ + log_warnx("lldp", name " TLV too large received on %s", \ + hardware->h_ifname); \ + goto malformed; \ + } \ + } while (0) int lldp_decode(struct lldpd *cfg, char *frame, int s, struct lldpd_hardware *hardware, diff --git a/src/lib/atoms/dot3.c b/src/lib/atoms/dot3.c index b6347b73..ffe497dd 100644 --- a/src/lib/atoms/dot3.c +++ b/src/lib/atoms/dot3.c @@ -68,86 +68,93 @@ static struct atom_map port_dot3_power_pd_4pid_map = { .map = { { 0, "PD does not support powering both modes" }, { 1, "PD supports powering both modes" }, + { 0, NULL}, }, }; static struct atom_map port_dot3_power_pse_status_map = { .key = lldpctl_k_dot3_power_pse_status, .map = { - { 0, "Unknown" }, + { 0, "unknown" }, { 1, "2-pair powering" }, { 2, "4-pair powering dual-signature PD" }, { 3, "4-pair powering single-signature PD" }, + { 0, NULL }, }, }; static struct atom_map port_dot3_power_pd_status_map = { .key = lldpctl_k_dot3_power_pd_status, .map = { - { 0, "Unknown" }, + { 0, "unknown" }, { 1, "2-pair powered PD" }, { 2, "4-pair powered dual-signature PD" }, { 3, "4-pair powered single-signature PD" }, + { 0, NULL }, }, }; static struct atom_map port_dot3_power_pse_pairs_ext_map = { .key = lldpctl_k_dot3_power_pse_pairs_ext, .map = { - { 0, "Unknown" }, - { 1, "Alternative A" }, - { 2, "Alternative B" }, - { 3, "Both alternatives" }, + { 0, "unknown" }, + { 1, "alternative A" }, + { 2, "alternative B" }, + { 3, "both alternatives" }, + { 0, NULL }, }, }; static struct atom_map port_dot3_power_class_a_map = { .key = lldpctl_k_dot3_power_class_a, .map = { - { 0, "Unknown" }, - { 1, "Class 1" }, - { 2, "Class 2" }, - { 3, "Class 3" }, - { 4, "Class 4" }, - { 5, "Class 5" }, - { 6, "Unknown" }, - { 7, "Single-signature PD or 2-pair only PSE" }, + { 0, "unknown" }, + { 1, "class 1" }, + { 2, "class 2" }, + { 3, "class 3" }, + { 4, "class 4" }, + { 5, "class 5" }, + { 6, "unknown" }, + { 7, "single-signature PD or 2-pair only PSE" }, + { 0, NULL }, }, }; static struct atom_map port_dot3_power_class_b_map = { .key = lldpctl_k_dot3_power_class_b, .map = { - { 0, "Unknown" }, - { 1, "Class 1" }, - { 2, "Class 2" }, - { 3, "Class 3" }, - { 4, "Class 4" }, - { 5, "Class 5" }, - { 6, "Unknown" }, - { 7, "Single-signature PD or 2-pair only PSE" }, + { 0, "unknown" }, + { 1, "class 1" }, + { 2, "class 2" }, + { 3, "class 3" }, + { 4, "class 4" }, + { 5, "class 5" }, + { 6, "unknown" }, + { 7, "single-signature PD or 2-pair only PSE" }, + { 0, NULL }, }, }; static struct atom_map port_dot3_power_class_ext_map = { .key = lldpctl_k_dot3_power_class_ext, .map = { - { 0, "Unknown" }, - { 1, "Class 1" }, - { 2, "Class 2" }, - { 3, "Class 3" }, - { 4, "Class 4" }, - { 5, "Class 5" }, - { 6, "Class 6" }, - { 7, "Class 7" }, - { 8, "Class 8" }, - { 9, "Unknown" }, - { 10, "Unknown" }, - { 11, "Unknown" }, - { 12, "Unknown" }, - { 13, "Unknown" }, - { 14, "Unknown" }, - { 15, "Dual-signature PD" }, + { 0, "unknown" }, + { 1, "class 1" }, + { 2, "class 2" }, + { 3, "class 3" }, + { 4, "class 4" }, + { 5, "class 5" }, + { 6, "class 6" }, + { 7, "class 7" }, + { 8, "class 8" }, + { 9, "unknown" }, + { 10, "unknown" }, + { 11, "unknown" }, + { 12, "unknown" }, + { 13, "unknown" }, + { 14, "unknown" }, + { 15, "dual-signature PD" }, + { 0, NULL }, }, }; @@ -155,14 +162,15 @@ static struct atom_map port_dot3_power_type_ext_map = { .key = lldpctl_k_dot3_power_type_ext, .map = { { LLDP_DOT3_POWER_8023BT_OFF, "802.3bt off" }, - { 1, "Type 3 PSE" }, - { 2, "Type 4 PSE" }, - { 3, "Type 3 single-signature PD" }, - { 4, "Type 3 dual-signature PD" }, - { 5, "Type 4 single-signature PD" }, - { 6, "Type 4 dual-signature PD" }, - { 7, "Unknown" }, - { 8, "Unknown" }, + { 1, "type 3 PSE" }, + { 2, "type 4 PSE" }, + { 3, "type 3 single-signature PD" }, + { 4, "type 3 dual-signature PD" }, + { 5, "type 4 single-signature PD" }, + { 6, "type 4 dual-signature PD" }, + { 7, "unknown" }, + { 8, "unknown" }, + { 0, NULL }, }, }; @@ -173,6 +181,7 @@ static struct atom_map port_dot3_power_pd_load_map = { "electrically isolated" }, { 1, "PD is dual-signature and power is electrically " "isolated" }, + { 0, NULL }, }, }; diff --git a/tests/integration/test_dot3.py b/tests/integration/test_dot3.py index abeb86ef..35d036e7 100644 --- a/tests/integration/test_dot3.py +++ b/tests/integration/test_dot3.py @@ -49,6 +49,41 @@ class TestLldpDot3(object): "allocated": "15000", }, ), + ( + "pd type-ext 4 powerpairs signal class-a 4 class-b 3 class-ext 5 " + "pd-status 2 pd-4pid 0 " + "requested-a 1000 allocated-a 900 " + "requested-b 2000 allocated-b 500 " + "pd-load 400", + { + "supported": "no", + "enabled": "no", + "paircontrol": "no", + "device-type": "PD", + "pairs": "signal", + "power-type": "2", + # 802.3at is not configured + "class": "unknown", + "source": "unknown", + "priority": "unknown", + "requested": "0", + "allocated": "0", + # 802.3bt is configured + "requested-a": "1000", + "allocated-a": "900", + "requested-b": "2000", + "allocated-b": "500", + "power-pairs-ext": "unknown", + "pse-power-status": "unknown", + "pd-power-status": "4-pair powered dual-signature PD", + "power-class-ext-a": "class 4", + "power-class-ext-b": "class 3", + "power-class-ext": "class 5", + "power-type-ext": "unknown", + "pd-load": "???", + "max-power": "0", + }, + ), ], ) def test_power(self, lldpd1, lldpd, lldpcli, namespaces, command, expected):