net/mac80211/link.c

Source file repositories/reference/linux-study-clean/net/mac80211/link.c

File Facts

System
Linux kernel
Corpus path
net/mac80211/link.c
Extension
.c
Size
19088 bytes
Lines
694
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

struct link_container {
	struct ieee80211_link_data data;
	struct ieee80211_bss_conf conf;
};

static void ieee80211_tear_down_links(struct ieee80211_sub_if_data *sdata,
				      struct link_container **links, u16 mask)
{
	struct ieee80211_link_data *link;
	LIST_HEAD(keys);
	unsigned int link_id;

	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++) {
		if (!(mask & BIT(link_id)))
			continue;
		link = &links[link_id]->data;
		if (link_id == 0 && !link)
			link = &sdata->deflink;
		if (WARN_ON(!link))
			continue;
		ieee80211_remove_link_keys(link, &keys);
		ieee80211_link_debugfs_remove(link);
		ieee80211_link_stop(link);
	}

	synchronize_rcu();

	ieee80211_free_key_list(sdata->local, &keys);
}

static void ieee80211_free_links(struct ieee80211_sub_if_data *sdata,
				 struct link_container **links)
{
	unsigned int link_id;

	for (link_id = 0; link_id < IEEE80211_MLD_MAX_NUM_LINKS; link_id++)
		kfree(links[link_id]);
}

static int ieee80211_check_dup_link_addrs(struct ieee80211_sub_if_data *sdata)
{
	unsigned int i, j;

	for (i = 0; i < IEEE80211_MLD_MAX_NUM_LINKS; i++) {
		struct ieee80211_link_data *link1;

		link1 = sdata_dereference(sdata->link[i], sdata);
		if (!link1)
			continue;
		for (j = i + 1; j < IEEE80211_MLD_MAX_NUM_LINKS; j++) {
			struct ieee80211_link_data *link2;

			link2 = sdata_dereference(sdata->link[j], sdata);
			if (!link2)
				continue;

			if (ether_addr_equal(link1->conf->addr,
					     link2->conf->addr))
				return -EALREADY;
		}
	}

	return 0;
}

static void ieee80211_set_vif_links_bitmaps(struct ieee80211_sub_if_data *sdata,
					    u16 valid_links, u16 dormant_links)
{
	sdata->vif.valid_links = valid_links;
	sdata->vif.dormant_links = dormant_links;

	if (!valid_links ||
	    WARN((~valid_links & dormant_links) ||
		 !(valid_links & ~dormant_links),
		 "Invalid links: valid=0x%x, dormant=0x%x",
		 valid_links, dormant_links)) {
		sdata->vif.active_links = 0;
		sdata->vif.dormant_links = 0;
		return;
	}

	switch (sdata->vif.type) {
	case NL80211_IFTYPE_AP:
	case NL80211_IFTYPE_AP_VLAN:
		/* in an AP all links are always active */
		sdata->vif.active_links = valid_links;

		/* AP links are not expected to be disabled */
		WARN_ON(dormant_links);
		break;

Annotation

Implementation Notes