summaryrefslogtreecommitdiffstats
path: root/sbin/ifconfig
diff options
context:
space:
mode:
authorrpaulo <rpaulo@FreeBSD.org>2009-07-11 15:02:45 +0000
committerrpaulo <rpaulo@FreeBSD.org>2009-07-11 15:02:45 +0000
commit8424d740209fc6cee8a8bc4deba2a40cdc77d1fd (patch)
tree7dd4e6a8c026ec13b70ca0a34e625684d79ec055 /sbin/ifconfig
parentba5583d31888cb78136b114790fce49c792c14d0 (diff)
downloadFreeBSD-src-8424d740209fc6cee8a8bc4deba2a40cdc77d1fd.zip
FreeBSD-src-8424d740209fc6cee8a8bc4deba2a40cdc77d1fd.tar.gz
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
Diffstat (limited to 'sbin/ifconfig')
-rw-r--r--sbin/ifconfig/ifconfig.887
-rw-r--r--sbin/ifconfig/ifieee80211.c427
-rw-r--r--sbin/ifconfig/ifmedia.c3
3 files changed, 467 insertions, 50 deletions
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 5f571f8..1d2f096 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -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 display the stations that are
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
diff --git a/sbin/ifconfig/ifieee80211.c b/sbin/ifconfig/ifieee80211.c
index dbbc195..2b196a6 100644
--- a/sbin/ifconfig/ifieee80211.c
+++ b/sbin/ifconfig/ifieee80211.c
@@ -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 struct ieee80211req_chaninfo *,
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 s, const struct afswtch *rafp)
}
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, d)
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_t *ie, size_t ielen, int maxlen)
}
}
+
+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, int maxcols)
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 defrate, int defmcs)
}
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, arg, d)
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, int d, int s, const struct afswtch *raf
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),
diff --git a/sbin/ifconfig/ifmedia.c b/sbin/ifconfig/ifmedia.c
index d89f3eb..bb95043 100644
--- a/sbin/ifconfig/ifmedia.c
+++ b/sbin/ifconfig/ifmedia.c
@@ -104,7 +104,8 @@ static struct ifmedia_description *get_subtype_desc(int,
#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
OpenPOWER on IntegriCloud