88 lines
3.2 KiB
Diff
88 lines
3.2 KiB
Diff
|
|
From f91cf35f5871ab66f4482a9242c415264314ca84 Mon Sep 17 00:00:00 2001
|
||
|
|
From: Aaron Conole <aconole@redhat.com>
|
||
|
|
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 <mwhitehe@redhat.com>
|
||
|
|
Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1905210
|
||
|
|
Signed-off-by: Aaron Conole <aconole@redhat.com>
|
||
|
|
---
|
||
|
|
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
|
||
|
|
|