From f91cf35f5871ab66f4482a9242c415264314ca84 Mon Sep 17 00:00:00 2001 From: Aaron Conole Date: Tue, 8 Dec 2020 13:20:30 -0500 Subject: [PATCH] tx: when operating in rx-only mode don't send a port shutdown pdu Currently, lldpad correctly transmits a shutdown pdu with ttl = 0s when transitioning from rxtx or txonly to rxonly. However, when we shutdown lldpad it will transmit a shutdown pdu even if the port is configured to rxonly mode. For some implementations of LLDP this can create a confusing state and lead to issues in the network. Correct this by only transmitting a shutdown PDU when going from any transmit mode to a receive only mode, and don't transmit PDUs on shutdown if the port agent isn't configured to transmit. Reported-by: Matthew Whitehead Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1905210 Signed-off-by: Aaron Conole --- lldp/agent.c | 2 +- lldp/states.h | 2 +- lldp/tx.c | 15 +++++++++++++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/lldp/agent.c b/lldp/agent.c index aa4a8d1..14fcf71 100644 --- a/lldp/agent.c +++ b/lldp/agent.c @@ -200,7 +200,7 @@ void clean_lldp_agents(void) LLDPAD_DBG("Send shutdown frame on port %s\n", port->ifname); LIST_FOREACH(agent, &port->agent_head, entry) { - process_tx_shutdown_frame(port, agent); + process_tx_shutdown_frame(port, agent, false); } } else { LLDPAD_DBG("No shutdown frame is sent on port %s\n", diff --git a/lldp/states.h b/lldp/states.h index 7cf69b8..f7b8ee0 100644 --- a/lldp/states.h +++ b/lldp/states.h @@ -85,7 +85,7 @@ u8 txFrame(struct port *port, struct lldp_agent *); void run_tx_sm(struct port *, struct lldp_agent *); void process_tx_initialize_sm(struct port *); void process_tx_idle(struct lldp_agent *); -void process_tx_shutdown_frame(struct port *, struct lldp_agent *); +void process_tx_shutdown_frame(struct port *, struct lldp_agent *, bool); void process_tx_info_frame(struct port *, struct lldp_agent *); void update_tx_timers(struct lldp_agent *); void run_tx_timers_sm(struct port *, struct lldp_agent *); diff --git a/lldp/tx.c b/lldp/tx.c index 1b95208..9b36071 100644 --- a/lldp/tx.c +++ b/lldp/tx.c @@ -270,7 +270,7 @@ void run_tx_sm(struct port *port, struct lldp_agent *agent) process_tx_idle(agent); break; case TX_SHUTDOWN_FRAME: - process_tx_shutdown_frame(port, agent); + process_tx_shutdown_frame(port, agent, true); break; case TX_INFO_FRAME: process_tx_info_frame(port, agent); @@ -330,8 +330,19 @@ void process_tx_idle(UNUSED struct lldp_agent *agent) return; } -void process_tx_shutdown_frame(struct port *port, struct lldp_agent *agent) +/* we ignore 'state' value in the case that we have recently transitioned + * to the shutdown state (in the case of the 'tx' state change) to allow + * for transmitting the ttl==0 as required by the IEEE standard. */ +void process_tx_shutdown_frame(struct port *port, struct lldp_agent *agent, + bool ignoreState) { + if (agent->adminStatus != enabledRxTx && + agent->adminStatus != enabledTxOnly) { + if (!ignoreState) { + return; + } + } + if (agent->timers.txShutdownWhile == 0) { if (mibConstrShutdownLLDPDU(port, agent)) txFrame(port, agent); -- 2.33.0