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 */
119 /* Peer Link Management */
120 struct ieee80211_meshpeer_ie {
121 uint8_t peer_ie; /* IEEE80211_ELEMID_MESHPEER */
123 uint8_t peer_proto[4]; /* Peer Management Protocol */
124 uint16_t peer_llinkid; /* Local Link ID */
125 uint16_t peer_linkid; /* Peer Link ID */
130 IEEE80211_MESH_PEER_LINK_OPEN = 0,
131 IEEE80211_MESH_PEER_LINK_CONFIRM = 1,
132 IEEE80211_MESH_PEER_LINK_CLOSE = 2,
133 /* values 3-255 are reserved */
136 /* Mesh Peering Management Protocol */
137 #define IEEE80211_MESH_PEER_PROTO_OUI 0x00, 0x0f, 0xac
138 #define IEEE80211_MESH_PEER_PROTO_VALUE 0x2a
139 #define IEEE80211_MESH_PEER_PROTO { IEEE80211_MESH_PEER_PROTO_OUI, \
140 IEEE80211_MESH_PEER_PROTO_VALUE }
141 /* Abbreviated Handshake Protocol */
142 #define IEEE80211_MESH_PEER_PROTO_AH_OUI 0x00, 0x0f, 0xac
143 #define IEEE80211_MESH_PEER_PROTO_AH_VALUE 0x2b
144 #define IEEE80211_MESH_PEER_PROTO_AH { IEEE80211_MESH_PEER_PROTO_AH_OUI, \
145 IEEE80211_MESH_PEER_PROTO_AH_VALUE }
147 /* Mesh Channel Switch Annoucement */
148 struct ieee80211_meshcsa_ie {
149 uint8_t csa_ie; /* IEEE80211_ELEMID_MESHCSA */
152 uint8_t csa_newclass; /* New Regulatory Class */
154 uint8_t csa_precvalue; /* Precedence Value */
159 /* Equal to the non Mesh version */
161 /* Mesh Awake Window */
162 struct ieee80211_meshawakew_ie {
163 uint8_t awakew_ie; /* IEEE80211_ELEMID_MESHAWAKEW */
165 uint8_t awakew_windowlen; /* in TUs */
168 /* Mesh Beacon Timing */
169 struct ieee80211_meshbeacont_ie {
170 uint8_t beacont_ie; /* IEEE80211_ELEMID_MESHBEACONT */
173 uint8_t mp_aid; /* Least Octet of AID */
174 uint16_t mp_btime; /* Beacon Time */
175 uint16_t mp_bint; /* Beacon Interval */
176 } __packed mp[1]; /* NB: variable size */
180 /* Portal (MP) Annoucement */
181 struct ieee80211_meshpann_ie {
182 uint8_t pann_ie; /* IEEE80211_ELEMID_MESHPANN */
185 uint8_t pann_hopcount;
187 uint8_t pann_addr[IEEE80211_ADDR_LEN];
188 uint8_t pann_seq; /* PANN Sequence Number */
191 /* Root (MP) Annoucement */
192 struct ieee80211_meshrann_ie {
193 uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */
196 #define IEEE80211_MESHRANN_FLAGS_PR 0x01 /* Portal Role */
197 uint8_t rann_hopcount;
199 uint8_t rann_addr[IEEE80211_ADDR_LEN];
200 uint32_t rann_seq; /* HWMP Sequence Number */
201 uint32_t rann_metric;
204 /* Mesh Path Request */
205 struct ieee80211_meshpreq_ie {
206 uint8_t preq_ie; /* IEEE80211_ELEMID_MESHPREQ */
209 #define IEEE80211_MESHPREQ_FLAGS_PR 0x01 /* Portal Role */
210 #define IEEE80211_MESHPREQ_FLAGS_AM 0x02 /* 0 = ucast / 1 = bcast */
211 #define IEEE80211_MESHPREQ_FLAGS_PP 0x04 /* Proactive PREP */
212 #define IEEE80211_MESHPREQ_FLAGS_AE 0x40 /* Address Extension */
213 uint8_t preq_hopcount;
216 uint8_t preq_origaddr[IEEE80211_ADDR_LEN];
217 uint32_t preq_origseq; /* HWMP Sequence Number */
218 /* NB: may have Originator Proxied Address */
219 uint32_t preq_lifetime;
220 uint32_t preq_metric;
221 uint8_t preq_tcount; /* target count */
223 uint8_t target_flags;
224 #define IEEE80211_MESHPREQ_TFLAGS_TO 0x01 /* Target Only */
225 #define IEEE80211_MESHPREQ_TFLAGS_RF 0x02 /* Reply and Forward */
226 #define IEEE80211_MESHPREQ_TFLAGS_USN 0x04 /* Unknown HWMP seq number */
227 uint8_t target_addr[IEEE80211_ADDR_LEN];
228 uint32_t target_seq; /* HWMP Sequence Number */
229 } __packed preq_targets[1]; /* NB: variable size */
232 /* Mesh Path Reply */
233 struct ieee80211_meshprep_ie {
234 uint8_t prep_ie; /* IEEE80211_ELEMID_MESHPREP */
237 uint8_t prep_hopcount;
239 uint8_t prep_targetaddr[IEEE80211_ADDR_LEN];
240 uint32_t prep_targetseq;
241 /* NB: May have Target Proxied Address */
242 uint32_t prep_lifetime;
243 uint32_t prep_metric;
244 uint8_t prep_origaddr[IEEE80211_ADDR_LEN];
245 uint32_t prep_origseq; /* HWMP Sequence Number */
248 /* Mesh Path Error */
249 struct ieee80211_meshperr_ie {
250 uint8_t perr_ie; /* IEEE80211_ELEMID_MESHPERR */
253 uint8_t perr_ndests; /* Number of Destinations */
256 #define IEEE80211_MESHPERR_DFLAGS_USN 0x01
257 #define IEEE80211_MESHPERR_DFLAGS_RC 0x02
258 uint8_t dest_addr[IEEE80211_ADDR_LEN];
259 uint32_t dest_seq; /* HWMP Sequence Number */
261 } __packed perr_dests[1]; /* NB: variable size */
265 /* Mesh Proxy Update */
266 struct ieee80211_meshpu_ie {
267 uint8_t pu_ie; /* IEEE80211_ELEMID_MESHPU */
270 #define IEEE80211_MESHPU_FLAGS_MASK 0x1
271 #define IEEE80211_MESHPU_FLAGS_DEL 0x0
272 #define IEEE80211_MESHPU_FLAGS_ADD 0x1
273 uint8_t pu_seq; /* PU Sequence Number */
274 uint8_t pu_addr[IEEE80211_ADDR_LEN];
275 uint8_t pu_naddr; /* Number of Proxied Addresses */
276 /* NB: proxied address follows */
279 /* Mesh Proxy Update Confirmation */
280 struct ieee80211_meshpuc_ie {
281 uint8_t puc_ie; /* IEEE80211_ELEMID_MESHPUC */
284 uint8_t puc_seq; /* PU Sequence Number */
285 uint8_t puc_daddr[IEEE80211_ADDR_LEN];
290 * 802.11s Action Frames
292 #define IEEE80211_ACTION_CAT_MESHPEERING 30 /* XXX Linux */
293 #define IEEE80211_ACTION_CAT_MESHLMETRIC 13
294 #define IEEE80211_ACTION_CAT_MESHPATH 32 /* XXX Linux */
295 #define IEEE80211_ACTION_CAT_INTERWORK 15
296 #define IEEE80211_ACTION_CAT_RESOURCE 16
297 #define IEEE80211_ACTION_CAT_PROXY 17
300 * Mesh Peering Action codes.
303 IEEE80211_ACTION_MESHPEERING_OPEN = 0,
304 IEEE80211_ACTION_MESHPEERING_CONFIRM = 1,
305 IEEE80211_ACTION_MESHPEERING_CLOSE = 2,
310 * Mesh Path Selection Action code.
313 IEEE80211_ACTION_MESHPATH_SEL = 0,
318 * Mesh Link Metric Action codes.
321 IEEE80211_ACTION_MESHLMETRIC_REQ = 0, /* Link Metric Request */
322 IEEE80211_ACTION_MESHLMETRIC_REP = 1, /* Link Metric Report */
327 * Mesh Portal Annoucement Action codes.
330 IEEE80211_ACTION_MESHPANN = 0,
335 * Different mesh control structures based on the AE
336 * (Address Extension) bits.
338 struct ieee80211_meshcntl {
339 uint8_t mc_flags; /* Address Extension 00 */
340 uint8_t mc_ttl; /* TTL */
341 uint8_t mc_seq[4]; /* Sequence No. */
342 /* NB: more addresses may follow */
345 struct ieee80211_meshcntl_ae01 {
346 uint8_t mc_flags; /* Address Extension 01 */
347 uint8_t mc_ttl; /* TTL */
348 uint8_t mc_seq[4]; /* Sequence No. */
349 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
352 struct ieee80211_meshcntl_ae10 {
353 uint8_t mc_flags; /* Address Extension 10 */
354 uint8_t mc_ttl; /* TTL */
355 uint8_t mc_seq[4]; /* Sequence No. */
356 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
357 uint8_t mc_addr5[IEEE80211_ADDR_LEN];
360 struct ieee80211_meshcntl_ae11 {
361 uint8_t mc_flags; /* Address Extension 11 */
362 uint8_t mc_ttl; /* TTL */
363 uint8_t mc_seq[4]; /* Sequence No. */
364 uint8_t mc_addr4[IEEE80211_ADDR_LEN];
365 uint8_t mc_addr5[IEEE80211_ADDR_LEN];
366 uint8_t mc_addr6[IEEE80211_ADDR_LEN];
370 MALLOC_DECLARE(M_80211_MESH_RT);
371 struct ieee80211_mesh_route {
372 TAILQ_ENTRY(ieee80211_mesh_route) rt_next;
373 int rt_crtime; /* creation time */
374 uint8_t rt_dest[IEEE80211_ADDR_LEN];
375 uint8_t rt_nexthop[IEEE80211_ADDR_LEN];
376 uint32_t rt_metric; /* path metric */
377 uint16_t rt_nhops; /* number of hops */
379 #define IEEE80211_MESHRT_FLAGS_VALID 0x01 /* patch discovery complete */
380 #define IEEE80211_MESHRT_FLAGS_PROXY 0x02 /* proxy entry */
381 uint32_t rt_lifetime;
382 uint32_t rt_lastmseq; /* last seq# seen dest */
383 void *rt_priv; /* private data */
385 #define IEEE80211_MESH_ROUTE_PRIV(rt, cast) ((cast *)rt->rt_priv)
387 #define IEEE80211_MESH_PROTO_DSZ 12 /* description size */
389 * Mesh Path Selection Protocol.
391 enum ieee80211_state;
392 struct ieee80211_mesh_proto_path {
393 char mpp_descr[IEEE80211_MESH_PROTO_DSZ];
395 struct ieee80211_node *
396 (*mpp_discover)(struct ieee80211vap *,
397 const uint8_t [IEEE80211_ADDR_LEN],
399 void (*mpp_peerdown)(struct ieee80211_node *);
400 void (*mpp_vattach)(struct ieee80211vap *);
401 void (*mpp_vdetach)(struct ieee80211vap *);
402 int (*mpp_newstate)(struct ieee80211vap *,
403 enum ieee80211_state, int);
404 const size_t mpp_privlen; /* size required in the routing table
406 int mpp_inact; /* inact. timeout for invalid routes
411 * Mesh Link Metric Report Protocol.
413 struct ieee80211_mesh_proto_metric {
414 char mpm_descr[IEEE80211_MESH_PROTO_DSZ];
416 uint32_t (*mpm_metric)(struct ieee80211_node *);
421 * Mesh Authentication Protocol.
423 struct ieee80211_mesh_proto_auth {
427 struct ieee80211_mesh_proto_congestion {
430 struct ieee80211_mesh_proto_sync {
434 typedef uint32_t ieee80211_mesh_seq;
435 #define IEEE80211_MESH_SEQ_LEQ(a, b) ((int32_t)((a)-(b)) <= 0)
436 #define IEEE80211_MESH_SEQ_GEQ(a, b) ((int32_t)((a)-(b)) >= 0)
438 struct ieee80211_mesh_state {
440 uint8_t ms_id[IEEE80211_MESHID_LEN];
441 ieee80211_mesh_seq ms_seq; /* seq no for meshcntl */
442 uint16_t ms_neighbors;
443 uint8_t ms_ttl; /* mesh ttl set in packets */
444 #define IEEE80211_MESHFLAGS_AP 0x01 /* accept peers */
445 #define IEEE80211_MESHFLAGS_PORTAL 0x02 /* mesh portal role */
446 #define IEEE80211_MESHFLAGS_FWD 0x04 /* forward packets */
448 struct mtx ms_rt_lock;
449 struct callout ms_cleantimer;
450 TAILQ_HEAD(, ieee80211_mesh_route) ms_routes;
451 struct ieee80211_mesh_proto_metric *ms_pmetric;
452 struct ieee80211_mesh_proto_path *ms_ppath;
454 void ieee80211_mesh_attach(struct ieee80211com *);
455 void ieee80211_mesh_detach(struct ieee80211com *);
457 struct ieee80211_mesh_route *
458 ieee80211_mesh_rt_find(struct ieee80211vap *,
459 const uint8_t [IEEE80211_ADDR_LEN]);
460 struct ieee80211_mesh_route *
461 ieee80211_mesh_rt_add(struct ieee80211vap *,
462 const uint8_t [IEEE80211_ADDR_LEN]);
463 void ieee80211_mesh_rt_del(struct ieee80211vap *,
464 const uint8_t [IEEE80211_ADDR_LEN]);
465 void ieee80211_mesh_rt_flush(struct ieee80211vap *);
466 void ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
467 const uint8_t [IEEE80211_ADDR_LEN]);
468 void ieee80211_mesh_proxy_check(struct ieee80211vap *,
469 const uint8_t [IEEE80211_ADDR_LEN]);
471 int ieee80211_mesh_register_proto_path(const
472 struct ieee80211_mesh_proto_path *);
473 int ieee80211_mesh_register_proto_metric(const
474 struct ieee80211_mesh_proto_metric *);
476 uint8_t * ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
477 uint8_t * ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
478 uint8_t * ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
480 uint8_t * ieee80211_add_meshlmetric(uint8_t *, uint32_t);
482 void ieee80211_mesh_node_init(struct ieee80211vap *,
483 struct ieee80211_node *);
484 void ieee80211_mesh_node_cleanup(struct ieee80211_node *);
485 void ieee80211_parse_meshid(struct ieee80211_node *,
487 struct ieee80211_scanparams;
488 void ieee80211_mesh_init_neighbor(struct ieee80211_node *,
489 const struct ieee80211_frame *,
490 const struct ieee80211_scanparams *);
493 * Return non-zero if proxy operation is enabled.
496 ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
498 struct ieee80211_mesh_state *ms = vap->iv_mesh;
499 return (ms->ms_flags &
500 (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_PORTAL)) != 0;
504 * Process an outbound frame: if a path is known to the
505 * destination then return a reference to the next hop
506 * for immediate transmission. Otherwise initiate path
507 * discovery and, if possible queue the packet to be
508 * sent when path discovery completes.
510 static __inline struct ieee80211_node *
511 ieee80211_mesh_discover(struct ieee80211vap *vap,
512 const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
514 struct ieee80211_mesh_state *ms = vap->iv_mesh;
515 return ms->ms_ppath->mpp_discover(vap, dest, m);
519 #endif /* !_NET80211_IEEE80211_MESH_H_ */