net/bridge/br_if.c

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

File Facts

System
Linux kernel
Corpus path
net/bridge/br_if.c
Extension
.c
Size
17756 bytes
Lines
767
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 (ecmd.base.speed) {
		case SPEED_10000:
			return 2;
		case SPEED_5000:
			return 3;
		case SPEED_2500:
			return 4;
		case SPEED_1000:
			return 5;
		case SPEED_100:
			return 19;
		case SPEED_10:
			return 100;
		case SPEED_UNKNOWN:
			return 100;
		default:
			if (ecmd.base.speed > SPEED_10000)
				return 1;
		}
	}

	/* Old silly heuristics based on name */
	if (!strncmp(dev->name, "lec", 3))
		return 7;

	if (!strncmp(dev->name, "plip", 4))
		return 2500;

	return 100;	/* assume old 10Mbps */
}


/* Check for port carrier transitions. */
void br_port_carrier_check(struct net_bridge_port *p, bool *notified)
{
	struct net_device *dev = p->dev;
	struct net_bridge *br = p->br;

	if (!test_bit(BR_ADMIN_COST_BIT, &p->flags) &&
	    netif_running(dev) && netif_oper_up(dev))
		WRITE_ONCE(p->path_cost, port_cost(dev));

	*notified = false;
	if (!netif_running(br->dev))
		return;

	spin_lock_bh(&br->lock);
	if (netif_running(dev) && netif_oper_up(dev)) {
		if (p->state == BR_STATE_DISABLED) {
			br_stp_enable_port(p);
			*notified = true;
		}
	} else {
		if (p->state != BR_STATE_DISABLED) {
			br_stp_disable_port(p);
			*notified = true;
		}
	}
	spin_unlock_bh(&br->lock);
}

static void br_port_set_promisc(struct net_bridge_port *p)
{
	int err = 0;

	if (br_promisc_port(p))
		return;

	err = dev_set_promiscuity(p->dev, 1);
	if (err)
		return;

	br_fdb_unsync_static(p->br, p);
	set_bit(BR_PROMISC_BIT, &p->flags);
}

static void br_port_clear_promisc(struct net_bridge_port *p)
{
	int err;

	/* Check if the port is already non-promisc or if it doesn't
	 * support UNICAST filtering.  Without unicast filtering support
	 * we'll end up re-enabling promisc mode anyway, so just check for
	 * it here.
	 */
	if (!br_promisc_port(p) || !(p->dev->priv_flags & IFF_UNICAST_FLT))
		return;

	/* Since we'll be clearing the promisc mode, program the port
	 * first so that we don't have interruption in traffic.

Annotation

Implementation Notes