net/bridge/br_stp.c

Source file repositories/reference/linux-study-clean/net/bridge/br_stp.c

File Facts

System
Linux kernel
Corpus path
net/bridge/br_stp.c
Extension
.c
Size
17310 bytes
Lines
725
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

switch (p->state) {
		case BR_STATE_BLOCKING:
			p->stp_xstats.transition_blk++;
			break;
		case BR_STATE_FORWARDING:
			p->stp_xstats.transition_fwd++;
			break;
		}
	}
}

u8 br_port_get_stp_state(const struct net_device *dev)
{
	struct net_bridge_port *p;

	ASSERT_RTNL();

	p = br_port_get_rtnl(dev);
	if (!p)
		return BR_STATE_DISABLED;

	return p->state;
}
EXPORT_SYMBOL_GPL(br_port_get_stp_state);

/* called under bridge lock */
struct net_bridge_port *br_get_port(struct net_bridge *br, u16 port_no)
{
	struct net_bridge_port *p;

	list_for_each_entry_rcu(p, &br->port_list, list,
				lockdep_is_held(&br->lock)) {
		if (p->port_no == port_no)
			return p;
	}

	return NULL;
}

/* called under bridge lock */
static int br_should_become_root_port(const struct net_bridge_port *p,
				      u16 root_port)
{
	u32 p_path_cost, rp_path_cost, p_designated_cost, rp_designated_cost;
	struct net_bridge_port *rp;
	struct net_bridge *br;
	int t;

	br = p->br;
	if (p->state == BR_STATE_DISABLED ||
	    br_is_designated_port(p))
		return 0;

	if (memcmp(&br->bridge_id, &p->designated_root, 8) <= 0)
		return 0;

	if (!root_port)
		return 1;

	rp = br_get_port(br, root_port);

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

	p_path_cost = READ_ONCE(p->path_cost);
	rp_path_cost = READ_ONCE(rp->path_cost);
	p_designated_cost = READ_ONCE(p->designated_cost);
	rp_designated_cost = READ_ONCE(rp->designated_cost);

	if (p_designated_cost + p_path_cost <
	    rp_designated_cost + rp_path_cost)
		return 1;
	else if (p_designated_cost + p_path_cost >
		 rp_designated_cost + rp_path_cost)
		return 0;

	t = memcmp(&p->designated_bridge, &rp->designated_bridge, 8);
	if (t < 0)
		return 1;
	else if (t > 0)
		return 0;

	if (p->designated_port < rp->designated_port)
		return 1;
	else if (p->designated_port > rp->designated_port)
		return 0;

Annotation

Implementation Notes