* Changes:
+ lldpcli can now display local interfaces with LLDP data sent on
each of them ("show interfaces").
+ + As Dot3 PD device, echo back allocated value from PSE device.
* Fix:
+ Don't remove interfaces when they are released from a bridge.
+ Don't use "expect stop" with Upstart. It's buggy.
}
}
+/* If PD device and PSE allocated power, echo back this change. If we have
+ * several LLDP neighbors, we use the latest updated. */
+static void
+lldpd_dot3_power_pd_pse(struct lldpd_hardware *hardware)
+{
+#ifdef ENABLE_DOT3
+ struct lldpd_port *port, *selected_port = NULL;
+ /* Are we a PD device? */
+ if (hardware->h_lport.p_power.devicetype != LLDP_DOT3_POWER_PD)
+ return;
+ TAILQ_FOREACH(port, &hardware->h_rports, p_entries) {
+ if (port->p_hidden_in)
+ continue;
+ if (port->p_protocol != LLDPD_MODE_LLDP)
+ continue;
+ if (port->p_power.devicetype != LLDP_DOT3_POWER_PSE)
+ continue;
+ if (!selected_port || port->p_lastupdate > selected_port->p_lastupdate)
+ selected_port = port;
+ }
+ if (selected_port->p_power.allocated != hardware->h_lport.p_power.allocated) {
+ log_info("receive", "for %s, PSE told us allocated is now %d instead of %d",
+ hardware->h_ifname,
+ selected_port->p_power.allocated,
+ hardware->h_lport.p_power.allocated);
+ hardware->h_lport.p_power.allocated = selected_port->p_power.allocated;
+ levent_schedule_pdu(hardware);
+ }
+#endif
+}
+
void
lldpd_recv(struct lldpd *cfg, struct lldpd_hardware *hardware, int fd)
{
TRACE(LLDPD_FRAME_RECEIVED(hardware->h_ifname, buffer, (size_t)n));
lldpd_decode(cfg, buffer, n, hardware);
lldpd_hide_all(cfg); /* Immediatly hide */
+ lldpd_dot3_power_pd_pse(hardware);
lldpd_count_neighbors(cfg);
free(buffer);
}
import pytest
-import pyroute2
import shlex
import time
for k, v in out.items()
if k.startswith(pfx)}
assert out == expected
+
+ def test_autoneg_power(self, links, lldpd, lldpcli, namespaces):
+ links(namespaces(1), namespaces(2))
+ with namespaces(1):
+ lldpd()
+ with namespaces(2):
+ lldpd()
+ result = lldpcli(
+ *shlex.split("configure dot3 power pd "
+ "supported enabled paircontrol "
+ "powerpairs spare "
+ "class class-3 "
+ "type 1 source both priority low "
+ "requested 20000 allocated 5000"))
+ assert result.returncode == 0
+ time.sleep(2)
+ with namespaces(1):
+ # Did we receive the request?
+ out = lldpcli("-f", "keyvalue", "show", "neighbors", "details")
+ assert out['lldp.eth0.port.power.requested'] == '20000'
+ assert out['lldp.eth0.port.power.allocated'] == '5000'
+ # Send an answer we agree to give almost that (this part
+ # cannot be automated, lldpd cannot take this decision).
+ result = lldpcli(
+ *shlex.split("configure dot3 power pse "
+ "supported enabled paircontrol powerpairs "
+ "spare class class-3 "
+ "type 1 source primary priority high "
+ "requested 20000 allocated 19000"))
+ assert result.returncode == 0
+ time.sleep(2)
+ with namespaces(2):
+ # Did we receive that?
+ out = lldpcli("-f", "keyvalue", "show", "neighbors", "details")
+ assert out['lldp.eth1.port.power.requested'] == '20000'
+ assert out['lldp.eth1.port.power.allocated'] == '19000'
+ with namespaces(1):
+ # Did we get an echo back? This part is handled
+ # automatically by lldpd: we confirm we received the
+ # answer "immediately".
+ out = lldpcli("-f", "keyvalue", "show", "neighbors", "details")
+ assert out['lldp.eth0.port.power.requested'] == '20000'
+ assert out['lldp.eth0.port.power.allocated'] == '19000'