]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
daemon/protocols: fix some 802.3bt stuff
authorVincent Bernat <vincent@bernat.ch>
Sun, 15 Oct 2023 17:40:37 +0000 (19:40 +0200)
committerVincent Bernat <vincent@bernat.ch>
Sun, 15 Oct 2023 17:41:23 +0000 (19:41 +0200)
And add some tests.

NEWS
src/daemon/protocols/lldp.c
src/lib/atoms/dot3.c
tests/integration/test_dot3.py

diff --git a/NEWS b/NEWS
index ea6afcae1dc637257191eb97a3231bbea0859f43..ceb9bee5433c80abca3e58e56bbf8b49b0ff86f1 100644 (file)
--- 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.
 
index 23211f8e44f2c9885749eb60819f4cba4edc4eeb..3a93b96d615897cc3162dc6b3fdd5e6aecb3508b 100644 (file)
@@ -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,
index b6347b7343d45cb92344d64303b404b59e94c3e2..ffe497dd135109caf69145b5789f050126c33825 100644 (file)
@@ -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 },
        },
 };
 
index abeb86efa5458167bd90eebb2ab44d33df8f3612..35d036e71ab4315ec1d0bcff358557165d402372 100644 (file)
@@ -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):