svn commit: r195618 - in head: sbin/ifconfig share/man/man4 sys/amd64/conf sys/conf sys/dev/ath sys/dev/mwl sys/dev/ral sys/i386/conf sys/net sys/net80211 sys/pc98/conf sys/sparc64/conf tools/tools...

Rui Paulo rpaulo at FreeBSD.org
Sat Jul 11 15:02:47 UTC 2009


Author: rpaulo
Date: Sat Jul 11 15:02:45 2009
New Revision: 195618
URL: http://svn.freebsd.org/changeset/base/195618

Log:
  Implementation of the upcoming Wireless Mesh standard, 802.11s, on the
  net80211 wireless stack. This work is based on the March 2009 D3.0 draft
  standard. This standard is expected to become final next year.
  This includes two main net80211 modules, ieee80211_mesh.c
  which deals with peer link management, link metric calculation,
  routing table control and mesh configuration and ieee80211_hwmp.c
  which deals with the actually routing process on the mesh network.
  HWMP is the mandatory routing protocol on by the mesh standard, but
  others, such as RA-OLSR, can be implemented.
  
  Authentication and encryption are not implemented.
  
  There are several scripts under tools/tools/net80211/scripts that can be
  used to test different mesh network topologies and they also teach you
  how to setup a mesh vap (for the impatient: ifconfig wlan0 create
  wlandev ... wlanmode mesh).
  
  A new build option is available: IEEE80211_SUPPORT_MESH and it's enabled
  by default on GENERIC kernels for i386, amd64, sparc64 and pc98.
  
  Drivers that support mesh networks right now are: ath, ral and mwl.
  
  More information at: http://wiki.freebsd.org/WifiMesh
  
  Please note that this work is experimental. Also, please note that
  bridging a mesh vap with another network interface is not yet supported.
  
  Many thanks to the FreeBSD Foundation for sponsoring this project and to
  Sam Leffler for his support.
  Also, I would like to thank Gateworks Corporation for sending me a
  Cambria board which was used during the development of this project.
  
  Reviewed by:	sam
  Approved by:	re (kensmith)
  Obtained from:	projects/mesh11s

Added:
  head/sys/net80211/ieee80211_hwmp.c   (contents, props changed)
  head/sys/net80211/ieee80211_mesh.c   (contents, props changed)
  head/sys/net80211/ieee80211_mesh.h   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/
  head/tools/tools/net80211/scripts/mesh/common   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/config.mesh   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/setup.simple   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/topology.line   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/topology.ring   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/topology.star   (contents, props changed)
  head/tools/tools/net80211/scripts/mesh/topology.tree   (contents, props changed)
Modified:
  head/sbin/ifconfig/ifconfig.8
  head/sbin/ifconfig/ifieee80211.c
  head/sbin/ifconfig/ifmedia.c
  head/share/man/man4/ath.4
  head/share/man/man4/mwl.4
  head/share/man/man4/ral.4
  head/share/man/man4/wlan.4
  head/sys/amd64/conf/GENERIC
  head/sys/conf/NOTES
  head/sys/conf/files
  head/sys/conf/options
  head/sys/dev/ath/if_ath.c
  head/sys/dev/ath/if_athvar.h
  head/sys/dev/mwl/if_mwl.c
  head/sys/dev/ral/rt2560.c
  head/sys/dev/ral/rt2661.c
  head/sys/i386/conf/GENERIC
  head/sys/net/if_media.h
  head/sys/net80211/_ieee80211.h
  head/sys/net80211/ieee80211.c
  head/sys/net80211/ieee80211.h
  head/sys/net80211/ieee80211_action.c
  head/sys/net80211/ieee80211_ddb.c
  head/sys/net80211/ieee80211_freebsd.h
  head/sys/net80211/ieee80211_input.c
  head/sys/net80211/ieee80211_ioctl.c
  head/sys/net80211/ieee80211_ioctl.h
  head/sys/net80211/ieee80211_node.c
  head/sys/net80211/ieee80211_node.h
  head/sys/net80211/ieee80211_output.c
  head/sys/net80211/ieee80211_proto.c
  head/sys/net80211/ieee80211_proto.h
  head/sys/net80211/ieee80211_scan.c
  head/sys/net80211/ieee80211_scan.h
  head/sys/net80211/ieee80211_scan_sta.c
  head/sys/net80211/ieee80211_var.h
  head/sys/pc98/conf/GENERIC
  head/sys/sparc64/conf/GENERIC
  head/tools/tools/nanobsd/gateworks/G2348
  head/tools/tools/nanobsd/gateworks/G2358
  head/tools/tools/net80211/scripts/config
  head/tools/tools/net80211/wlanstats/wlanstats.c

Modified: head/sbin/ifconfig/ifconfig.8
==============================================================================
--- head/sbin/ifconfig/ifconfig.8	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sbin/ifconfig/ifconfig.8	Sat Jul 11 15:02:45 2009	(r195618)
@@ -28,7 +28,7 @@
 .\"     From: @(#)ifconfig.8	8.3 (Berkeley) 1/5/94
 .\" $FreeBSD$
 .\"
-.Dd June 24, 2009
+.Dd July 8, 2009
 .Dt IFCONFIG 8
 .Os
 .Sh NAME
@@ -623,6 +623,7 @@ is one of
 .Cm hostap ),
 .Cm wds ,
 .Cm tdma ,
+.Cm mesh ,
 and
 .Cm monitor .
 The operating mode of a cloned interface cannot be changed.
@@ -1195,6 +1196,9 @@ indicates the address is denied access,
 .Ql *
 indicates the address is present but the current policy open
 (so the ACL is not consulted).
+.It Cm list mesh
+Displays the mesh routing table, used for forwarding packets on a mesh
+network.
 .It Cm list regdomain
 Display the current regulatory settings including the available channels
 and transmit power caps.
@@ -1278,6 +1282,8 @@ When operating as an access point displa
 currently associated.
 When operating in ad-hoc mode display stations identified as
 neighbors in the IBSS.
+When operating in mesh mode display stations identified as
+neighbors in the MBSS.
 When operating in station mode display the access point.
 Capabilities advertised by the stations are described under
 the
@@ -1813,6 +1819,85 @@ as it handles the RADIUS processing
 (and marks stations as authorized).
 .El
 .Pp
+The following parameters are related to a wireless interface operating in mesh
+mode:
+.Bl -tag -width indent
+.It Cm meshid Ar meshid
+Set the desired Mesh Identifier.
+The Mesh ID is a string up to 32 characters in length.
+A mesh interface must have a Mesh Identifier specified
+to reach an operational state.
+.It Cm meshttl Ar ttl
+Set the desired ``time to live'' for mesh forwarded packets;
+this is the number of hops a packet may be forwarded before
+it is discarded.
+The default setting for
+.Cm meshttl
+is 31.
+.It Cm meshpeering
+Enable or disable peering with neighbor mesh stations.
+Stations must peer before any data packets can be exchanged.
+By default
+.Cm meshpeering
+is enabled.
+.It Cm meshforward
+Enable or disable forwarding packets by a mesh interface.
+By default
+.Cm meshforward
+is enabled.
+.It Cm meshmetric Ar protocol
+Set the specified
+.Ar protocol
+as the link metric protocol used on a mesh network.
+The default protocol is called
+.Ar AIRTIME .
+The mesh interface will restart after changing this setting.
+.It Cm meshpath Ar protocol
+Set the specified
+.Ar protocol
+as the path selection protocol used on a mesh network.
+The only available protocol at the moment is called
+.Ar HWMP
+(Hybrid Wireless Mesh Protocol).
+The mesh interface will restart after changing this setting.
+.It Cm hwmprootmode Ar mode
+Stations on a mesh network can operate as ``root nodes.''
+Root nodes try to find paths to all mesh nodes and advertise themselves
+regularly.
+When there is a root mesh node on a network, other mesh nodes can setup
+paths between themselves faster because they can use the root node
+to find the destination.
+This path may not be the best, but on-demand
+routing will eventually find the best path.
+The following modes are recognized:
+.Pp
+.Bl -tag -width ".Cm PROACTIVE" -compact
+.It Cm DISABLED
+Disable root mode.
+.It Cm NORMAL
+Send broadcast path requests every two seconds.
+Nodes on the mesh without a path to this root mesh station with try to
+discover a path to us.
+.It Cm PROACTIVE
+Send broadcast path requests every two seconds and every node must reply with
+with a path reply even if it already has a path to this root mesh station,
+.It Cm RANN
+Send broadcast root annoucement (RANN) frames.
+Nodes on the mesh without a path to this root mesh station with try to
+discover a path to us.
+.El
+By default
+.Cm hwmprootmode 
+is set to
+.Ar DISABLED .
+.It Cm hwmpmaxhops Ar cnt
+Set the maximum number of hops allowed in an HMWP path to
+.Ar cnt .
+The default setting for
+.Cm hwmpmaxhops
+is 31.
+.El
+.Pp
 The following parameters are for compatibility with other systems:
 .Bl -tag -width indent
 .It Cm nwid Ar ssid

Modified: head/sbin/ifconfig/ifieee80211.c
==============================================================================
--- head/sbin/ifconfig/ifieee80211.c	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sbin/ifconfig/ifieee80211.c	Sat Jul 11 15:02:45 2009	(r195618)
@@ -81,6 +81,7 @@
 #include <net80211/ieee80211_freebsd.h>
 #include <net80211/ieee80211_superg.h>
 #include <net80211/ieee80211_tdma.h>
+#include <net80211/ieee80211_mesh.h>
 
 #include <assert.h>
 #include <ctype.h>
@@ -162,6 +163,7 @@ static void print_channels(int, const st
     int allchans, int verbose);
 static void regdomain_makechannels(struct ieee80211_regdomain_req *,
     const struct ieee80211_devcaps_req *);
+static const char *mesh_linkstate_string(uint8_t state);
 
 static struct ieee80211req_chaninfo *chaninfo;
 static struct ieee80211_regdomain regdomain;
@@ -575,6 +577,20 @@ set80211ssid(const char *val, int d, int
 }
 
 static void
+set80211meshid(const char *val, int d, int s, const struct afswtch *rafp)
+{
+	int		len;
+	u_int8_t	data[IEEE80211_NWID_LEN];
+
+	memset(data, 0, sizeof(data));
+	len = sizeof(data);
+	if (get_string(val, NULL, data, &len) == NULL)
+		exit(1);
+
+	set80211(s, IEEE80211_IOC_MESH_ID, 0, len, data);
+}	
+
+static void
 set80211stationname(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	int			len;
@@ -1262,6 +1278,66 @@ DECL_CMD_FUNC(set80211maccmd, val, d)
 }
 
 static void
+set80211meshrtmac(int s, int req, const char *val)
+{
+	char *temp;
+	struct sockaddr_dl sdl;
+
+	temp = malloc(strlen(val) + 2); /* ':' and '\0' */
+	if (temp == NULL)
+		errx(1, "malloc failed");
+	temp[0] = ':';
+	strcpy(temp + 1, val);
+	sdl.sdl_len = sizeof(sdl);
+	link_addr(temp, &sdl);
+	free(temp);
+	if (sdl.sdl_alen != IEEE80211_ADDR_LEN)
+		errx(1, "malformed link-level address");
+	set80211(s, IEEE80211_IOC_MESH_RTCMD, req,
+	    IEEE80211_ADDR_LEN, LLADDR(&sdl));
+}
+
+static
+DECL_CMD_FUNC(set80211addmeshrt, val, d)
+{
+	set80211meshrtmac(s, IEEE80211_MESH_RTCMD_ADD, val);
+}
+
+static
+DECL_CMD_FUNC(set80211delmeshrt, val, d)
+{
+	set80211meshrtmac(s, IEEE80211_MESH_RTCMD_DELETE, val);
+}
+
+static
+DECL_CMD_FUNC(set80211meshrtcmd, val, d)
+{
+	set80211(s, IEEE80211_IOC_MESH_RTCMD, d, 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211hwmprootmode, val, d)
+{
+	int mode;
+
+	if (strcasecmp(val, "normal") == 0)
+		mode = IEEE80211_HWMP_ROOTMODE_NORMAL;
+	else if (strcasecmp(val, "proactive") == 0)
+		mode = IEEE80211_HWMP_ROOTMODE_PROACTIVE;
+	else if (strcasecmp(val, "rann") == 0)
+		mode = IEEE80211_HWMP_ROOTMODE_RANN;
+	else
+		mode = IEEE80211_HWMP_ROOTMODE_DISABLED;
+	set80211(s, IEEE80211_IOC_HWMP_ROOTMODE, mode, 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211hwmpmaxhops, val, d)
+{
+	set80211(s, IEEE80211_IOC_HWMP_MAXHOPS, atoi(val), 0, NULL);
+}
+
+static void
 set80211pureg(const char *val, int d, int s, const struct afswtch *rafp)
 {
 	set80211(s, IEEE80211_IOC_PUREG, d, 0, NULL);
@@ -1771,6 +1847,42 @@ DECL_CMD_FUNC(set80211tdmabintval, val, 
 	set80211(s, IEEE80211_IOC_TDMA_BINTERVAL, atoi(val), 0, NULL);
 }
 
+static
+DECL_CMD_FUNC(set80211meshttl, val, d)
+{
+	set80211(s, IEEE80211_IOC_MESH_TTL, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211meshforward, val, d)
+{
+	set80211(s, IEEE80211_IOC_MESH_FWRD, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211meshpeering, val, d)
+{
+	set80211(s, IEEE80211_IOC_MESH_AP, atoi(val), 0, NULL);
+}
+
+static
+DECL_CMD_FUNC(set80211meshmetric, val, d)
+{
+	char v[12];
+	
+	memcpy(v, val, sizeof(v));
+	set80211(s, IEEE80211_IOC_MESH_PR_METRIC, 0, 0, v);
+}
+
+static
+DECL_CMD_FUNC(set80211meshpath, val, d)
+{
+	char v[12];
+	
+	memcpy(v, val, sizeof(v));
+	set80211(s, IEEE80211_IOC_MESH_PR_PATH, 0, 0, v);
+}
+
 static int
 regdomain_sort(const void *a, const void *b)
 {
@@ -2498,6 +2610,45 @@ printathie(const char *tag, const u_int8
 	}
 }
 
+
+static void
+printmeshconf(const char *tag, const uint8_t *ie, size_t ielen, int maxlen)
+{
+#define MATCHOUI(field, oui, string)					\
+do {									\
+	if (memcmp(field, oui, 4) == 0)					\
+		printf("%s", string);					\
+} while (0)
+
+	printf("%s", tag);
+	if (verbose) {
+		const struct ieee80211_meshconf_ie *mconf =
+			(const struct ieee80211_meshconf_ie *)ie;
+		const uint8_t null[4] = IEEE80211_MESHCONF_NULL;
+		const uint8_t hwmp[4] = IEEE80211_MESHCONF_HWMP;
+		const uint8_t airtime[4] = IEEE80211_MESHCONF_AIRTIME;
+		const uint8_t ccsig[4] = IEEE80211_MESHCONF_CCSIG;
+		const uint8_t sae[4] = IEEE80211_MESHCONF_SAE;
+		const uint8_t neighoff[4] = IEEE80211_MESHCONF_SAE;
+		printf("<v%d PATH:", mconf->conf_ver);
+		MATCHOUI(mconf->conf_pselid, hwmp, "HWMP");
+		printf(" LINK:");
+		MATCHOUI(mconf->conf_pmetid, airtime, "AIRTIME");
+		printf(" CONGESTION:");
+		MATCHOUI(mconf->conf_ccid, ccsig, "SIG");
+		MATCHOUI(mconf->conf_ccid, null, "NULL");
+		printf(" SYNC:");
+		MATCHOUI(mconf->conf_syncid, neighoff, "NEIGHOFF");
+		MATCHOUI(mconf->conf_syncid, null, "NULL");
+		printf(" AUTH:");
+		MATCHOUI(mconf->conf_authid, sae, "SAE");
+		MATCHOUI(mconf->conf_authid, null, "NULL");
+		printf(" FORM:0x%x CAPS:0x%x>", mconf->conf_form,
+		    mconf->conf_cap);
+	}
+#undef MATCHOUI
+}
+
 static const char *
 wpa_cipher(const u_int8_t *sel)
 {
@@ -2968,6 +3119,13 @@ printies(const u_int8_t *vp, int ielen, 
 			if (verbose)
 				printhtinfo(" HTINFO", vp, 2+vp[1], maxcols);
 			break;
+		case IEEE80211_ELEMID_MESHID:
+			if (verbose)
+				printssid(" MESHID", vp, 2+vp[1], maxcols);
+			break;
+		case IEEE80211_ELEMID_MESHCONF:
+			printmeshconf(" MESHCONF", vp, 2+vp[1], maxcols);
+			break;
 		default:
 			if (verbose)
 				printie(iename(vp[0]), vp, 2+vp[1], maxcols);
@@ -2996,7 +3154,7 @@ list_scan(int s)
 	uint8_t buf[24*1024];
 	char ssid[IEEE80211_NWID_LEN+1];
 	const uint8_t *cp;
-	int len, ssidmax;
+	int len, ssidmax, idlen;
 
 	if (get80211len(s, IEEE80211_IOC_SCAN_RESULTS, buf, sizeof(buf), &len) < 0)
 		errx(1, "unable to get scan results");
@@ -3005,9 +3163,9 @@ list_scan(int s)
 
 	getchaninfo(s);
 
-	ssidmax = verbose ? IEEE80211_NWID_LEN : 14;
+	ssidmax = verbose ? IEEE80211_NWID_LEN - 1 : 14;
 	printf("%-*.*s  %-17.17s  %4s %4s  %-7s  %3s %4s\n"
-		, ssidmax, ssidmax, "SSID"
+		, ssidmax, ssidmax, "SSID/MESH ID"
 		, "BSSID"
 		, "CHAN"
 		, "RATE"
@@ -3018,13 +3176,20 @@ list_scan(int s)
 	cp = buf;
 	do {
 		const struct ieee80211req_scan_result *sr;
-		const uint8_t *vp;
+		const uint8_t *vp, *idp;
 
 		sr = (const struct ieee80211req_scan_result *) cp;
 		vp = cp + sr->isr_ie_off;
+		if (sr->isr_meshid_len) {
+			idp = vp + sr->isr_ssid_len;
+			idlen = sr->isr_meshid_len;
+		} else {
+			idp = vp;
+			idlen = sr->isr_ssid_len;
+		}
 		printf("%-*.*s  %s  %3d  %3dM %3d:%-3d  %3d %-4.4s"
 			, ssidmax
-			  , copy_essid(ssid, ssidmax, vp, sr->isr_ssid_len)
+			  , copy_essid(ssid, ssidmax, idp, idlen)
 			  , ssid
 			, ether_ntoa((const struct ether_addr *) sr->isr_bssid)
 			, ieee80211_mhz2ieee(sr->isr_freq, sr->isr_flags)
@@ -3033,7 +3198,8 @@ list_scan(int s)
 			, sr->isr_intval
 			, getcaps(sr->isr_capinfo)
 		);
-		printies(vp + sr->isr_ssid_len, sr->isr_ie_len, 24);
+		printies(vp + sr->isr_ssid_len + sr->isr_meshid_len,
+		    sr->isr_ie_len, 24);
 		printf("\n");
 		cp += sr->isr_len, len -= sr->isr_len;
 	} while (len >= sizeof(struct ieee80211req_scan_result));
@@ -3151,18 +3317,32 @@ list_stations(int s)
 
 	getchaninfo(s);
 
-	printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %-7s\n"
-		, "ADDR"
-		, "AID"
-		, "CHAN"
-		, "RATE"
-		, "RSSI"
-		, "IDLE"
-		, "TXSEQ"
-		, "RXSEQ"
-		, "CAPS"
-		, "FLAG"
-	);
+	if (opmode == IEEE80211_M_MBSS)
+		printf("%-17.17s %4s %5s %5s %7s %4s %4s %4s %6s %6s\n"
+			, "ADDR"
+			, "CHAN"
+			, "LOCAL"
+			, "PEER"
+			, "STATE"
+			, "RATE"
+			, "RSSI"
+			, "IDLE"
+			, "TXSEQ"
+			, "RXSEQ"
+		);
+	else 
+		printf("%-17.17s %4s %4s %4s %4s %4s %6s %6s %4s %-7s\n"
+			, "ADDR"
+			, "AID"
+			, "CHAN"
+			, "RATE"
+			, "RSSI"
+			, "IDLE"
+			, "TXSEQ"
+			, "RXSEQ"
+			, "CAPS"
+			, "FLAG"
+		);
 	cp = (const uint8_t *) u.req.info;
 	do {
 		const struct ieee80211req_sta_info *si;
@@ -3170,18 +3350,36 @@ list_stations(int s)
 		si = (const struct ieee80211req_sta_info *) cp;
 		if (si->isi_len < sizeof(*si))
 			break;
-		printf("%s %4u %4d %3dM %3.1f %4d %6d %6d %-4.4s %-7.7s"
-			, ether_ntoa((const struct ether_addr*) si->isi_macaddr)
-			, IEEE80211_AID(si->isi_associd)
-			, ieee80211_mhz2ieee(si->isi_freq, si->isi_flags)
-			, si->isi_txmbps/2
-			, si->isi_rssi/2.
-			, si->isi_inact
-			, gettxseq(si)
-			, getrxseq(si)
-			, getcaps(si->isi_capinfo)
-			, getflags(si->isi_state)
-		);
+		if (opmode == IEEE80211_M_MBSS)
+			printf("%s %4d %5x %5x %7.7s %3dM %4.1f %4d %6d %6d"
+				, ether_ntoa((const struct ether_addr*)
+				    si->isi_macaddr)
+				, ieee80211_mhz2ieee(si->isi_freq,
+				    si->isi_flags)
+				, si->isi_localid
+				, si->isi_peerid
+				, mesh_linkstate_string(si->isi_peerstate)
+				, si->isi_txmbps/2
+				, si->isi_rssi/2.
+				, si->isi_inact
+				, gettxseq(si)
+				, getrxseq(si)
+			);
+		else 
+			printf("%s %4u %4d %3dM %4.1f %4d %6d %6d %-4.4s %-7.7s"
+				, ether_ntoa((const struct ether_addr*)
+				    si->isi_macaddr)
+				, IEEE80211_AID(si->isi_associd)
+				, ieee80211_mhz2ieee(si->isi_freq,
+				    si->isi_flags)
+				, si->isi_txmbps/2
+				, si->isi_rssi/2.
+				, si->isi_inact
+				, gettxseq(si)
+				, getrxseq(si)
+				, getcaps(si->isi_capinfo)
+				, getflags(si->isi_state)
+			);
 		printies(cp + si->isi_ie_off, si->isi_ie_len, 24);
 		printmimo(&si->isi_mimo);
 		printf("\n");
@@ -3190,6 +3388,28 @@ list_stations(int s)
 }
 
 static const char *
+mesh_linkstate_string(uint8_t state)
+{
+#define	N(a)	(sizeof(a) / sizeof(a[0]))
+	static const char *state_names[] = {
+	    [0] = "IDLE",
+	    [1] = "OPEN-TX",
+	    [2] = "OPEN-RX",
+	    [3] = "CONF-RX",
+	    [4] = "ESTAB",
+	    [5] = "HOLDING",
+	};
+
+	if (state >= N(state_names)) {
+		static char buf[10];
+		snprintf(buf, sizeof(buf), "#%u", state);
+		return buf;
+	} else
+		return state_names[state];
+#undef N
+}
+
+static const char *
 get_chaninfo(const struct ieee80211_channel *c, int precise,
 	char buf[], size_t bsize)
 {
@@ -3409,9 +3629,9 @@ list_keys(int s)
 }
 
 #define	IEEE80211_C_BITS \
-	"\20\1STA\7FF\10TURBOP\11IBSS\12PMGT" \
+	"\20\1STA\002803ENCAP\7FF\10TURBOP\11IBSS\12PMGT" \
 	"\13HOSTAP\14AHDEMO\15SWRETRY\16TXPMGT\17SHSLOT\20SHPREAMBLE" \
-	"\21MONITOR\22DFS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
+	"\21MONITOR\22DFS\23MBSS\30WPA1\31WPA2\32BURST\33WME\34WDS\36BGSCAN" \
 	"\37TXFRAG\40TDMA"
 
 static void
@@ -3729,6 +3949,40 @@ list_regdomain(int s, int channelsalso)
 		print_regdomain(&regdomain, verbose);
 }
 
+static void
+list_mesh(int s)
+{
+	int i;
+	struct ieee80211req ireq;
+	struct ieee80211req_mesh_route routes[128];
+
+	(void) memset(&ireq, 0, sizeof(ireq));
+	(void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
+	ireq.i_type = IEEE80211_IOC_MESH_RTCMD;
+	ireq.i_val = IEEE80211_MESH_RTCMD_LIST;
+	ireq.i_data = &routes;
+	ireq.i_len = sizeof(routes);
+	if (ioctl(s, SIOCG80211, &ireq) < 0)
+	 	err(1, "unable to get the Mesh routing table");
+
+	printf("%-17.17s %-17.17s %4s %4s %4s\n"
+		, "DEST"
+		, "NEXT HOP"
+		, "HOPS"
+		, "METRIC"
+		, "LIFETIME");
+
+	for (i = 0; i < ireq.i_len / sizeof(*routes); i++) {
+		printf("%s ",
+		    ether_ntoa((const struct ether_addr *)routes[i].imr_dest));
+		printf("%s %4u   %4d   %6d\n",
+			ether_ntoa((const struct ether_addr *)
+			    routes[i].imr_nexthop),
+			routes[i].imr_nhops, routes[i].imr_metric,
+			routes[i].imr_lifetime);
+	}
+}
+
 static
 DECL_CMD_FUNC(set80211list, arg, d)
 {
@@ -3762,6 +4016,8 @@ DECL_CMD_FUNC(set80211list, arg, d)
 		list_regdomain(s, 1);
 	else if (iseq(arg, "countries"))
 		list_countries();
+	else if (iseq(arg, "mesh"))
+		list_mesh(s);
 	else
 		errx(1, "Don't know how to list %s for %s", arg, name);
 	LINE_BREAK();
@@ -3787,6 +4043,8 @@ get80211opmode(int s)
 			return IEEE80211_M_HOSTAP;
 		if (ifmr.ifm_current & IFM_IEEE80211_MONITOR)
 			return IEEE80211_M_MONITOR;
+		if (ifmr.ifm_current & IFM_IEEE80211_MBSS)
+			return IEEE80211_M_MBSS;
 	}
 	return IEEE80211_M_STA;
 }
@@ -3911,13 +4169,13 @@ printrate(const char *tag, int v, int de
 }
 
 static int
-getssid(int s, int ix, void *data, size_t len, int *plen)
+getid(int s, int ix, void *data, size_t len, int *plen, int mesh)
 {
 	struct ieee80211req ireq;
 
 	(void) memset(&ireq, 0, sizeof(ireq));
 	(void) strncpy(ireq.i_name, name, sizeof(ireq.i_name));
-	ireq.i_type = IEEE80211_IOC_SSID;
+	ireq.i_type = (!mesh) ? IEEE80211_IOC_SSID : IEEE80211_IOC_MESH_ID;
 	ireq.i_val = ix;
 	ireq.i_data = data;
 	ireq.i_len = len;
@@ -3938,7 +4196,7 @@ ieee80211_status(int s)
 	const struct ieee80211_roamparam *rp;
 	const struct ieee80211_txparam *tp;
 
-	if (getssid(s, -1, data, sizeof(data), &len) < 0) {
+	if (getid(s, -1, data, sizeof(data), &len, 0) < 0) {
 		/* If we can't get the SSID, this isn't an 802.11 device. */
 		return;
 	}
@@ -3953,19 +4211,25 @@ ieee80211_status(int s)
 	gothtconf = 0;
 	gotregdomain = 0;
 
-	if (get80211val(s, IEEE80211_IOC_NUMSSIDS, &num) < 0)
-		num = 0;
-	printf("\tssid ");
-	if (num > 1) {
-		for (i = 0; i < num; i++) {
-			if (getssid(s, i, data, sizeof(data), &len) >= 0 && len > 0) {
-				printf(" %d:", i + 1);
-				print_string(data, len);
-			}
-		}
-	} else
+	printf("\t");
+	if (opmode == IEEE80211_M_MBSS) {
+		printf("meshid ");
+		getid(s, 0, data, sizeof(data), &len, 1);
 		print_string(data, len);
-
+	} else {
+		if (get80211val(s, IEEE80211_IOC_NUMSSIDS, &num) < 0)
+			num = 0;
+		printf("ssid ");
+		if (num > 1) {
+			for (i = 0; i < num; i++) {
+				if (getid(s, i, data, sizeof(data), &len, 0) >= 0 && len > 0) {
+					printf(" %d:", i + 1);
+					print_string(data, len);
+				}
+			}
+		} else
+			print_string(data, len);
+	}
 	c = getcurchan(s);
 	if (c->ic_freq != IEEE80211_CHAN_ANY) {
 		char buf[14];
@@ -4515,6 +4779,57 @@ end:
 		LINE_BREAK();
 		list_wme(s);
 	}
+
+	if (opmode == IEEE80211_M_MBSS) {
+		if (get80211val(s, IEEE80211_IOC_MESH_TTL, &val) != -1) {
+			LINE_CHECK("meshttl %u", val);
+		}
+		if (get80211val(s, IEEE80211_IOC_MESH_AP, &val) != -1) {
+			if (val)
+				LINE_CHECK("meshpeering");
+			else
+				LINE_CHECK("-meshpeering");
+		}
+		if (get80211val(s, IEEE80211_IOC_MESH_FWRD, &val) != -1) {
+			if (val)
+				LINE_CHECK("meshforward");
+			else
+				LINE_CHECK("-meshforward");
+		}
+		if (get80211len(s, IEEE80211_IOC_MESH_PR_METRIC, data, 12,
+		    &len) != -1) {
+			data[len] = '\0';
+			LINE_CHECK("meshmetric %s", data);
+		}
+		if (get80211len(s, IEEE80211_IOC_MESH_PR_PATH, data, 12,
+		    &len) != -1) {
+			data[len] = '\0';
+			LINE_CHECK("meshpath %s", data);
+		}
+		if (get80211val(s, IEEE80211_IOC_HWMP_ROOTMODE, &val) != -1) {
+			switch (val) {
+			case IEEE80211_HWMP_ROOTMODE_DISABLED:
+				LINE_CHECK("hwmprootmode DISABLED");
+				break;
+			case IEEE80211_HWMP_ROOTMODE_NORMAL:
+				LINE_CHECK("hwmprootmode NORMAL");
+				break;
+			case IEEE80211_HWMP_ROOTMODE_PROACTIVE:
+				LINE_CHECK("hwmprootmode PROACTIVE");
+				break;
+			case IEEE80211_HWMP_ROOTMODE_RANN:
+				LINE_CHECK("hwmprootmode RANN");
+				break;
+			default:
+				LINE_CHECK("hwmprootmode UNKNOWN(%d)", val);
+				break;
+			}
+		}
+		if (get80211val(s, IEEE80211_IOC_HWMP_MAXHOPS, &val) != -1) {
+			LINE_CHECK("hwmpmaxhops %u", val);
+		}
+	}
+
 	LINE_BREAK();
 }
 
@@ -4731,7 +5046,9 @@ DECL_CMD_FUNC(set80211clone_wlanmode, ar
 	else if (iseq(arg, "tdma")) {
 		params.icp_opmode = IEEE80211_M_AHDEMO;
 		params.icp_flags |= IEEE80211_CLONE_TDMA;
-	} else
+	} else if (iseq(arg, "mesh") || iseq(arg, "mp")) /* mesh point */
+		params.icp_opmode = IEEE80211_M_MBSS;
+	else
 		errx(1, "Don't know to create %s for %s", arg, name);
 #undef iseq
 }
@@ -4767,6 +5084,7 @@ set80211clone_wdslegacy(const char *val,
 static struct cmd ieee80211_cmds[] = {
 	DEF_CMD_ARG("ssid",		set80211ssid),
 	DEF_CMD_ARG("nwid",		set80211ssid),
+	DEF_CMD_ARG("meshid",		set80211meshid),
 	DEF_CMD_ARG("stationname",	set80211stationname),
 	DEF_CMD_ARG("station",		set80211stationname),	/* BSD/OS */
 	DEF_CMD_ARG("channel",		set80211channel),
@@ -4908,6 +5226,19 @@ static struct cmd ieee80211_cmds[] = {
 	DEF_CMD_ARG("tdmaslotlen",	set80211tdmaslotlen),
 	DEF_CMD_ARG("tdmabintval",	set80211tdmabintval),
 
+	DEF_CMD_ARG("meshttl",		set80211meshttl),
+	DEF_CMD("meshforward",	1,	set80211meshforward),
+	DEF_CMD("-meshforward",	0,	set80211meshforward),
+	DEF_CMD("meshpeering",	1,	set80211meshpeering),
+	DEF_CMD("-meshpeering",	0,	set80211meshpeering),
+	DEF_CMD_ARG("meshmetric",	set80211meshmetric),
+	DEF_CMD_ARG("meshpath",		set80211meshpath),
+	DEF_CMD("meshrt:flush",	IEEE80211_MESH_RTCMD_FLUSH,	set80211meshrtcmd),
+	DEF_CMD_ARG("meshrt:add",	set80211addmeshrt),
+	DEF_CMD_ARG("meshrt:del",	set80211delmeshrt),
+	DEF_CMD_ARG("hwmprootmode",	set80211hwmprootmode),
+	DEF_CMD_ARG("hwmpmaxhops",	set80211hwmpmaxhops),
+
 	/* vap cloning support */
 	DEF_CLONE_CMD_ARG("wlanaddr",	set80211clone_wlanaddr),
 	DEF_CLONE_CMD_ARG("wlanbssid",	set80211clone_wlanbssid),

Modified: head/sbin/ifconfig/ifmedia.c
==============================================================================
--- head/sbin/ifconfig/ifmedia.c	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sbin/ifconfig/ifmedia.c	Sat Jul 11 15:02:45 2009	(r195618)
@@ -104,7 +104,8 @@ static struct ifmedia_description *get_s
 
 #define	IFM_OPMODE(x) \
 	((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \
-	 IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR))
+	 IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \
+	 IFM_IEEE80211_MBSS))
 #define	IFM_IEEE80211_STA	0
 
 static void

Modified: head/share/man/man4/ath.4
==============================================================================
--- head/share/man/man4/ath.4	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/share/man/man4/ath.4	Sat Jul 11 15:02:45 2009	(r195618)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"/
-.Dd March 25, 2009
+.Dd July 8, 2009
 .Dt ATH 4
 .Os
 .Sh NAME
@@ -61,7 +61,7 @@ These APIs are used by a wide variety of
 a PCI and/or CardBus interface are supported.
 .Pp
 Supported features include 802.11 and 802.3 frames, power management, BSS,
-IBSS, TDMA, and host-based access point operation modes.
+IBSS, MBSS, TDMA, and host-based access point operation modes.
 All host/device interaction is via DMA.
 .Pp
 The
@@ -102,6 +102,7 @@ The driver supports
 .Cm adhoc ,
 .Cm adhoc-demo ,
 .Cm hostap ,
+.Cm mesh ,
 .Cm wds ,
 and
 .Cm monitor
@@ -175,6 +176,12 @@ ifconfig wlan0 inet 192.168.0.10 netmask
 	mode 11g
 .Ed
 .Pp
+Create an 802.11a mesh station:
+.Bd -literal -offset indent
+ifconfig wlan0 create wlandev ath0 wlanmode mesh
+ifconfig wlan0 meshid my_mesh mode 11a inet 192.168.0.10/24
+.Ed
+.Pp
 Create two virtual 802.11a host-based access points, one with
 with WEP enabled and one with no security, and bridge them to
 the fxp0 (wired) device:

Modified: head/share/man/man4/mwl.4
==============================================================================
--- head/share/man/man4/mwl.4	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/share/man/man4/mwl.4	Sat Jul 11 15:02:45 2009	(r195618)
@@ -28,7 +28,7 @@
 .\"
 .\" $FreeBSD$
 .\"/
-.Dd June 9, 2009
+.Dd July 8, 2009
 .Dt MWL 4
 .Os
 .Sh NAME
@@ -64,7 +64,7 @@ module to work.
 Normally this module is loaded on demand by the driver but it may
 also be compiled into the kernel.
 .Pp
-Supported features include 802.11n, power management, BSS,
+Supported features include 802.11n, power management, BSS, MBSS,
 and host-based access point operation modes.
 All host/device interaction is via DMA.
 .Pp
@@ -83,6 +83,7 @@ AES-CCM, TKIP, and Michael cryptographic
 The driver supports
 .Cm station ,
 .Cm hostap ,
+.Cm mesh ,
 and
 .Cm wds
 mode operation.
@@ -139,6 +140,12 @@ ifconfig wlan0 inet 192.168.0.10 netmask
 	mode 11g
 .Ed
 .Pp
+Create an 802.11a mesh station:
+.Bd -literal -offset indent
+ifconfig wlan0 create wlandev mwl0 wlanmode mesh
+ifconfig wlan0 meshid my_mesh mode 11a inet 192.168.0.10/24
+.Ed
+.Pp
 Create two virtual 802.11a host-based access points, one with
 with WEP enabled and one with no security, and bridge them to
 the fxp0 (wired) device:

Modified: head/share/man/man4/ral.4
==============================================================================
--- head/share/man/man4/ral.4	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/share/man/man4/ral.4	Sat Jul 11 15:02:45 2009	(r195618)
@@ -15,7 +15,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd April 13, 2008
+.Dd July 8, 2009
 .Os
 .Dt RAL 4
 .Sh NAME
@@ -72,12 +72,15 @@ supports
 .Cm station ,
 .Cm adhoc ,
 .Cm hostap ,
+.Cm mesh ,
 .Cm wds ,
 and
 .Cm monitor
 mode operation.
 Only one
 .Cm hostap
+or
+.Cm mesh
 virtual interface may be configured at a time.
 Any number of 
 .Cm wds

Modified: head/share/man/man4/wlan.4
==============================================================================
--- head/share/man/man4/wlan.4	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/share/man/man4/wlan.4	Sat Jul 11 15:02:45 2009	(r195618)
@@ -25,7 +25,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd May 15, 2009
+.Dd July 8, 2009
 .Dt WLAN 4
 .Os
 .Sh NAME
@@ -48,7 +48,7 @@ support.
 .Nm
 supports multi-mode devices capable of
 operating in both 2.4GHz and 5GHz bands and supports numerous
-802.11 standards: 802.11a, 802.11b, 802.11g, and 802.11n.
+802.11 standards: 802.11a, 802.11b, 802.11g, 802.11n, and 802.11s (Draft 3.0).
 The WPA, 802.11i, and 802.1x security protocols are supported
 through a combination of in-kernel code and user-mode applications.
 The WME/WMM multi-media protocols are supported entirely within
@@ -83,6 +83,8 @@ A client station in an infrastructure bs
 (i.e. one that associates to an access point).
 .It Cm hostap
 An access point in an infrastructure bss.
+.It Cm mesh
+A mesh station in an MBSS network.
 .It Cm adhoc
 A station in an IBSS network.
 .It Cm ahdemo
@@ -115,8 +117,6 @@ interface that does not send beacon fram
 interfaces may be created.
 .El
 .Pp
-More types are planned to support
-802.11s mesh nodes (station and ap).
 Note that an interface's type cannot be changed once it is created.
 .Pp
 .Nm
@@ -161,6 +161,12 @@ The module name of
 .Nm
 was used to be compatible with
 .Nx .
+.Pp
+Mesh stations follow the 802.11s Draft 3.0 specification which is
+not ratified and subject to change.
+Beware that this specification is incompatible with earlier drafts;
+and stations implementing earlier drafts (e.g. Linux)
+may not interoperate.
 .Sh SEE ALSO
 .Xr an 4 ,
 .Xr ath 4 ,

Modified: head/sys/amd64/conf/GENERIC
==============================================================================
--- head/sys/amd64/conf/GENERIC	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sys/amd64/conf/GENERIC	Sat Jul 11 15:02:45 2009	(r195618)
@@ -258,6 +258,7 @@ device		xe		# Xircom pccard Ethernet
 device		wlan		# 802.11 support
 options 	IEEE80211_DEBUG	# enable debug msgs
 options 	IEEE80211_AMPDU_AGE # age frames in AMPDU reorder q's
+options 	IEEE80211_SUPPORT_MESH	# enable 802.11s D3.0 support
 device		wlan_wep	# 802.11 WEP support
 device		wlan_ccmp	# 802.11 CCMP support
 device		wlan_tkip	# 802.11 TKIP support

Modified: head/sys/conf/NOTES
==============================================================================
--- head/sys/conf/NOTES	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sys/conf/NOTES	Sat Jul 11 15:02:45 2009	(r195618)
@@ -738,6 +738,8 @@ device		vlan
 device		wlan
 options 	IEEE80211_DEBUG		#enable debugging msgs
 options 	IEEE80211_AMPDU_AGE	#age frames in AMPDU reorder q's
+options 	IEEE80211_SUPPORT_MESH	#enable 802.11s D3.0 support
+options 	IEEE80211_SUPPORT_TDMA	#enable TDMA support
 
 #  The `wlan_wep', `wlan_tkip', and `wlan_ccmp' devices provide
 #  support for WEP, TKIP, and AES-CCMP crypto protocols optionally

Modified: head/sys/conf/files
==============================================================================
--- head/sys/conf/files	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sys/conf/files	Sat Jul 11 15:02:45 2009	(r195618)
@@ -2239,6 +2239,7 @@ net80211/ieee80211_acl.c	optional wlan w
 net80211/ieee80211_action.c	optional wlan
 net80211/ieee80211_ageq.c	optional wlan
 net80211/ieee80211_adhoc.c	optional wlan
+net80211/ieee80211_ageq.c	optional wlan
 net80211/ieee80211_amrr.c	optional wlan wlan_amrr
 net80211/ieee80211_crypto.c	optional wlan
 net80211/ieee80211_crypto_ccmp.c optional wlan wlan_ccmp
@@ -2250,8 +2251,10 @@ net80211/ieee80211_dfs.c	optional wlan
 net80211/ieee80211_freebsd.c	optional wlan
 net80211/ieee80211_hostap.c	optional wlan
 net80211/ieee80211_ht.c		optional wlan
+net80211/ieee80211_hwmp.c	optional wlan ieee80211_support_mesh
 net80211/ieee80211_input.c	optional wlan
 net80211/ieee80211_ioctl.c	optional wlan
+net80211/ieee80211_mesh.c	optional wlan ieee80211_support_mesh
 net80211/ieee80211_monitor.c	optional wlan
 net80211/ieee80211_node.c	optional wlan
 net80211/ieee80211_output.c	optional wlan

Modified: head/sys/conf/options
==============================================================================
--- head/sys/conf/options	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sys/conf/options	Sat Jul 11 15:02:45 2009	(r195618)
@@ -804,6 +804,7 @@ INTR_FILTER
 IEEE80211_DEBUG		opt_wlan.h
 IEEE80211_DEBUG_REFCNT	opt_wlan.h
 IEEE80211_AMPDU_AGE	opt_wlan.h
+IEEE80211_SUPPORT_MESH	opt_wlan.h
 IEEE80211_SUPPORT_SUPERG	opt_wlan.h
 IEEE80211_SUPPORT_TDMA	opt_wlan.h
 

Modified: head/sys/dev/ath/if_ath.c
==============================================================================
--- head/sys/dev/ath/if_ath.c	Sat Jul 11 08:27:48 2009	(r195617)
+++ head/sys/dev/ath/if_ath.c	Sat Jul 11 15:02:45 2009	(r195618)
@@ -578,6 +578,7 @@ ath_attach(u_int16_t devid, struct ath_s
 		| IEEE80211_C_MONITOR		/* monitor mode */
 		| IEEE80211_C_AHDEMO		/* adhoc demo mode */
 		| IEEE80211_C_WDS		/* 4-address traffic works */
+		| IEEE80211_C_MBSS		/* mesh point link mode */
 		| IEEE80211_C_SHPREAMBLE	/* short preamble supported */
 		| IEEE80211_C_SHSLOT		/* short slot time supported */
 		| IEEE80211_C_WPA		/* capable of WPA1+WPA2 */
@@ -655,6 +656,7 @@ ath_attach(u_int16_t devid, struct ath_s
 	if (ath_hal_hasbursting(ah))
 		ic->ic_caps |= IEEE80211_C_BURST;
 	sc->sc_hasbmask = ath_hal_hasbssidmask(ah);
+	sc->sc_hasbmatch = ath_hal_hasbssidmatch(ah);
 	sc->sc_hastsfadd = ath_hal_hastsfadjust(ah);
 	if (ath_hal_hasfastframes(ah))
 		ic->ic_caps |= IEEE80211_C_FF;
@@ -918,6 +920,7 @@ ath_vap_create(struct ieee80211com *ic,
 		}
 		break;
 	case IEEE80211_M_HOSTAP:
+	case IEEE80211_M_MBSS:
 		needbeacon = 1;
 		break;
 	case IEEE80211_M_WDS:
@@ -936,7 +939,6 @@ ath_vap_create(struct ieee80211com *ic,
 			ic_opmode = IEEE80211_M_HOSTAP;
 		else
 			ic_opmode = ic->ic_opmode;
-		break;
 	default:
 		device_printf(sc->sc_dev, "unknown opmode %d\n", opmode);
 		goto bad;
@@ -950,7 +952,7 @@ ath_vap_create(struct ieee80211com *ic,

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***


More information about the svn-src-head mailing list