Linux Kernel STP Bridging Patch
Description of Bug
This function is called to determine whether a BPDU received on a particular
port should be ignored or processed.

/* called under bridge lock */
static int br_supersedes_port_info(struct net_bridge_port *p, struct
br_config_bpdu *bpdu)
{
	int t;

	t = memcmp(&bpdu->root, &p->designated_root, 8);
	if (t < 0)
		return 1;
	else if (t > 0)
		return 0;

	if (bpdu->root_path_cost < p->designated_cost)
		return 1;

	// THIS ELSE IF IS WRONG!
	else if (bpdu->root_path_cost > p->designated_cost)
		return 0;

	//...
	//...
	//...
}


in br_stp.c at line 271
this "else if" should not be here at all.  it is saying:

if the BPDU's root path cost is greater than the designated cost on
the port on which the bpdu arrived, then ignore the BPDU completely.
this means that if the root path cost of a parent bridge in the tree
goes up, the child will start to ignore the BPDUs and the message age
timer will eventually expire.  the following setup has been tested to
illustrate the issue. letters represent bridges, R is the root, and
path costs as numbers:

time = 0:   [R]--------100----------[a]-----------5000--------[b]
time = 1:   [R]--------101----------[a]-----------5000--------[b]

at t=0, the designated cost on [b]'s root port is 100, and the BPDUs received
on this port contain a root path cost of 100, all is well.

at t=1, the designated cost on [b]'s root port is 100 still.  the BPDU's
received on this port contain a root path cost of 101 now.  the "else if" at
br_stp.c:271  evaluates to true, so the BPDU is ignored.
----------------------------------------------------------------------
The patch
(download)
Applicable Standards
802.1D-1998
802.1D-2004