net/mac80211/mesh_plink.c

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

File Facts

System
Linux kernel
Corpus path
net/mac80211/mesh_plink.c
Extension
.c
Size
33904 bytes
Lines
1261
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 (!sta->sta.deflink.ht_cap.ht_supported) {
			mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
				       sta->sta.addr);
			non_ht_sta = true;
			break;
		}

		mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
		ht20_sta = true;
	}
	rcu_read_unlock();

	if (non_ht_sta)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
	else if (ht20_sta &&
		 sdata->vif.bss_conf.chanreq.oper.width > NL80211_CHAN_WIDTH_20)
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
	else
		ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;

	if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
		return 0;

	sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
	sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
	mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
	return BSS_CHANGED_HT;
}

static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
			       struct sta_info *sta,
			       enum ieee80211_self_protected_actioncode action,
			       u8 *da, u16 llid, u16 plid, u16 reason)
{
	int hdr_len = IEEE80211_MIN_ACTION_SIZE(self_prot);
	struct ieee80211_local *local = sdata->local;
	struct sk_buff *skb;
	struct ieee80211_tx_info *info;
	struct ieee80211_mgmt *mgmt;
	bool include_plid = false;
	u16 peering_proto = 0;
	u8 *pos, ie_len = 4;
	u8 ie_len_he_cap, ie_len_eht_cap;
	int err = -ENOMEM;

	ie_len_he_cap = ieee80211_ie_len_he_cap(sdata);
	ie_len_eht_cap = ieee80211_ie_len_eht_cap(sdata);
	skb = dev_alloc_skb(local->tx_headroom +
			    hdr_len +
			    2 + /* capability info */
			    2 + /* AID */
			    2 + 8 + /* supported rates */
			    2 + (IEEE80211_MAX_SUPP_RATES - 8) +
			    2 + sdata->u.mesh.mesh_id_len +
			    2 + sizeof(struct ieee80211_meshconf_ie) +
			    2 + sizeof(struct ieee80211_ht_cap) +
			    2 + sizeof(struct ieee80211_ht_operation) +
			    2 + sizeof(struct ieee80211_vht_cap) +
			    2 + sizeof(struct ieee80211_vht_operation) +
			    ie_len_he_cap +
			    2 + 1 + sizeof(struct ieee80211_he_operation) +
				    sizeof(struct ieee80211_he_6ghz_oper) +
			    2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
			    ie_len_eht_cap +
			    2 + 1 + offsetof(struct ieee80211_eht_operation, optional) +
				    offsetof(struct ieee80211_eht_operation_info, optional) +
			    2 + 8 + /* peering IE */
			    sdata->u.mesh.ie_len);
	if (!skb)
		return err;
	info = IEEE80211_SKB_CB(skb);
	skb_reserve(skb, local->tx_headroom);
	mgmt = skb_put_zero(skb, hdr_len);
	mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
					  IEEE80211_STYPE_ACTION);
	memcpy(mgmt->da, da, ETH_ALEN);
	memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
	memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
	mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
	mgmt->u.action.action_code = action;

	if (action != WLAN_SP_MESH_PEERING_CLOSE) {
		struct ieee80211_supported_band *sband;
		u32 basic_rates;

		sband = ieee80211_get_sband(sdata);
		if (!sband) {
			err = -EINVAL;
			goto free;
		}

Annotation

Implementation Notes