Skip to content

Commit

Permalink
lldp: Fix for OVS crashes when a LLDP-enabled port is deleted
Browse files Browse the repository at this point in the history
Issue:
When LLDP is enabled on a port, a structure to hold LLDP related state
is created and that structure has a reference to the port. The ofproto
monitor thread accesses the LLDP structure to periodically send packets
over the associated port. When the port is deleted, the LLDP structure
is not cleaned up and it continues to refer to the deleted port.

When the monitor thread attempts to access the deleted port OVS crashes.
Crash can happen with bridge delete and bond delete also.

Fix:
Remove all references to the LLDP structure and free it when
the port is deleted.

Signed-off-by: Surya Rudra <rudrasurya.r@altencalsoftlabs.com>
Signed-off-by: Ben Pfaff <blp@ovn.org>
  • Loading branch information
Surya Rudra authored and blp committed Oct 24, 2019
1 parent c685776 commit 637fa40
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
10 changes: 5 additions & 5 deletions ofproto/ofproto-dpif.c
Expand Up @@ -2239,24 +2239,24 @@ set_lldp(struct ofport *ofport_,
const struct smap *cfg)
{
struct ofport_dpif *ofport = ofport_dpif_cast(ofport_);
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofport->up.ofproto);
int error = 0;

if (cfg) {
if (!ofport->lldp) {
struct ofproto_dpif *ofproto;

ofproto = ofproto_dpif_cast(ofport->up.ofproto);
ofproto->backer->need_revalidate = REV_RECONFIGURE;
ofport->lldp = lldp_create(ofport->up.netdev, ofport_->mtu, cfg);
}

if (!lldp_configure(ofport->lldp, cfg)) {
lldp_unref(ofport->lldp);
ofport->lldp = NULL;
error = EINVAL;
}
}
if (error) {
} else if (ofport->lldp) {
lldp_unref(ofport->lldp);
ofport->lldp = NULL;
ofproto->backer->need_revalidate = REV_RECONFIGURE;
}

ofproto_dpif_monitor_port_update(ofport,
Expand Down
3 changes: 3 additions & 0 deletions ofproto/ofproto.c
Expand Up @@ -2492,6 +2492,9 @@ ofproto_port_unregister(struct ofproto *ofproto, ofp_port_t ofp_port)
{
struct ofport *port = ofproto_get_port(ofproto, ofp_port);
if (port) {
if (port->ofproto->ofproto_class->set_lldp) {
port->ofproto->ofproto_class->set_lldp(port, NULL);
}
if (port->ofproto->ofproto_class->set_stp_port) {
port->ofproto->ofproto_class->set_stp_port(port, NULL);
}
Expand Down

0 comments on commit 637fa40

Please sign in to comment.