net/wireless/mesh.c

Source file repositories/reference/linux-study-clean/net/wireless/mesh.c

File Facts

System
Linux kernel
Corpus path
net/wireless/mesh.c
Extension
.c
Size
8054 bytes
Lines
290
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 (setup->chandef.chan->band == NL80211_BAND_2GHZ) {
			int i;

			/*
			 * Older versions selected the mandatory rates for
			 * 2.4 GHz as well, but were broken in that only
			 * 1 Mbps was regarded as a mandatory rate. Keep
			 * using just 1 Mbps as the default basic rate for
			 * mesh to be interoperable with older versions.
			 */
			for (i = 0; i < sband->n_bitrates; i++) {
				if (sband->bitrates[i].bitrate == 10) {
					setup->basic_rates = BIT(i);
					break;
				}
			}
		} else {
			setup->basic_rates = ieee80211_mandatory_rates(sband);
		}
	}

	err = cfg80211_chandef_dfs_required(&rdev->wiphy,
					    &setup->chandef,
					    NL80211_IFTYPE_MESH_POINT);
	if (err < 0)
		return err;
	if (err > 0 && !setup->userspace_handles_dfs)
		return -EINVAL;

	if (!cfg80211_reg_can_beacon(&rdev->wiphy, &setup->chandef,
				     NL80211_IFTYPE_MESH_POINT))
		return -EINVAL;

	err = rdev_join_mesh(rdev, dev, conf, setup);
	if (!err) {
		memcpy(wdev->u.mesh.id, setup->mesh_id, setup->mesh_id_len);
		wdev->u.mesh.id_len = setup->mesh_id_len;
		wdev->u.mesh.chandef = setup->chandef;
		wdev->u.mesh.beacon_interval = setup->beacon_interval;
	}

	return err;
}

int cfg80211_set_mesh_channel(struct cfg80211_registered_device *rdev,
			      struct wireless_dev *wdev,
			      struct cfg80211_chan_def *chandef)
{
	int err;

	/*
	 * Workaround for libertas (only!), it puts the interface
	 * into mesh mode but doesn't implement join_mesh. Instead,
	 * it is configured via sysfs and then joins the mesh when
	 * you set the channel. Note that the libertas mesh isn't
	 * compatible with 802.11 mesh.
	 */
	if (rdev->ops->libertas_set_mesh_channel) {
		if (chandef->width != NL80211_CHAN_WIDTH_20_NOHT)
			return -EINVAL;

		if (!netif_running(wdev->netdev))
			return -ENETDOWN;

		err = rdev_libertas_set_mesh_channel(rdev, wdev->netdev,
						     chandef->chan);
		if (!err)
			wdev->u.mesh.chandef = *chandef;

		return err;
	}

	if (wdev->u.mesh.id_len)
		return -EBUSY;

	wdev->u.mesh.preset_chandef = *chandef;
	return 0;
}

int cfg80211_leave_mesh(struct cfg80211_registered_device *rdev,
			struct net_device *dev)
{
	struct wireless_dev *wdev = dev->ieee80211_ptr;
	int err;

	lockdep_assert_wiphy(wdev->wiphy);

	if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_MESH_POINT)
		return -EOPNOTSUPP;

Annotation

Implementation Notes