132176cfdSRui Paulo /*-
232176cfdSRui Paulo * Copyright (c) 2009 The FreeBSD Foundation
332176cfdSRui Paulo * All rights reserved.
432176cfdSRui Paulo *
532176cfdSRui Paulo * This software was developed by Rui Paulo under sponsorship from the
632176cfdSRui Paulo * FreeBSD Foundation.
732176cfdSRui Paulo *
832176cfdSRui Paulo * Redistribution and use in source and binary forms, with or without
932176cfdSRui Paulo * modification, are permitted provided that the following conditions
1032176cfdSRui Paulo * are met:
1132176cfdSRui Paulo * 1. Redistributions of source code must retain the above copyright
1232176cfdSRui Paulo * notice, this list of conditions and the following disclaimer.
1332176cfdSRui Paulo * 2. Redistributions in binary form must reproduce the above copyright
1432176cfdSRui Paulo * notice, this list of conditions and the following disclaimer in the
1532176cfdSRui Paulo * documentation and/or other materials provided with the distribution.
1632176cfdSRui Paulo *
1732176cfdSRui Paulo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1832176cfdSRui Paulo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1932176cfdSRui Paulo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2032176cfdSRui Paulo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2132176cfdSRui Paulo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2232176cfdSRui Paulo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2332176cfdSRui Paulo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2432176cfdSRui Paulo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2532176cfdSRui Paulo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2632176cfdSRui Paulo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2732176cfdSRui Paulo * SUCH DAMAGE.
2832176cfdSRui Paulo *
29085ff963SMatthew Dillon * $FreeBSD$
3032176cfdSRui Paulo */
3132176cfdSRui Paulo #ifndef _NET80211_IEEE80211_MESH_H_
3232176cfdSRui Paulo #define _NET80211_IEEE80211_MESH_H_
3332176cfdSRui Paulo
3432176cfdSRui Paulo #define IEEE80211_MESH_DEFAULT_TTL 31
35085ff963SMatthew Dillon #define IEEE80211_MESH_MAX_NEIGHBORS 15
3632176cfdSRui Paulo
3732176cfdSRui Paulo /*
3832176cfdSRui Paulo * NB: all structures are __packed so sizeof works on arm, et. al.
3932176cfdSRui Paulo */
4032176cfdSRui Paulo /*
4132176cfdSRui Paulo * 802.11s Information Elements.
4232176cfdSRui Paulo */
4332176cfdSRui Paulo /* Mesh Configuration */
44085ff963SMatthew Dillon #define IEEE80211_MESH_CONF_SZ (7)
4532176cfdSRui Paulo struct ieee80211_meshconf_ie {
4632176cfdSRui Paulo uint8_t conf_ie; /* IEEE80211_ELEMID_MESHCONF */
4732176cfdSRui Paulo uint8_t conf_len;
4832176cfdSRui Paulo uint8_t conf_pselid; /* Active Path Sel. Proto. ID */
4932176cfdSRui Paulo uint8_t conf_pmetid; /* Active Metric Identifier */
5032176cfdSRui Paulo uint8_t conf_ccid; /* Congestion Control Mode ID */
5132176cfdSRui Paulo uint8_t conf_syncid; /* Sync. Protocol ID */
5232176cfdSRui Paulo uint8_t conf_authid; /* Auth. Protocol ID */
5332176cfdSRui Paulo uint8_t conf_form; /* Formation Information */
54085ff963SMatthew Dillon uint8_t conf_cap;
5532176cfdSRui Paulo } __packed;
5632176cfdSRui Paulo
5732176cfdSRui Paulo /* Hybrid Wireless Mesh Protocol */
58085ff963SMatthew Dillon enum {
59085ff963SMatthew Dillon /* 0 reserved */
60085ff963SMatthew Dillon IEEE80211_MESHCONF_PATH_HWMP = 1,
61085ff963SMatthew Dillon /* 2-254 reserved */
62085ff963SMatthew Dillon IEEE80211_MESHCONF_PATH_VENDOR = 255,
63085ff963SMatthew Dillon };
64085ff963SMatthew Dillon
6532176cfdSRui Paulo /* Airtime Link Metric */
66085ff963SMatthew Dillon enum {
67085ff963SMatthew Dillon /* 0 reserved */
68085ff963SMatthew Dillon IEEE80211_MESHCONF_METRIC_AIRTIME = 1,
69085ff963SMatthew Dillon /* 2-254 reserved */
70085ff963SMatthew Dillon IEEE80211_MESHCONF_METRIC_VENDOR = 255,
71085ff963SMatthew Dillon };
72085ff963SMatthew Dillon
7332176cfdSRui Paulo /* Congestion Control */
74085ff963SMatthew Dillon enum {
75085ff963SMatthew Dillon IEEE80211_MESHCONF_CC_DISABLED = 0,
76085ff963SMatthew Dillon IEEE80211_MESHCONF_CC_SIG = 1,
77085ff963SMatthew Dillon /* 2-254 reserved */
78085ff963SMatthew Dillon IEEE80211_MESHCONF_CC_VENDOR = 255,
79085ff963SMatthew Dillon };
80085ff963SMatthew Dillon
8132176cfdSRui Paulo /* Neighbour Offset */
82085ff963SMatthew Dillon enum {
83085ff963SMatthew Dillon /* 0 reserved */
84085ff963SMatthew Dillon IEEE80211_MESHCONF_SYNC_NEIGHOFF = 1,
85085ff963SMatthew Dillon /* 2-254 rserved */
86085ff963SMatthew Dillon IEEE80211_MESHCONF_SYNC_VENDOR = 255,
87085ff963SMatthew Dillon };
88085ff963SMatthew Dillon
89085ff963SMatthew Dillon /* Authentication Protocol Identifier */
90085ff963SMatthew Dillon enum {
91085ff963SMatthew Dillon
92085ff963SMatthew Dillon IEEE80211_MESHCONF_AUTH_DISABLED = 0,
9332176cfdSRui Paulo /* Simultaneous Authenticaction of Equals */
94085ff963SMatthew Dillon IEEE80211_MESHCONF_AUTH_SEA = 1,
95085ff963SMatthew Dillon IEEE80211_MESHCONF_AUTH_8021X = 2, /* IEEE 802.1X */
96085ff963SMatthew Dillon /* 3-254 reserved */
97085ff963SMatthew Dillon IEEE80211_MESHCONF_AUTH_VENDOR = 255,
98085ff963SMatthew Dillon };
99085ff963SMatthew Dillon
100085ff963SMatthew Dillon /* Mesh Formation Info */
101085ff963SMatthew Dillon #define IEEE80211_MESHCONF_FORM_GATE 0x01 /* Connected to Gate */
102085ff963SMatthew Dillon #define IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x7E /* Number of Neighbours */
103085ff963SMatthew Dillon #define IEEE80211_MESHCONF_FORM_SA 0xF0 /* indicating 802.1X auth */
104085ff963SMatthew Dillon
105085ff963SMatthew Dillon /* Mesh Capability */
10632176cfdSRui Paulo #define IEEE80211_MESHCONF_CAP_AP 0x01 /* Accepting Peers */
10732176cfdSRui Paulo #define IEEE80211_MESHCONF_CAP_MCCAS 0x02 /* MCCA supported */
10832176cfdSRui Paulo #define IEEE80211_MESHCONF_CAP_MCCAE 0x04 /* MCCA enabled */
10932176cfdSRui Paulo #define IEEE80211_MESHCONF_CAP_FWRD 0x08 /* forwarding enabled */
11032176cfdSRui Paulo #define IEEE80211_MESHCONF_CAP_BTR 0x10 /* Beacon Timing Report Enab */
111085ff963SMatthew Dillon #define IEEE80211_MESHCONF_CAP_TBTT 0x20 /* TBTT Adjusting */
112085ff963SMatthew Dillon #define IEEE80211_MESHCONF_CAP_PSL 0x40 /* Power Save Level */
113085ff963SMatthew Dillon /* 0x80 reserved */
11432176cfdSRui Paulo
11532176cfdSRui Paulo /* Mesh Identifier */
11632176cfdSRui Paulo struct ieee80211_meshid_ie {
11732176cfdSRui Paulo uint8_t id_ie; /* IEEE80211_ELEMID_MESHID */
11832176cfdSRui Paulo uint8_t id_len;
11932176cfdSRui Paulo } __packed;
12032176cfdSRui Paulo
12132176cfdSRui Paulo /* Link Metric Report */
12232176cfdSRui Paulo struct ieee80211_meshlmetric_ie {
123085ff963SMatthew Dillon uint8_t lm_ie; /* IEEE80211_ACTION_MESH_LMETRIC */
12432176cfdSRui Paulo uint8_t lm_len;
125085ff963SMatthew Dillon uint8_t lm_flags;
126085ff963SMatthew Dillon #define IEEE80211_MESH_LMETRIC_FLAGS_REQ 0x01 /* Request */
127085ff963SMatthew Dillon /*
128085ff963SMatthew Dillon * XXX: this field should be variable in size and depend on
129085ff963SMatthew Dillon * the active active path selection metric identifier
130085ff963SMatthew Dillon */
13132176cfdSRui Paulo uint32_t lm_metric;
13232176cfdSRui Paulo #define IEEE80211_MESHLMETRIC_INITIALVAL 0
13332176cfdSRui Paulo } __packed;
13432176cfdSRui Paulo
13532176cfdSRui Paulo /* Congestion Notification */
13632176cfdSRui Paulo struct ieee80211_meshcngst_ie {
13732176cfdSRui Paulo uint8_t cngst_ie; /* IEEE80211_ELEMID_MESHCNGST */
13832176cfdSRui Paulo uint8_t cngst_len;
13932176cfdSRui Paulo uint16_t cngst_timer[4]; /* Expiration Timers: AC_BK,
14032176cfdSRui Paulo AC_BE, AC_VI, AC_VO */
14132176cfdSRui Paulo } __packed;
14232176cfdSRui Paulo
14332176cfdSRui Paulo /* Peer Link Management */
144085ff963SMatthew Dillon #define IEEE80211_MPM_BASE_SZ (4)
145085ff963SMatthew Dillon #define IEEE80211_MPM_MAX_SZ (8)
14632176cfdSRui Paulo struct ieee80211_meshpeer_ie {
14732176cfdSRui Paulo uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
14832176cfdSRui Paulo uint8_t peer_len;
149085ff963SMatthew Dillon uint16_t peer_proto; /* Peer Management Protocol */
15032176cfdSRui Paulo uint16_t peer_llinkid; /* Local Link ID */
15132176cfdSRui Paulo uint16_t peer_linkid; /* Peer Link ID */
15232176cfdSRui Paulo uint16_t peer_rcode;
15332176cfdSRui Paulo } __packed;
15432176cfdSRui Paulo
155085ff963SMatthew Dillon /* Mesh Peering Protocol Identifier field value */
15632176cfdSRui Paulo enum {
157085ff963SMatthew Dillon IEEE80211_MPPID_MPM = 0, /* Mesh peering management */
158085ff963SMatthew Dillon IEEE80211_MPPID_AUTH_MPM = 1, /* Auth. mesh peering exchange */
159085ff963SMatthew Dillon /* 2-65535 reserved */
16032176cfdSRui Paulo };
16132176cfdSRui Paulo
16232176cfdSRui Paulo #ifdef notyet
16332176cfdSRui Paulo /* Mesh Channel Switch Annoucement */
16432176cfdSRui Paulo struct ieee80211_meshcsa_ie {
16532176cfdSRui Paulo uint8_t csa_ie; /* IEEE80211_ELEMID_MESHCSA */
16632176cfdSRui Paulo uint8_t csa_len;
16732176cfdSRui Paulo uint8_t csa_mode;
16832176cfdSRui Paulo uint8_t csa_newclass; /* New Regulatory Class */
16932176cfdSRui Paulo uint8_t csa_newchan;
17032176cfdSRui Paulo uint8_t csa_precvalue; /* Precedence Value */
17132176cfdSRui Paulo uint8_t csa_count;
17232176cfdSRui Paulo } __packed;
17332176cfdSRui Paulo
17432176cfdSRui Paulo /* Mesh TIM */
17532176cfdSRui Paulo /* Equal to the non Mesh version */
17632176cfdSRui Paulo
17732176cfdSRui Paulo /* Mesh Awake Window */
17832176cfdSRui Paulo struct ieee80211_meshawakew_ie {
17932176cfdSRui Paulo uint8_t awakew_ie; /* IEEE80211_ELEMID_MESHAWAKEW */
18032176cfdSRui Paulo uint8_t awakew_len;
18132176cfdSRui Paulo uint8_t awakew_windowlen; /* in TUs */
18232176cfdSRui Paulo } __packed;
18332176cfdSRui Paulo
18432176cfdSRui Paulo /* Mesh Beacon Timing */
18532176cfdSRui Paulo struct ieee80211_meshbeacont_ie {
18632176cfdSRui Paulo uint8_t beacont_ie; /* IEEE80211_ELEMID_MESHBEACONT */
18732176cfdSRui Paulo uint8_t beacont_len;
18832176cfdSRui Paulo struct {
18932176cfdSRui Paulo uint8_t mp_aid; /* Least Octet of AID */
19032176cfdSRui Paulo uint16_t mp_btime; /* Beacon Time */
19132176cfdSRui Paulo uint16_t mp_bint; /* Beacon Interval */
19232176cfdSRui Paulo } __packed mp[1]; /* NB: variable size */
19332176cfdSRui Paulo } __packed;
19432176cfdSRui Paulo #endif
19532176cfdSRui Paulo
196085ff963SMatthew Dillon /* Gate (GANN) Annoucement */
197085ff963SMatthew Dillon /*
198085ff963SMatthew Dillon * NB: these macros used for the length in the IEs does not include 2 bytes
199085ff963SMatthew Dillon * for _ie and _len fields as is defined by the standard.
200085ff963SMatthew Dillon */
201085ff963SMatthew Dillon #define IEEE80211_MESHGANN_BASE_SZ (15)
202085ff963SMatthew Dillon struct ieee80211_meshgann_ie {
203085ff963SMatthew Dillon uint8_t gann_ie; /* IEEE80211_ELEMID_MESHGANN */
204085ff963SMatthew Dillon uint8_t gann_len;
205085ff963SMatthew Dillon uint8_t gann_flags;
206085ff963SMatthew Dillon uint8_t gann_hopcount;
207085ff963SMatthew Dillon uint8_t gann_ttl;
208085ff963SMatthew Dillon uint8_t gann_addr[IEEE80211_ADDR_LEN];
209085ff963SMatthew Dillon uint32_t gann_seq; /* GANN Sequence Number */
210085ff963SMatthew Dillon uint16_t gann_interval; /* GANN Interval */
21132176cfdSRui Paulo } __packed;
21232176cfdSRui Paulo
21332176cfdSRui Paulo /* Root (MP) Annoucement */
214085ff963SMatthew Dillon #define IEEE80211_MESHRANN_BASE_SZ (21)
21532176cfdSRui Paulo struct ieee80211_meshrann_ie {
21632176cfdSRui Paulo uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */
21732176cfdSRui Paulo uint8_t rann_len;
21832176cfdSRui Paulo uint8_t rann_flags;
219085ff963SMatthew Dillon #define IEEE80211_MESHRANN_FLAGS_GATE 0x01 /* Mesh Gate */
22032176cfdSRui Paulo uint8_t rann_hopcount;
22132176cfdSRui Paulo uint8_t rann_ttl;
22232176cfdSRui Paulo uint8_t rann_addr[IEEE80211_ADDR_LEN];
22332176cfdSRui Paulo uint32_t rann_seq; /* HWMP Sequence Number */
224085ff963SMatthew Dillon uint32_t rann_interval;
22532176cfdSRui Paulo uint32_t rann_metric;
22632176cfdSRui Paulo } __packed;
22732176cfdSRui Paulo
22832176cfdSRui Paulo /* Mesh Path Request */
229085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_BASE_SZ (26)
230085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_BASE_SZ_AE (32)
231085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_TRGT_SZ (11)
232085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_TCNT_OFFSET (27)
233085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_TCNT_OFFSET_AE (33)
23432176cfdSRui Paulo struct ieee80211_meshpreq_ie {
23532176cfdSRui Paulo uint8_t preq_ie; /* IEEE80211_ELEMID_MESHPREQ */
23632176cfdSRui Paulo uint8_t preq_len;
23732176cfdSRui Paulo uint8_t preq_flags;
238085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_FLAGS_GATE 0x01 /* Mesh Gate */
239085ff963SMatthew Dillon #define IEEE80211_MESHPREQ_FLAGS_AM 0x02 /* 0 = bcast / 1 = ucast */
24032176cfdSRui Paulo #define IEEE80211_MESHPREQ_FLAGS_PP 0x04 /* Proactive PREP */
24132176cfdSRui Paulo #define IEEE80211_MESHPREQ_FLAGS_AE 0x40 /* Address Extension */
24232176cfdSRui Paulo uint8_t preq_hopcount;
24332176cfdSRui Paulo uint8_t preq_ttl;
24432176cfdSRui Paulo uint32_t preq_id;
24532176cfdSRui Paulo uint8_t preq_origaddr[IEEE80211_ADDR_LEN];
24632176cfdSRui Paulo uint32_t preq_origseq; /* HWMP Sequence Number */
247085ff963SMatthew Dillon /* NB: may have Originator External Address */
248085ff963SMatthew Dillon uint8_t preq_orig_ext_addr[IEEE80211_ADDR_LEN];
24932176cfdSRui Paulo uint32_t preq_lifetime;
25032176cfdSRui Paulo uint32_t preq_metric;
25132176cfdSRui Paulo uint8_t preq_tcount; /* target count */
25232176cfdSRui Paulo struct {
25332176cfdSRui Paulo uint8_t target_flags;
25432176cfdSRui Paulo #define IEEE80211_MESHPREQ_TFLAGS_TO 0x01 /* Target Only */
25532176cfdSRui Paulo #define IEEE80211_MESHPREQ_TFLAGS_USN 0x04 /* Unknown HWMP seq number */
25632176cfdSRui Paulo uint8_t target_addr[IEEE80211_ADDR_LEN];
25732176cfdSRui Paulo uint32_t target_seq; /* HWMP Sequence Number */
25832176cfdSRui Paulo } __packed preq_targets[1]; /* NB: variable size */
25932176cfdSRui Paulo } __packed;
26032176cfdSRui Paulo
26132176cfdSRui Paulo /* Mesh Path Reply */
262085ff963SMatthew Dillon #define IEEE80211_MESHPREP_BASE_SZ (31)
263085ff963SMatthew Dillon #define IEEE80211_MESHPREP_BASE_SZ_AE (37)
26432176cfdSRui Paulo struct ieee80211_meshprep_ie {
26532176cfdSRui Paulo uint8_t prep_ie; /* IEEE80211_ELEMID_MESHPREP */
26632176cfdSRui Paulo uint8_t prep_len;
26732176cfdSRui Paulo uint8_t prep_flags;
268085ff963SMatthew Dillon #define IEEE80211_MESHPREP_FLAGS_AE 0x40 /* Address Extension */
26932176cfdSRui Paulo uint8_t prep_hopcount;
27032176cfdSRui Paulo uint8_t prep_ttl;
27132176cfdSRui Paulo uint8_t prep_targetaddr[IEEE80211_ADDR_LEN];
27232176cfdSRui Paulo uint32_t prep_targetseq;
273085ff963SMatthew Dillon /* NB: May have Target External Address */
274085ff963SMatthew Dillon uint8_t prep_target_ext_addr[IEEE80211_ADDR_LEN];
27532176cfdSRui Paulo uint32_t prep_lifetime;
27632176cfdSRui Paulo uint32_t prep_metric;
27732176cfdSRui Paulo uint8_t prep_origaddr[IEEE80211_ADDR_LEN];
27832176cfdSRui Paulo uint32_t prep_origseq; /* HWMP Sequence Number */
27932176cfdSRui Paulo } __packed;
28032176cfdSRui Paulo
28132176cfdSRui Paulo /* Mesh Path Error */
282085ff963SMatthew Dillon #define IEEE80211_MESHPERR_MAXDEST (19)
283085ff963SMatthew Dillon #define IEEE80211_MESHPERR_NDEST_OFFSET (3)
284085ff963SMatthew Dillon #define IEEE80211_MESHPERR_BASE_SZ (2)
285085ff963SMatthew Dillon #define IEEE80211_MESHPERR_DEST_SZ (13)
286085ff963SMatthew Dillon #define IEEE80211_MESHPERR_DEST_SZ_AE (19)
28732176cfdSRui Paulo struct ieee80211_meshperr_ie {
28832176cfdSRui Paulo uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */
28932176cfdSRui Paulo uint8_t perr_len;
29032176cfdSRui Paulo uint8_t perr_ttl;
29132176cfdSRui Paulo uint8_t perr_ndests; /* Number of Destinations */
29232176cfdSRui Paulo struct {
29332176cfdSRui Paulo uint8_t dest_flags;
294085ff963SMatthew Dillon #define IEEE80211_MESHPERR_DFLAGS_USN 0x01 /* XXX: not part of standard */
295085ff963SMatthew Dillon #define IEEE80211_MESHPERR_DFLAGS_RC 0x02 /* XXX: not part of standard */
296085ff963SMatthew Dillon #define IEEE80211_MESHPERR_FLAGS_AE 0x40 /* Address Extension */
29732176cfdSRui Paulo uint8_t dest_addr[IEEE80211_ADDR_LEN];
29832176cfdSRui Paulo uint32_t dest_seq; /* HWMP Sequence Number */
299085ff963SMatthew Dillon /* NB: May have Destination External Address */
300085ff963SMatthew Dillon uint8_t dest_ext_addr[IEEE80211_ADDR_LEN];
30132176cfdSRui Paulo uint16_t dest_rcode;
30232176cfdSRui Paulo } __packed perr_dests[1]; /* NB: variable size */
30332176cfdSRui Paulo } __packed;
30432176cfdSRui Paulo
30532176cfdSRui Paulo #ifdef notyet
30632176cfdSRui Paulo /* Mesh Proxy Update */
30732176cfdSRui Paulo struct ieee80211_meshpu_ie {
30832176cfdSRui Paulo uint8_t pu_ie; /* IEEE80211_ELEMID_MESHPU */
30932176cfdSRui Paulo uint8_t pu_len;
31032176cfdSRui Paulo uint8_t pu_flags;
31132176cfdSRui Paulo #define IEEE80211_MESHPU_FLAGS_MASK 0x1
31232176cfdSRui Paulo #define IEEE80211_MESHPU_FLAGS_DEL 0x0
31332176cfdSRui Paulo #define IEEE80211_MESHPU_FLAGS_ADD 0x1
31432176cfdSRui Paulo uint8_t pu_seq; /* PU Sequence Number */
31532176cfdSRui Paulo uint8_t pu_addr[IEEE80211_ADDR_LEN];
31632176cfdSRui Paulo uint8_t pu_naddr; /* Number of Proxied Addresses */
31732176cfdSRui Paulo /* NB: proxied address follows */
31832176cfdSRui Paulo } __packed;
31932176cfdSRui Paulo
32032176cfdSRui Paulo /* Mesh Proxy Update Confirmation */
32132176cfdSRui Paulo struct ieee80211_meshpuc_ie {
32232176cfdSRui Paulo uint8_t puc_ie; /* IEEE80211_ELEMID_MESHPUC */
32332176cfdSRui Paulo uint8_t puc_len;
32432176cfdSRui Paulo uint8_t puc_flags;
32532176cfdSRui Paulo uint8_t puc_seq; /* PU Sequence Number */
32632176cfdSRui Paulo uint8_t puc_daddr[IEEE80211_ADDR_LEN];
32732176cfdSRui Paulo } __packed;
32832176cfdSRui Paulo #endif
32932176cfdSRui Paulo
33032176cfdSRui Paulo /*
33132176cfdSRui Paulo * 802.11s Action Frames
332085ff963SMatthew Dillon * XXX: these are wrong, and some of them should be
333085ff963SMatthew Dillon * under MESH category while PROXY is under MULTIHOP category.
33432176cfdSRui Paulo */
33532176cfdSRui Paulo #define IEEE80211_ACTION_CAT_INTERWORK 15
33632176cfdSRui Paulo #define IEEE80211_ACTION_CAT_RESOURCE 16
33732176cfdSRui Paulo #define IEEE80211_ACTION_CAT_PROXY 17
33832176cfdSRui Paulo
33932176cfdSRui Paulo /*
34032176cfdSRui Paulo * Mesh Peering Action codes.
34132176cfdSRui Paulo */
34232176cfdSRui Paulo enum {
343085ff963SMatthew Dillon /* 0 reserved */
344085ff963SMatthew Dillon IEEE80211_ACTION_MESHPEERING_OPEN = 1,
345085ff963SMatthew Dillon IEEE80211_ACTION_MESHPEERING_CONFIRM = 2,
346085ff963SMatthew Dillon IEEE80211_ACTION_MESHPEERING_CLOSE = 3,
347085ff963SMatthew Dillon /* 4-255 reserved */
34832176cfdSRui Paulo };
34932176cfdSRui Paulo
35032176cfdSRui Paulo /*
351085ff963SMatthew Dillon * Mesh Action code.
35232176cfdSRui Paulo */
35332176cfdSRui Paulo enum {
354085ff963SMatthew Dillon IEEE80211_ACTION_MESH_LMETRIC = 0, /* Mesh Link Metric Report */
355085ff963SMatthew Dillon IEEE80211_ACTION_MESH_HWMP = 1, /* HWMP Mesh Path Selection */
356085ff963SMatthew Dillon IEEE80211_ACTION_MESH_GANN = 2, /* Gate Announcement */
357085ff963SMatthew Dillon IEEE80211_ACTION_MESH_CC = 3, /* Congestion Control */
358085ff963SMatthew Dillon IEEE80211_ACTION_MESH_MCCA_SREQ = 4, /* MCCA Setup Request */
359085ff963SMatthew Dillon IEEE80211_ACTION_MESH_MCCA_SREP = 5, /* MCCA Setup Reply */
360085ff963SMatthew Dillon IEEE80211_ACTION_MESH_MCCA_AREQ = 6, /* MCCA Advertisement Req. */
361085ff963SMatthew Dillon IEEE80211_ACTION_MESH_MCCA_ADVER =7, /* MCCA Advertisement */
362085ff963SMatthew Dillon IEEE80211_ACTION_MESH_MCCA_TRDOWN = 8, /* MCCA Teardown */
363085ff963SMatthew Dillon IEEE80211_ACTION_MESH_TBTT_REQ = 9, /* TBTT Adjustment Request */
364085ff963SMatthew Dillon IEEE80211_ACTION_MESH_TBTT_RES = 10, /* TBTT Adjustment Response */
365085ff963SMatthew Dillon /* 11-255 reserved */
36632176cfdSRui Paulo };
36732176cfdSRui Paulo
36832176cfdSRui Paulo /*
36932176cfdSRui Paulo * Different mesh control structures based on the AE
37032176cfdSRui Paulo * (Address Extension) bits.
37132176cfdSRui Paulo */
37232176cfdSRui Paulo struct ieee80211_meshcntl {
37332176cfdSRui Paulo uint8_t mc_flags; /* Address Extension 00 */
37432176cfdSRui Paulo uint8_t mc_ttl; /* TTL */
37532176cfdSRui Paulo uint8_t mc_seq[4]; /* Sequence No. */
37632176cfdSRui Paulo /* NB: more addresses may follow */
37732176cfdSRui Paulo } __packed;
37832176cfdSRui Paulo
37932176cfdSRui Paulo struct ieee80211_meshcntl_ae01 {
38032176cfdSRui Paulo uint8_t mc_flags; /* Address Extension 01 */
38132176cfdSRui Paulo uint8_t mc_ttl; /* TTL */
38232176cfdSRui Paulo uint8_t mc_seq[4]; /* Sequence No. */
38332176cfdSRui Paulo uint8_t mc_addr4[IEEE80211_ADDR_LEN];
38432176cfdSRui Paulo } __packed;
38532176cfdSRui Paulo
38632176cfdSRui Paulo struct ieee80211_meshcntl_ae10 {
38732176cfdSRui Paulo uint8_t mc_flags; /* Address Extension 10 */
38832176cfdSRui Paulo uint8_t mc_ttl; /* TTL */
38932176cfdSRui Paulo uint8_t mc_seq[4]; /* Sequence No. */
39032176cfdSRui Paulo uint8_t mc_addr5[IEEE80211_ADDR_LEN];
39132176cfdSRui Paulo uint8_t mc_addr6[IEEE80211_ADDR_LEN];
39232176cfdSRui Paulo } __packed;
39332176cfdSRui Paulo
394085ff963SMatthew Dillon #define IEEE80211_MESH_AE_MASK 0x03
395085ff963SMatthew Dillon enum {
396085ff963SMatthew Dillon IEEE80211_MESH_AE_00 = 0, /* MC has no AE subfield */
397085ff963SMatthew Dillon IEEE80211_MESH_AE_01 = 1, /* MC contain addr4 */
398085ff963SMatthew Dillon IEEE80211_MESH_AE_10 = 2, /* MC contain addr5 & addr6 */
399085ff963SMatthew Dillon IEEE80211_MESH_AE_11 = 3, /* RESERVED */
400085ff963SMatthew Dillon };
401085ff963SMatthew Dillon
40232176cfdSRui Paulo #ifdef _KERNEL
403*805c8e8eSzrj #ifdef MALLOC_DECLARE
404085ff963SMatthew Dillon MALLOC_DECLARE(M_80211_MESH_PREQ);
405085ff963SMatthew Dillon MALLOC_DECLARE(M_80211_MESH_PREP);
406085ff963SMatthew Dillon MALLOC_DECLARE(M_80211_MESH_PERR);
407085ff963SMatthew Dillon
40832176cfdSRui Paulo MALLOC_DECLARE(M_80211_MESH_RT);
409085ff963SMatthew Dillon MALLOC_DECLARE(M_80211_MESH_GT_RT);
410*805c8e8eSzrj #endif
411085ff963SMatthew Dillon /*
412085ff963SMatthew Dillon * Basic forwarding information:
413085ff963SMatthew Dillon * o Destination MAC
414085ff963SMatthew Dillon * o Next-hop MAC
415085ff963SMatthew Dillon * o Precursor list (not implemented yet)
416085ff963SMatthew Dillon * o Path timeout
417085ff963SMatthew Dillon * The rest is part of the active Mesh path selection protocol.
418085ff963SMatthew Dillon * XXX: to be moved out later.
419085ff963SMatthew Dillon */
42032176cfdSRui Paulo struct ieee80211_mesh_route {
42132176cfdSRui Paulo TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
422085ff963SMatthew Dillon struct ieee80211vap *rt_vap;
423c3bc1bd4SImre Vadász ieee80211_rte_lock_t rt_lock; /* fine grained route lock */
424085ff963SMatthew Dillon struct callout rt_discovery; /* discovery timeout */
425085ff963SMatthew Dillon int rt_updtime; /* last update time */
42632176cfdSRui Paulo uint8_t rt_dest[IEEE80211_ADDR_LEN];
427085ff963SMatthew Dillon uint8_t rt_mesh_gate[IEEE80211_ADDR_LEN]; /* meshDA */
42832176cfdSRui Paulo uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
42932176cfdSRui Paulo uint32_t rt_metric; /* path metric */
43032176cfdSRui Paulo uint16_t rt_nhops; /* number of hops */
43132176cfdSRui Paulo uint16_t rt_flags;
432085ff963SMatthew Dillon #define IEEE80211_MESHRT_FLAGS_DISCOVER 0x01 /* path discovery */
433085ff963SMatthew Dillon #define IEEE80211_MESHRT_FLAGS_VALID 0x02 /* path discovery complete */
434085ff963SMatthew Dillon #define IEEE80211_MESHRT_FLAGS_PROXY 0x04 /* proxy entry */
435085ff963SMatthew Dillon #define IEEE80211_MESHRT_FLAGS_GATE 0x08 /* mesh gate entry */
436085ff963SMatthew Dillon uint32_t rt_lifetime; /* route timeout */
43732176cfdSRui Paulo uint32_t rt_lastmseq; /* last seq# seen dest */
438085ff963SMatthew Dillon uint32_t rt_ext_seq; /* proxy seq number */
43932176cfdSRui Paulo void *rt_priv; /* private data */
44032176cfdSRui Paulo };
44132176cfdSRui Paulo #define IEEE80211_MESH_ROUTE_PRIV(rt, cast) ((cast *)rt->rt_priv)
44232176cfdSRui Paulo
443085ff963SMatthew Dillon /*
444085ff963SMatthew Dillon * Stored information about known mesh gates.
445085ff963SMatthew Dillon */
446085ff963SMatthew Dillon struct ieee80211_mesh_gate_route {
447085ff963SMatthew Dillon TAILQ_ENTRY(ieee80211_mesh_gate_route) gr_next;
448085ff963SMatthew Dillon uint8_t gr_addr[IEEE80211_ADDR_LEN];
449085ff963SMatthew Dillon uint32_t gr_lastseq;
450085ff963SMatthew Dillon struct ieee80211_mesh_route *gr_route;
451085ff963SMatthew Dillon };
452085ff963SMatthew Dillon
45332176cfdSRui Paulo #define IEEE80211_MESH_PROTO_DSZ 12 /* description size */
45432176cfdSRui Paulo /*
45532176cfdSRui Paulo * Mesh Path Selection Protocol.
45632176cfdSRui Paulo */
45732176cfdSRui Paulo enum ieee80211_state;
45832176cfdSRui Paulo struct ieee80211_mesh_proto_path {
45932176cfdSRui Paulo uint8_t mpp_active;
46032176cfdSRui Paulo char mpp_descr[IEEE80211_MESH_PROTO_DSZ];
46132176cfdSRui Paulo uint8_t mpp_ie;
46232176cfdSRui Paulo struct ieee80211_node *
46332176cfdSRui Paulo (*mpp_discover)(struct ieee80211vap *,
46432176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN],
46532176cfdSRui Paulo struct mbuf *);
46632176cfdSRui Paulo void (*mpp_peerdown)(struct ieee80211_node *);
467085ff963SMatthew Dillon void (*mpp_senderror)(struct ieee80211vap *,
468085ff963SMatthew Dillon const uint8_t [IEEE80211_ADDR_LEN],
469085ff963SMatthew Dillon struct ieee80211_mesh_route *, int);
47032176cfdSRui Paulo void (*mpp_vattach)(struct ieee80211vap *);
47132176cfdSRui Paulo void (*mpp_vdetach)(struct ieee80211vap *);
47232176cfdSRui Paulo int (*mpp_newstate)(struct ieee80211vap *,
47332176cfdSRui Paulo enum ieee80211_state, int);
47432176cfdSRui Paulo const size_t mpp_privlen; /* size required in the routing table
47532176cfdSRui Paulo for private data */
47632176cfdSRui Paulo int mpp_inact; /* inact. timeout for invalid routes
47732176cfdSRui Paulo (ticks) */
47832176cfdSRui Paulo };
47932176cfdSRui Paulo
48032176cfdSRui Paulo /*
48132176cfdSRui Paulo * Mesh Link Metric Report Protocol.
48232176cfdSRui Paulo */
48332176cfdSRui Paulo struct ieee80211_mesh_proto_metric {
48432176cfdSRui Paulo uint8_t mpm_active;
48532176cfdSRui Paulo char mpm_descr[IEEE80211_MESH_PROTO_DSZ];
48632176cfdSRui Paulo uint8_t mpm_ie;
48732176cfdSRui Paulo uint32_t (*mpm_metric)(struct ieee80211_node *);
48832176cfdSRui Paulo };
48932176cfdSRui Paulo
49032176cfdSRui Paulo #ifdef notyet
49132176cfdSRui Paulo /*
49232176cfdSRui Paulo * Mesh Authentication Protocol.
49332176cfdSRui Paulo */
49432176cfdSRui Paulo struct ieee80211_mesh_proto_auth {
49532176cfdSRui Paulo uint8_t mpa_ie[4];
49632176cfdSRui Paulo };
49732176cfdSRui Paulo
49832176cfdSRui Paulo struct ieee80211_mesh_proto_congestion {
49932176cfdSRui Paulo };
50032176cfdSRui Paulo
50132176cfdSRui Paulo struct ieee80211_mesh_proto_sync {
50232176cfdSRui Paulo };
50332176cfdSRui Paulo #endif
50432176cfdSRui Paulo
50532176cfdSRui Paulo typedef uint32_t ieee80211_mesh_seq;
50632176cfdSRui Paulo #define IEEE80211_MESH_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0)
50732176cfdSRui Paulo #define IEEE80211_MESH_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
50832176cfdSRui Paulo
50932176cfdSRui Paulo struct ieee80211_mesh_state {
51032176cfdSRui Paulo int ms_idlen;
51132176cfdSRui Paulo uint8_t ms_id[IEEE80211_MESHID_LEN];
51232176cfdSRui Paulo ieee80211_mesh_seq ms_seq; /* seq no for meshcntl */
51332176cfdSRui Paulo uint16_t ms_neighbors;
51432176cfdSRui Paulo uint8_t ms_ttl; /* mesh ttl set in packets */
51532176cfdSRui Paulo #define IEEE80211_MESHFLAGS_AP 0x01 /* accept peers */
516085ff963SMatthew Dillon #define IEEE80211_MESHFLAGS_GATE 0x02 /* mesh gate role */
51732176cfdSRui Paulo #define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
518085ff963SMatthew Dillon #define IEEE80211_MESHFLAGS_ROOT 0x08 /* configured as root */
51932176cfdSRui Paulo uint8_t ms_flags;
520c3bc1bd4SImre Vadász ieee80211_rt_lock_t ms_rt_lock;
52132176cfdSRui Paulo struct callout ms_cleantimer;
522085ff963SMatthew Dillon struct callout ms_gatetimer;
523085ff963SMatthew Dillon ieee80211_mesh_seq ms_gateseq;
524085ff963SMatthew Dillon TAILQ_HEAD(, ieee80211_mesh_gate_route) ms_known_gates;
52532176cfdSRui Paulo TAILQ_HEAD(, ieee80211_mesh_route) ms_routes;
52632176cfdSRui Paulo struct ieee80211_mesh_proto_metric *ms_pmetric;
52732176cfdSRui Paulo struct ieee80211_mesh_proto_path *ms_ppath;
52832176cfdSRui Paulo };
52932176cfdSRui Paulo void ieee80211_mesh_attach(struct ieee80211com *);
53032176cfdSRui Paulo void ieee80211_mesh_detach(struct ieee80211com *);
53132176cfdSRui Paulo
53232176cfdSRui Paulo struct ieee80211_mesh_route *
53332176cfdSRui Paulo ieee80211_mesh_rt_find(struct ieee80211vap *,
53432176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN]);
53532176cfdSRui Paulo struct ieee80211_mesh_route *
53632176cfdSRui Paulo ieee80211_mesh_rt_add(struct ieee80211vap *,
53732176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN]);
53832176cfdSRui Paulo void ieee80211_mesh_rt_del(struct ieee80211vap *,
53932176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN]);
54032176cfdSRui Paulo void ieee80211_mesh_rt_flush(struct ieee80211vap *);
54132176cfdSRui Paulo void ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
54232176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN]);
543085ff963SMatthew Dillon int ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int);
54432176cfdSRui Paulo void ieee80211_mesh_proxy_check(struct ieee80211vap *,
54532176cfdSRui Paulo const uint8_t [IEEE80211_ADDR_LEN]);
54632176cfdSRui Paulo
54732176cfdSRui Paulo int ieee80211_mesh_register_proto_path(const
54832176cfdSRui Paulo struct ieee80211_mesh_proto_path *);
54932176cfdSRui Paulo int ieee80211_mesh_register_proto_metric(const
55032176cfdSRui Paulo struct ieee80211_mesh_proto_metric *);
55132176cfdSRui Paulo
55232176cfdSRui Paulo uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
55332176cfdSRui Paulo uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
55432176cfdSRui Paulo uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
55532176cfdSRui Paulo uint16_t);
556085ff963SMatthew Dillon uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint8_t, uint32_t);
557085ff963SMatthew Dillon uint8_t * ieee80211_add_meshgate(uint8_t *,
558085ff963SMatthew Dillon struct ieee80211_meshgann_ie *);
55932176cfdSRui Paulo
56032176cfdSRui Paulo void ieee80211_mesh_node_init(struct ieee80211vap *,
56132176cfdSRui Paulo struct ieee80211_node *);
56232176cfdSRui Paulo void ieee80211_mesh_node_cleanup(struct ieee80211_node *);
56332176cfdSRui Paulo void ieee80211_parse_meshid(struct ieee80211_node *,
56432176cfdSRui Paulo const uint8_t *);
56532176cfdSRui Paulo struct ieee80211_scanparams;
56632176cfdSRui Paulo void ieee80211_mesh_init_neighbor(struct ieee80211_node *,
56732176cfdSRui Paulo const struct ieee80211_frame *,
56832176cfdSRui Paulo const struct ieee80211_scanparams *);
56932176cfdSRui Paulo void ieee80211_mesh_update_beacon(struct ieee80211vap *,
57032176cfdSRui Paulo struct ieee80211_beacon_offsets *);
571085ff963SMatthew Dillon struct ieee80211_mesh_gate_route *
572085ff963SMatthew Dillon ieee80211_mesh_mark_gate(struct ieee80211vap *,
573085ff963SMatthew Dillon const uint8_t *, struct ieee80211_mesh_route *);
574085ff963SMatthew Dillon void ieee80211_mesh_forward_to_gates(struct ieee80211vap *,
575085ff963SMatthew Dillon struct ieee80211_mesh_route *);
576085ff963SMatthew Dillon struct ieee80211_node *
577085ff963SMatthew Dillon ieee80211_mesh_find_txnode(struct ieee80211vap *,
578085ff963SMatthew Dillon const uint8_t [IEEE80211_ADDR_LEN]);
57932176cfdSRui Paulo
58032176cfdSRui Paulo /*
58132176cfdSRui Paulo * Return non-zero if proxy operation is enabled.
58232176cfdSRui Paulo */
58332176cfdSRui Paulo static __inline int
ieee80211_mesh_isproxyena(struct ieee80211vap * vap)58432176cfdSRui Paulo ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
58532176cfdSRui Paulo {
58632176cfdSRui Paulo struct ieee80211_mesh_state *ms = vap->iv_mesh;
58732176cfdSRui Paulo return (ms->ms_flags &
588085ff963SMatthew Dillon (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_GATE)) != 0;
58932176cfdSRui Paulo }
59032176cfdSRui Paulo
59132176cfdSRui Paulo /*
59232176cfdSRui Paulo * Process an outbound frame: if a path is known to the
59332176cfdSRui Paulo * destination then return a reference to the next hop
59432176cfdSRui Paulo * for immediate transmission. Otherwise initiate path
59532176cfdSRui Paulo * discovery and, if possible queue the packet to be
59632176cfdSRui Paulo * sent when path discovery completes.
59732176cfdSRui Paulo */
59832176cfdSRui Paulo static __inline struct ieee80211_node *
ieee80211_mesh_discover(struct ieee80211vap * vap,const uint8_t dest[IEEE80211_ADDR_LEN],struct mbuf * m)59932176cfdSRui Paulo ieee80211_mesh_discover(struct ieee80211vap *vap,
60032176cfdSRui Paulo const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
60132176cfdSRui Paulo {
60232176cfdSRui Paulo struct ieee80211_mesh_state *ms = vap->iv_mesh;
60332176cfdSRui Paulo return ms->ms_ppath->mpp_discover(vap, dest, m);
60432176cfdSRui Paulo }
60532176cfdSRui Paulo
60632176cfdSRui Paulo #endif /* _KERNEL */
60732176cfdSRui Paulo #endif /* !_NET80211_IEEE80211_MESH_H_ */
608