2 * Copyright (c) 2009 The FreeBSD Foundation
5 * This software was developed by Rui Paulo under sponsorship from the
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 #ifndef _NET80211_IEEE80211_MESH_H_
32 #define _NET80211_IEEE80211_MESH_H_
34 #define IEEE80211_MESH_DEFAULT_TTL 31
37 * NB: all structures are__packed so sizeof works on arm, et. al.
40 * 802.11s Information Elements.
42 /* Mesh Configuration */
43 struct ieee80211_meshconf_ie {
44 uint8_t conf_ie; /* IEEE80211_ELEMID_MESHCONF */
47 uint8_t conf_pselid[4]; /* Active Path Sel. Proto. ID */
48 uint8_t conf_pmetid[4]; /* APS Metric Identifier */
49 uint8_t conf_ccid[4]; /* Congestion Control Mode ID */
50 uint8_t conf_syncid[4]; /* Sync. Protocol ID */
51 uint8_t conf_authid[4]; /* Auth. Protocol ID */
52 uint8_t conf_form; /* Formation Information */
56 #define IEEE80211_MESHCONF_VERSION 1
58 #define IEEE80211_MESHCONF_NULL_OUI 0x00, 0x0f, 0xac
59 #define IEEE80211_MESHCONF_NULL_VALUE 0xff
60 #define IEEE80211_MESHCONF_NULL { IEEE80211_MESHCONF_NULL_OUI, \
61 IEEE80211_MESHCONF_NULL_VALUE }
62 /* Hybrid Wireless Mesh Protocol */
63 #define IEEE80211_MESHCONF_HWMP_OUI 0x00, 0x0f, 0xac
64 #define IEEE80211_MESHCONF_HWMP_VALUE 0x00
65 #define IEEE80211_MESHCONF_HWMP { IEEE80211_MESHCONF_HWMP_OUI, \
66 IEEE80211_MESHCONF_HWMP_VALUE }
67 /* Airtime Link Metric */
68 #define IEEE80211_MESHCONF_AIRTIME_OUI 0x00, 0x0f, 0xac
69 #define IEEE80211_MESHCONF_AIRTIME_VALUE 0x00
70 #define IEEE80211_MESHCONF_AIRTIME { IEEE80211_MESHCONF_AIRTIME_OUI, \
71 IEEE80211_MESHCONF_AIRTIME_VALUE }
72 /* Congestion Control Signaling */
73 #define IEEE80211_MESHCONF_CCSIG_OUI 0x00, 0x0f, 0xac
74 #define IEEE80211_MESHCONF_CCSIG_VALUE 0x00
75 #define IEEE80211_MESHCONF_CCSIG { IEEE80211_MESHCONF_CCSIG_OUI,\
76 IEEE80211_MESHCONF_CCSIG_VALUE }
77 /* Neighbour Offset */
78 #define IEEE80211_MESHCONF_NEIGHOFF_OUI 0x00, 0x0f, 0xac
79 #define IEEE80211_MESHCONF_NEIGHOFF_VALUE 0x00
80 #define IEEE80211_MESHCONF_NEIGHOFF { IEEE80211_MESHCONF_NEIGHOFF_OUI, \
81 IEEE80211_MESHCONF_NEIGHOFF_VALUE }
82 /* Simultaneous Authenticaction of Equals */
83 #define IEEE80211_MESHCONF_SAE_OUI 0x00, 0x0f, 0xac
84 #define IEEE80211_MESHCONF_SAE_VALUE 0x01
85 #define IEEE80211_MESHCONF_SAE { IEEE80211_MESHCONF_SAE_OUI, \
86 IEEE80211_MESHCONF_SAE_VALUE }
87 #define IEEE80211_MESHCONF_FORM_MP 0x01 /* Connected to Portal */
88 #define IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x04 /* Number of Neighbours */
89 #define IEEE80211_MESHCONF_CAP_AP 0x01 /* Accepting Peers */
90 #define IEEE80211_MESHCONF_CAP_MCCAS 0x02 /* MCCA supported */
91 #define IEEE80211_MESHCONF_CAP_MCCAE 0x04 /* MCCA enabled */
92 #define IEEE80211_MESHCONF_CAP_FWRD 0x08 /* forwarding enabled */
93 #define IEEE80211_MESHCONF_CAP_BTR 0x10 /* Beacon Timing Report Enab */
94 #define IEEE80211_MESHCONF_CAP_TBTTA 0x20 /* TBTT Adj. Enabled */
95 #define IEEE80211_MESHCONF_CAP_PSL 0x40 /* Power Save Level */
98 struct ieee80211_meshid_ie {
99 uint8_t id_ie; /* IEEE80211_ELEMID_MESHID */
103 /* Link Metric Report */
104 struct ieee80211_meshlmetric_ie {
105 uint8_t lm_ie; /* IEEE80211_ELEMID_MESHLINK */
108 #define IEEE80211_MESHLMETRIC_INITIALVAL 0
111 /* Congestion Notification */
112 struct ieee80211_meshcngst_ie {
113 uint8_t cngst_ie; /* IEEE80211_ELEMID_MESHCNGST */
115 uint16_t cngst_timer[4]; /* Expiration Timers: AC_BK,
116 AC_BE, AC_VI, AC_VO */
120 struct ieee80211_meshpeerver_ie {
121 uint8_t peerver_ie; /* IEEE80211_ELEMID_MESHPEERVER */
123 uint8_t peerver_proto[4];
125 /* Mesh Peering Management Protocol */
126 #define IEEE80211_MESHPEERVER_PEER_OUI 0x00, 0x0f, 0xac
127 #define IEEE80211_MESHPEERVER_PEER_VALUE 0x2a
128 #define IEEE80211_MESHPEERVER_PEER { IEEE80211_MESHPEERVER_PEER_OUI, \
129 IEEE80211_MESHPEERVER_PEER_VALUE }
130 /* Abbreviated Handshake Protocol */
131 #define IEEE80211_MESHPEERVER_AH_OUI 0x00, 0x0f, 0xac
132 #define IEEE80211_MESHPEERVER_AH_VALUE 0x2b
133 #define IEEE80211_MESHPEERVER_AH { IEEE80211_MESHPEERVER_AH_OUI, \
134 IEEE80211_MESHPEERVER_AH_VALUE }
136 /* Peer Link Management */
137 struct ieee80211_meshpeer_ie {
138 uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
140 uint8_t peer_subtype;
141 uint16_t peer_llinkid; /* Local Link ID */
142 uint16_t peer_linkid; /* Peer Link ID */
147 IEEE80211_MESH_PEER_LINK_OPEN = 0,
148 IEEE80211_MESH_PEER_LINK_CONFIRM = 1,
149 IEEE80211_MESH_PEER_LINK_CLOSE = 2,
150 /* values 3-255 are reserved */
154 /* Mesh Channel Switch Annoucement */
155 struct ieee80211_meshcsa_ie {
156 uint8_t csa_ie; /* IEEE80211_ELEMID_MESHCSA */
159 uint8_t csa_newclass; /* New Regulatory Class */
161 uint8_t csa_precvalue; /* Precedence Value */
166 /* Equal to the non Mesh version */
168 /* Mesh Awake Window */
169 struct ieee80211_meshawakew_ie {
170 uint8_t awakew_ie; /* IEEE80211_ELEMID_MESHAWAKEW */
172 uint8_t awakew_windowlen; /* in TUs */
175 /* Mesh Beacon Timing */
176 struct ieee80211_meshbeacont_ie {
177 uint8_t beacont_ie; /* IEEE80211_ELEMID_MESHBEACONT */
180 uint8_t mp_aid; /* Least Octet of AID */
181 uint16_t mp_btime; /* Beacon Time */
182 uint16_t mp_bint; /* Beacon Interval */
183 } __packed mp[1]; /* NB: variable size */
187 /* Portal (MP) Annoucement */
188 struct ieee80211_meshpann_ie {
189 uint8_t pann_ie; /* IEEE80211_ELEMID_MESHPANN */
192 uint8_t pann_hopcount;
194 uint8_t pann_addr[IEEE80211_ADDR_LEN];
195 uint8_t pann_seq; /* PANN Sequence Number */
198 /* Root (MP) Annoucement */
199 struct ieee80211_meshrann_ie {
200 uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */
203 #define IEEE80211_MESHRANN_FLAGS_PR 0x01 /* Portal Role */
204 uint8_t rann_hopcount;
206 uint8_t rann_addr[IEEE80211_ADDR_LEN];
207 uint32_t rann_seq; /* HWMP Sequence Number */
208 uint32_t rann_metric;
211 /* Mesh Path Request */
212 struct ieee80211_meshpreq_ie {
213 uint8_t preq_ie; /* IEEE80211_ELEMID_MESHPREQ */
216 #define IEEE80211_MESHPREQ_FLAGS_PR 0x01 /* Portal Role */
217 #define IEEE80211_MESHPREQ_FLAGS_AM 0x02 /* 0 = ucast / 1 = bcast */
218 #define IEEE80211_MESHPREQ_FLAGS_PP 0x04 /* Proactive PREP */
219 #define IEEE80211_MESHPREQ_FLAGS_AE 0x40 /* Address Extension */
220 uint8_t preq_hopcount;
223 uint8_t preq_origaddr[IEEE80211_ADDR_LEN];
224 uint32_t preq_origseq; /* HWMP Sequence Number */
225 /* NB: may have Originator Proxied Address */
226 uint32_t preq_lifetime;
227 uint32_t preq_metric;
228 uint8_t preq_tcount; /* target count */
230 uint8_t target_flags;
231 #define IEEE80211_MESHPREQ_TFLAGS_TO 0x01 /* Target Only */
232 #define IEEE80211_MESHPREQ_TFLAGS_RF 0x02 /* Reply and Forward */
233 #define IEEE80211_MESHPREQ_TFLAGS_USN 0x04 /* Unknown HWMP seq number */
234 uint8_t target_addr[IEEE80211_ADDR_LEN];
235 uint32_t target_seq; /* HWMP Sequence Number */
236 } __packed preq_targets[1]; /* NB: variable size */
239 /* Mesh Path Reply */
240 struct ieee80211_meshprep_ie {
241 uint8_t prep_ie; /* IEEE80211_ELEMID_MESHPREP */
244 uint8_t prep_hopcount;
246 uint8_t prep_targetaddr[IEEE80211_ADDR_LEN];
247 uint32_t prep_targetseq;
248 /* NB: May have Target Proxied Address */
249 uint32_t prep_lifetime;
250 uint32_t prep_metric;
251 uint8_t prep_origaddr[IEEE80211_ADDR_LEN];
252 uint32_t prep_origseq; /* HWMP Sequence Number */
255 /* Mesh Path Error */
256 struct ieee80211_meshperr_ie {
257 uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */
259 uint8_t perr_mode; /* NB: reserved */
260 uint8_t perr_ndests; /* Number of Destinations */
262 uint8_t dest_addr[IEEE80211_ADDR_LEN];
263 uint32_t dest_seq; /* HWMP Sequence Number */
264 } __packed perr_dests[1]; /* NB: variable size */
268 /* Mesh Proxy Update */
269 struct ieee80211_meshpu_ie {
270 uint8_t pu_ie; /* IEEE80211_ELEMID_MESHPU */
273 #define IEEE80211_MESHPU_FLAGS_MASK 0x1
274 #define IEEE80211_MESHPU_FLAGS_DEL 0x0
275 #define IEEE80211_MESHPU_FLAGS_ADD 0x1
276 uint8_t pu_seq; /* PU Sequence Number */
277 uint8_t pu_addr[IEEE80211_ADDR_LEN];
278 uint8_t pu_naddr; /* Number of Proxied Addresses */
279 /* NB: proxied address follows */
282 /* Mesh Proxy Update Confirmation */
283 struct ieee80211_meshpuc_ie {
284 uint8_t puc_ie; /* IEEE80211_ELEMID_MESHPUC */
287 uint8_t puc_seq; /* PU Sequence Number */
288 uint8_t puc_daddr[IEEE80211_ADDR_LEN];
293 * 802.11s Action Frames
295 #define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */
296 #define IEEE80211_ACTION_CAT_MESHLMETRIC 13
297 #define IEEE80211_ACTION_CAT_MESHPATH 32 /* XXX Linux */
298 #define IEEE80211_ACTION_CAT_INTERWORK 15
299 #define IEEE80211_ACTION_CAT_RESOURCE 16
300 #define IEEE80211_ACTION_CAT_PROXY 17
303 * Mesh Peering Action codes.
306 IEEE80211_ACTION_MESHPEERING_OPEN = 0,
307 IEEE80211_ACTION_MESHPEERING_CONFIRM = 1,
308 IEEE80211_ACTION_MESHPEERING_CLOSE = 2,
313 * Mesh Path Selection Action codes.
316 IEEE80211_ACTION_MESHPATH_REQ = 0,
317 IEEE80211_ACTION_MESHPATH_REP = 1,
318 IEEE80211_ACTION_MESHPATH_ERR = 2,
319 IEEE80211_ACTION_MESHPATH_RANN = 3,
324 * Mesh Link Metric Action codes.
327 IEEE80211_ACTION_MESHLMETRIC_REQ = 0, /* Link Metric Request */
328 IEEE80211_ACTION_MESHLMETRIC_REP = 1, /* Link Metric Report */
333 * Mesh Portal Annoucement Action codes.
336 IEEE80211_ACTION_MESHPANN = 0,
341 * Different mesh control structures based on the AE
342 * (Address Extension) bits.
344 struct ieee80211_meshcntl {
345 uint8_t mc_flags; /* Address Extension 00 */
346 uint8_t mc_ttl; /* TTL */
347 uint8_t mc_seq[4]; /* Sequence No. */
348 /* NB: more addresses may follow */
351 struct ieee80211_meshcntl_ae01 {
352 uint8_t mc_flags; /* Address Extension 01 */
353 uint8_t mc_ttl; /* TTL */
354 uint8_t mc_seq[4]; /* Sequence No. */
355 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
358 struct ieee80211_meshcntl_ae10 {
359 uint8_t mc_flags; /* Address Extension 10 */
360 uint8_t mc_ttl; /* TTL */
361 uint8_t mc_seq[4]; /* Sequence No. */
362 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
363 uint8_t mc_addr5[IEEE80211_ADDR_LEN];
366 struct ieee80211_meshcntl_ae11 {
367 uint8_t mc_flags; /* Address Extension 11 */
368 uint8_t mc_ttl; /* TTL */
369 uint8_t mc_seq[4]; /* Sequence No. */
370 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
371 uint8_t mc_addr5[IEEE80211_ADDR_LEN];
372 uint8_t mc_addr6[IEEE80211_ADDR_LEN];
376 MALLOC_DECLARE(M_80211_MESH_RT);
377 struct ieee80211_mesh_route {
378 TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
379 int rt_crtime; /* creation time */
380 uint8_t rt_dest[IEEE80211_ADDR_LEN];
381 uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
382 uint32_t rt_metric; /* path metric */
383 uint16_t rt_nhops; /* number of hops */
385 #define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* patch discovery complete */
386 #define IEEE80211_MESHRT_FLAGS_PROXY 0x02 /* proxy entry */
387 uint32_t rt_lifetime;
388 uint32_t rt_lastmseq; /* last seq# seen dest */
389 void *rt_priv; /* private data */
391 #define IEEE80211_MESH_ROUTE_PRIV(rt, cast) ((cast *)rt->rt_priv)
393 #define IEEE80211_MESH_PROTO_DSZ 12 /* description size */
395 * Mesh Path Selection Protocol.
397 enum ieee80211_state;
398 struct ieee80211_mesh_proto_path {
399 char mpp_descr[IEEE80211_MESH_PROTO_DSZ];
401 struct ieee80211_node *
402 (*mpp_discover)(struct ieee80211vap *,
403 const uint8_t [IEEE80211_ADDR_LEN],
405 void (*mpp_peerdown)(struct ieee80211_node *);
406 void (*mpp_vattach)(struct ieee80211vap *);
407 void (*mpp_vdetach)(struct ieee80211vap *);
408 int (*mpp_newstate)(struct ieee80211vap *,
409 enum ieee80211_state, int);
410 const size_t mpp_privlen; /* size required in the routing table
412 int mpp_inact; /* inact. timeout for invalid routes
417 * Mesh Link Metric Report Protocol.
419 struct ieee80211_mesh_proto_metric {
420 char mpm_descr[IEEE80211_MESH_PROTO_DSZ];
422 uint32_t (*mpm_metric)(struct ieee80211_node *);
427 * Mesh Authentication Protocol.
429 struct ieee80211_mesh_proto_auth {
433 struct ieee80211_mesh_proto_congestion {
436 struct ieee80211_mesh_proto_sync {
440 typedef uint32_t ieee80211_mesh_seq;
441 #define IEEE80211_MESH_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0)
442 #define IEEE80211_MESH_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
444 struct ieee80211_mesh_state {
446 uint8_t ms_id[IEEE80211_MESHID_LEN];
447 ieee80211_mesh_seq ms_seq; /* seq no for meshcntl */
448 uint16_t ms_neighbors;
449 uint8_t ms_ttl; /* mesh ttl set in packets */
450 #define IEEE80211_MESHFLAGS_AP 0x01 /* accept peers */
451 #define IEEE80211_MESHFLAGS_PORTAL 0x02 /* mesh portal role */
452 #define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
454 struct mtx ms_rt_lock;
455 struct callout ms_cleantimer;
456 TAILQ_HEAD(, ieee80211_mesh_route) ms_routes;
457 struct ieee80211_mesh_proto_metric *ms_pmetric;
458 struct ieee80211_mesh_proto_path *ms_ppath;
460 void ieee80211_mesh_attach(struct ieee80211com *);
461 void ieee80211_mesh_detach(struct ieee80211com *);
463 struct ieee80211_mesh_route *
464 ieee80211_mesh_rt_find(struct ieee80211vap *,
465 const uint8_t [IEEE80211_ADDR_LEN]);
466 struct ieee80211_mesh_route *
467 ieee80211_mesh_rt_add(struct ieee80211vap *,
468 const uint8_t [IEEE80211_ADDR_LEN]);
469 void ieee80211_mesh_rt_del(struct ieee80211vap *,
470 const uint8_t [IEEE80211_ADDR_LEN]);
471 void ieee80211_mesh_rt_flush(struct ieee80211vap *);
472 void ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
473 const uint8_t [IEEE80211_ADDR_LEN]);
474 void ieee80211_mesh_proxy_check(struct ieee80211vap *,
475 const uint8_t [IEEE80211_ADDR_LEN]);
477 int ieee80211_mesh_register_proto_path(const
478 struct ieee80211_mesh_proto_path *);
479 int ieee80211_mesh_register_proto_metric(const
480 struct ieee80211_mesh_proto_metric *);
482 uint8_t * ieee80211_add_meshpeerver(uint8_t *, struct ieee80211vap *);
483 uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
484 uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
485 uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
487 uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint32_t);
489 void ieee80211_mesh_node_init(struct ieee80211vap *,
490 struct ieee80211_node *);
491 void ieee80211_mesh_node_cleanup(struct ieee80211_node *);
492 void ieee80211_parse_meshid(struct ieee80211_node *,
494 struct ieee80211_scanparams;
495 void ieee80211_mesh_init_neighbor(struct ieee80211_node *,
496 const struct ieee80211_frame *,
497 const struct ieee80211_scanparams *);
500 * Return non-zero if proxy operation is enabled.
503 ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
505 struct ieee80211_mesh_state *ms = vap->iv_mesh;
506 return (ms->ms_flags &
507 (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_PORTAL)) != 0;
511 * Process an outbound frame: if a path is known to the
512 * destination then return a reference to the next hop
513 * for immediate transmission. Otherwise initiate path
514 * discovery and, if possible queue the packet to be
515 * sent when path discovery completes.
517 static __inline struct ieee80211_node *
518 ieee80211_mesh_discover(struct ieee80211vap *vap,
519 const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
521 struct ieee80211_mesh_state *ms = vap->iv_mesh;
522 return ms->ms_ppath->mpp_discover(vap, dest, m);
526 #endif /* !_NET80211_IEEE80211_MESH_H_ */