net/dsa/switch.c

Source file repositories/reference/linux-study-clean/net/dsa/switch.c

File Facts

System
Linux kernel
Corpus path
net/dsa/switch.c
Extension
.c
Size
26792 bytes
Lines
1135
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source 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

if (dsa_port_mtu_match(dp, info)) {
			ret = ds->ops->port_change_mtu(ds, dp->index,
						       info->mtu);
			if (ret)
				return ret;
		}
	}

	return 0;
}

static int dsa_switch_bridge_join(struct dsa_switch *ds,
				  struct dsa_notifier_bridge_info *info)
{
	int err;

	if (info->dp->ds == ds) {
		if (!ds->ops->port_bridge_join)
			return -EOPNOTSUPP;

		err = ds->ops->port_bridge_join(ds, info->dp->index,
						info->bridge,
						&info->tx_fwd_offload,
						info->extack);
		if (err)
			return err;
	}

	if (info->dp->ds != ds && ds->ops->crosschip_bridge_join) {
		err = ds->ops->crosschip_bridge_join(ds,
						     info->dp->ds->dst->index,
						     info->dp->ds->index,
						     info->dp->index,
						     info->bridge,
						     info->extack);
		if (err)
			return err;
	}

	return 0;
}

static int dsa_switch_bridge_leave(struct dsa_switch *ds,
				   struct dsa_notifier_bridge_info *info)
{
	if (info->dp->ds == ds && ds->ops->port_bridge_leave)
		ds->ops->port_bridge_leave(ds, info->dp->index, info->bridge);

	if (info->dp->ds != ds && ds->ops->crosschip_bridge_leave)
		ds->ops->crosschip_bridge_leave(ds, info->dp->ds->dst->index,
						info->dp->ds->index,
						info->dp->index,
						info->bridge);

	return 0;
}

/* Matches for all upstream-facing ports (the CPU port and all upstream-facing
 * DSA links) that sit between the targeted port on which the notifier was
 * emitted and its dedicated CPU port.
 */
static bool dsa_port_host_address_match(struct dsa_port *dp,
					const struct dsa_port *targeted_dp)
{
	struct dsa_port *cpu_dp = targeted_dp->cpu_dp;

	if (dsa_switch_is_upstream_of(dp->ds, targeted_dp->ds))
		return dp->index == dsa_towards_port(dp->ds, cpu_dp->ds->index,
						     cpu_dp->index);

	return false;
}

static struct dsa_mac_addr *dsa_mac_addr_find(struct list_head *addr_list,
					      const unsigned char *addr, u16 vid,
					      struct dsa_db db)
{
	struct dsa_mac_addr *a;

	list_for_each_entry(a, addr_list, list)
		if (ether_addr_equal(a->addr, addr) && a->vid == vid &&
		    dsa_db_equal(&a->db, &db))
			return a;

	return NULL;
}

static int dsa_port_do_mdb_add(struct dsa_port *dp,
			       const struct switchdev_obj_port_mdb *mdb,
			       struct dsa_db db)

Annotation

Implementation Notes