xref: /freebsd/sys/net80211/ieee80211_mesh.h (revision 315ee00f)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2009 The FreeBSD Foundation
5  *
6  * This software was developed by Rui Paulo under sponsorship from the
7  * FreeBSD Foundation.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31 #ifndef _NET80211_IEEE80211_MESH_H_
32 #define _NET80211_IEEE80211_MESH_H_
33 
34 #define	IEEE80211_MESH_DEFAULT_TTL	31
35 #define	IEEE80211_MESH_MAX_NEIGHBORS	15
36 
37 /*
38  * NB: all structures are __packed  so sizeof works on arm, et. al.
39  */
40 /*
41  * 802.11s Information Elements.
42 */
43 /* Mesh Configuration */
44 #define IEEE80211_MESH_CONF_SZ		(7)
45 struct ieee80211_meshconf_ie {
46 	uint8_t		conf_ie;	/* IEEE80211_ELEMID_MESHCONF */
47 	uint8_t		conf_len;
48 	uint8_t		conf_pselid;	/* Active Path Sel. Proto. ID */
49 	uint8_t		conf_pmetid;	/* Active Metric Identifier */
50 	uint8_t		conf_ccid;	/* Congestion Control Mode ID  */
51 	uint8_t		conf_syncid;	/* Sync. Protocol ID */
52 	uint8_t		conf_authid;	/* Auth. Protocol ID */
53 	uint8_t		conf_form;	/* Formation Information */
54 	uint8_t		conf_cap;
55 } __packed;
56 
57 /* Hybrid Wireless Mesh Protocol */
58 enum {
59 	/* 0 reserved */
60 	IEEE80211_MESHCONF_PATH_HWMP		= 1,
61 	/* 2-254 reserved */
62 	IEEE80211_MESHCONF_PATH_VENDOR		= 255,
63 };
64 
65 /* Airtime Link Metric */
66 enum {
67 	/* 0 reserved */
68 	IEEE80211_MESHCONF_METRIC_AIRTIME	= 1,
69 	/* 2-254 reserved */
70 	IEEE80211_MESHCONF_METRIC_VENDOR	= 255,
71 };
72 
73 /* Congestion Control */
74 enum {
75 	IEEE80211_MESHCONF_CC_DISABLED		= 0,
76 	IEEE80211_MESHCONF_CC_SIG		= 1,
77 	/* 2-254 reserved */
78 	IEEE80211_MESHCONF_CC_VENDOR		= 255,
79 };
80 
81 /* Neighbour Offset */
82 enum {
83 	/* 0 reserved */
84 	IEEE80211_MESHCONF_SYNC_NEIGHOFF	= 1,
85 	/* 2-254 rserved */
86 	IEEE80211_MESHCONF_SYNC_VENDOR		= 255,
87 };
88 
89 /* Authentication Protocol Identifier */
90 enum {
91 	IEEE80211_MESHCONF_AUTH_DISABLED	= 0,
92 	/* Simultaneous Authenticaction of Equals */
93 	IEEE80211_MESHCONF_AUTH_SEA		= 1,
94 	IEEE80211_MESHCONF_AUTH_8021X		= 2, /* IEEE 802.1X */
95 	/* 3-254 reserved */
96 	IEEE80211_MESHCONF_AUTH_VENDOR		= 255,
97 };
98 
99 /* Mesh Formation Info */
100 #define	IEEE80211_MESHCONF_FORM_GATE	0x01 	/* Connected to Gate */
101 #define	IEEE80211_MESHCONF_FORM_NNEIGH_MASK 0x7E /* Number of Neighbours */
102 #define	IEEE80211_MESHCONF_FORM_SA	0xF0 	/* indicating 802.1X auth */
103 
104 /* Mesh Capability */
105 #define	IEEE80211_MESHCONF_CAP_AP	0x01	/* Accepting Peers */
106 #define	IEEE80211_MESHCONF_CAP_MCCAS	0x02	/* MCCA supported */
107 #define	IEEE80211_MESHCONF_CAP_MCCAE	0x04	/* MCCA enabled */
108 #define	IEEE80211_MESHCONF_CAP_FWRD 	0x08	/* forwarding enabled */
109 #define	IEEE80211_MESHCONF_CAP_BTR	0x10	/* Beacon Timing Report Enab */
110 #define	IEEE80211_MESHCONF_CAP_TBTT	0x20	/* TBTT Adjusting  */
111 #define	IEEE80211_MESHCONF_CAP_PSL	0x40	/* Power Save Level */
112 /* 0x80 reserved */
113 
114 /* Mesh Identifier */
115 struct ieee80211_meshid_ie {
116 	uint8_t		id_ie;		/* IEEE80211_ELEMID_MESHID */
117 	uint8_t		id_len;
118 } __packed;
119 
120 /* Link Metric Report */
121 struct ieee80211_meshlmetric_ie {
122 	uint8_t		lm_ie;	/* IEEE80211_ACTION_MESH_LMETRIC */
123 	uint8_t		lm_len;
124 	uint8_t		lm_flags;
125 #define	IEEE80211_MESH_LMETRIC_FLAGS_REQ	0x01	/* Request */
126 	/*
127 	 * XXX: this field should be variable in size and depend on
128 	 * the active active path selection metric identifier
129 	 */
130 	uint32_t	lm_metric;
131 #define	IEEE80211_MESHLMETRIC_INITIALVAL	0
132 } __packed;
133 
134 /* Congestion Notification */
135 struct ieee80211_meshcngst_ie {
136 	uint8_t		cngst_ie;	/* IEEE80211_ELEMID_MESHCNGST */
137 	uint8_t		cngst_len;
138 	uint16_t	cngst_timer[4];	/* Expiration Timers: AC_BK,
139 					   AC_BE, AC_VI, AC_VO */
140 } __packed;
141 
142 /* Peer Link Management */
143 #define IEEE80211_MPM_BASE_SZ	(4)
144 #define IEEE80211_MPM_MAX_SZ	(8)
145 struct ieee80211_meshpeer_ie {
146 	uint8_t		peer_ie;	/* IEEE80211_ELEMID_MESHPEER */
147 	uint8_t		peer_len;
148 	uint16_t	peer_proto;	/* Peer Management Protocol */
149 	uint16_t	peer_llinkid;	/* Local Link ID */
150 	uint16_t	peer_linkid;	/* Peer Link ID */
151 	uint16_t	peer_rcode;
152 } __packed;
153 
154 /* Mesh Peering Protocol Identifier field value */
155 enum {
156 	IEEE80211_MPPID_MPM		= 0,	/* Mesh peering management */
157 	IEEE80211_MPPID_AUTH_MPM	= 1,	/* Auth. mesh peering exchange */
158 	/* 2-65535 reserved */
159 };
160 
161 #ifdef notyet
162 /* Mesh Channel Switch Annoucement */
163 struct ieee80211_meshcsa_ie {
164 	uint8_t		csa_ie;		/* IEEE80211_ELEMID_MESHCSA */
165 	uint8_t		csa_len;
166 	uint8_t		csa_mode;
167 	uint8_t		csa_newclass;	/* New Regulatory Class */
168 	uint8_t		csa_newchan;
169 	uint8_t		csa_precvalue;	/* Precedence Value */
170 	uint8_t		csa_count;
171 } __packed;
172 
173 /* Mesh TIM */
174 /* Equal to the non Mesh version */
175 
176 /* Mesh Awake Window */
177 struct ieee80211_meshawakew_ie {
178 	uint8_t		awakew_ie;		/* IEEE80211_ELEMID_MESHAWAKEW */
179 	uint8_t		awakew_len;
180 	uint8_t		awakew_windowlen;	/* in TUs */
181 } __packed;
182 
183 /* Mesh Beacon Timing */
184 struct ieee80211_meshbeacont_ie {
185 	uint8_t		beacont_ie;		/* IEEE80211_ELEMID_MESHBEACONT */
186 	uint8_t		beacont_len;
187 	struct {
188 		uint8_t		mp_aid;		/* Least Octet of AID */
189 		uint16_t	mp_btime;	/* Beacon Time */
190 		uint16_t	mp_bint;	/* Beacon Interval */
191 	} __packed mp[1];			/* NB: variable size */
192 } __packed;
193 #endif
194 
195 /* Gate (GANN) Annoucement */
196 /*
197  * NB: these macros used for the length in the IEs does not include 2 bytes
198  * for _ie and _len fields as is defined by the standard.
199  */
200 #define	IEEE80211_MESHGANN_BASE_SZ 	(15)
201 struct ieee80211_meshgann_ie {
202 	uint8_t		gann_ie;		/* IEEE80211_ELEMID_MESHGANN */
203 	uint8_t		gann_len;
204 	uint8_t		gann_flags;
205 	uint8_t		gann_hopcount;
206 	uint8_t		gann_ttl;
207 	uint8_t		gann_addr[IEEE80211_ADDR_LEN];
208 	uint32_t	gann_seq;		/* GANN Sequence Number */
209 	uint16_t	gann_interval;		/* GANN Interval */
210 } __packed;
211 
212 /* Root (MP) Annoucement */
213 #define	IEEE80211_MESHRANN_BASE_SZ 	(21)
214 struct ieee80211_meshrann_ie {
215 	uint8_t		rann_ie;		/* IEEE80211_ELEMID_MESHRANN */
216 	uint8_t		rann_len;
217 	uint8_t		rann_flags;
218 #define	IEEE80211_MESHRANN_FLAGS_GATE	0x01	/* Mesh Gate */
219 	uint8_t		rann_hopcount;
220 	uint8_t		rann_ttl;
221 	uint8_t		rann_addr[IEEE80211_ADDR_LEN];
222 	uint32_t	rann_seq;		/* HWMP Sequence Number */
223 	uint32_t	rann_interval;
224 	uint32_t	rann_metric;
225 } __packed;
226 
227 /* Mesh Path Request */
228 #define	IEEE80211_MESHPREQ_BASE_SZ 		(26)
229 #define	IEEE80211_MESHPREQ_BASE_SZ_AE 		(32)
230 #define	IEEE80211_MESHPREQ_TRGT_SZ 		(11)
231 #define	IEEE80211_MESHPREQ_TCNT_OFFSET		(27)
232 #define	IEEE80211_MESHPREQ_TCNT_OFFSET_AE	(33)
233 struct ieee80211_meshpreq_ie {
234 	uint8_t		preq_ie;	/* IEEE80211_ELEMID_MESHPREQ */
235 	uint8_t		preq_len;
236 	uint8_t		preq_flags;
237 #define	IEEE80211_MESHPREQ_FLAGS_GATE	0x01	/* Mesh Gate */
238 #define	IEEE80211_MESHPREQ_FLAGS_AM	0x02	/* 0 = bcast / 1 = ucast */
239 #define	IEEE80211_MESHPREQ_FLAGS_PP	0x04	/* Proactive PREP */
240 #define	IEEE80211_MESHPREQ_FLAGS_AE	0x40	/* Address Extension */
241 	uint8_t		preq_hopcount;
242 	uint8_t		preq_ttl;
243 	uint32_t	preq_id;
244 	uint8_t		preq_origaddr[IEEE80211_ADDR_LEN];
245 	uint32_t	preq_origseq;	/* HWMP Sequence Number */
246 	/* NB: may have Originator External Address */
247 	uint8_t		preq_orig_ext_addr[IEEE80211_ADDR_LEN];
248 	uint32_t	preq_lifetime;
249 	uint32_t	preq_metric;
250 	uint8_t		preq_tcount;	/* target count */
251 	struct {
252 		uint8_t		target_flags;
253 #define	IEEE80211_MESHPREQ_TFLAGS_TO	0x01	/* Target Only */
254 #define	IEEE80211_MESHPREQ_TFLAGS_USN	0x04	/* Unknown HWMP seq number */
255 		uint8_t		target_addr[IEEE80211_ADDR_LEN];
256 		uint32_t	target_seq;	/* HWMP Sequence Number */
257 	} __packed preq_targets[1];		/* NB: variable size */
258 } __packed;
259 
260 /* Mesh Path Reply */
261 #define	IEEE80211_MESHPREP_BASE_SZ 	(31)
262 #define	IEEE80211_MESHPREP_BASE_SZ_AE 	(37)
263 struct ieee80211_meshprep_ie {
264 	uint8_t		prep_ie;	/* IEEE80211_ELEMID_MESHPREP */
265 	uint8_t		prep_len;
266 	uint8_t		prep_flags;
267 #define	IEEE80211_MESHPREP_FLAGS_AE	0x40	/* Address Extension */
268 	uint8_t		prep_hopcount;
269 	uint8_t		prep_ttl;
270 	uint8_t		prep_targetaddr[IEEE80211_ADDR_LEN];
271 	uint32_t	prep_targetseq;
272 	/* NB: May have Target External Address */
273 	uint8_t		prep_target_ext_addr[IEEE80211_ADDR_LEN];
274 	uint32_t	prep_lifetime;
275 	uint32_t	prep_metric;
276 	uint8_t		prep_origaddr[IEEE80211_ADDR_LEN];
277 	uint32_t	prep_origseq;	/* HWMP Sequence Number */
278 } __packed;
279 
280 /* Mesh Path Error */
281 #define	IEEE80211_MESHPERR_MAXDEST	(19)
282 #define	IEEE80211_MESHPERR_NDEST_OFFSET	(3)
283 #define	IEEE80211_MESHPERR_BASE_SZ 	(2)
284 #define	IEEE80211_MESHPERR_DEST_SZ 	(13)
285 #define	IEEE80211_MESHPERR_DEST_SZ_AE 	(19)
286 struct ieee80211_meshperr_ie {
287 	uint8_t		perr_ie;	/* IEEE80211_ELEMID_MESHPERR */
288 	uint8_t		perr_len;
289 	uint8_t		perr_ttl;
290 	uint8_t		perr_ndests;	/* Number of Destinations */
291 	struct {
292 		uint8_t		dest_flags;
293 #define	IEEE80211_MESHPERR_DFLAGS_USN	0x01	/* XXX: not part of standard */
294 #define	IEEE80211_MESHPERR_DFLAGS_RC	0x02	/* XXX: not part of standard */
295 #define	IEEE80211_MESHPERR_FLAGS_AE	0x40	/* Address Extension */
296 		uint8_t		dest_addr[IEEE80211_ADDR_LEN];
297 		uint32_t	dest_seq;	/* HWMP Sequence Number */
298 		/* NB: May have Destination External Address */
299 		uint8_t		dest_ext_addr[IEEE80211_ADDR_LEN];
300 		uint16_t	dest_rcode;
301 	} __packed perr_dests[1];		/* NB: variable size */
302 } __packed;
303 
304 #ifdef notyet
305 /* Mesh Proxy Update */
306 struct ieee80211_meshpu_ie {
307 	uint8_t		pu_ie;		/* IEEE80211_ELEMID_MESHPU */
308 	uint8_t		pu_len;
309 	uint8_t		pu_flags;
310 #define	IEEE80211_MESHPU_FLAGS_MASK		0x1
311 #define	IEEE80211_MESHPU_FLAGS_DEL		0x0
312 #define	IEEE80211_MESHPU_FLAGS_ADD		0x1
313 	uint8_t		pu_seq;		/* PU Sequence Number */
314 	uint8_t		pu_addr[IEEE80211_ADDR_LEN];
315 	uint8_t		pu_naddr;	/* Number of Proxied Addresses */
316 	/* NB: proxied address follows */
317 } __packed;
318 
319 /* Mesh Proxy Update Confirmation */
320 struct ieee80211_meshpuc_ie {
321 	uint8_t		puc_ie;		/* IEEE80211_ELEMID_MESHPUC */
322 	uint8_t		puc_len;
323 	uint8_t		puc_flags;
324 	uint8_t		puc_seq;	/* PU Sequence Number */
325 	uint8_t		puc_daddr[IEEE80211_ADDR_LEN];
326 } __packed;
327 #endif
328 
329 /*
330  * 802.11s Action Frames
331  * XXX: these are wrong, and some of them should be
332  * under MESH category while PROXY is under MULTIHOP category.
333  */
334 #define	IEEE80211_ACTION_CAT_INTERWORK		15
335 #define	IEEE80211_ACTION_CAT_RESOURCE		16
336 #define	IEEE80211_ACTION_CAT_PROXY		17
337 
338 /*
339  * Mesh Peering Action codes.
340  */
341 enum {
342 	/* 0 reserved */
343 	IEEE80211_ACTION_MESHPEERING_OPEN	= 1,
344 	IEEE80211_ACTION_MESHPEERING_CONFIRM	= 2,
345 	IEEE80211_ACTION_MESHPEERING_CLOSE	= 3,
346 	/* 4-255 reserved */
347 };
348 
349 /*
350  * Mesh Action code.
351  */
352 enum {
353 	IEEE80211_ACTION_MESH_LMETRIC	= 0,	/* Mesh Link Metric Report */
354 	IEEE80211_ACTION_MESH_HWMP	= 1,	/* HWMP Mesh Path Selection */
355 	IEEE80211_ACTION_MESH_GANN	= 2,	/* Gate Announcement */
356 	IEEE80211_ACTION_MESH_CC	= 3,	/* Congestion Control */
357 	IEEE80211_ACTION_MESH_MCCA_SREQ	= 4,	/* MCCA Setup Request */
358 	IEEE80211_ACTION_MESH_MCCA_SREP	= 5,	/* MCCA Setup Reply */
359 	IEEE80211_ACTION_MESH_MCCA_AREQ	= 6,	/* MCCA Advertisement Req. */
360 	IEEE80211_ACTION_MESH_MCCA_ADVER =7,	/* MCCA Advertisement */
361 	IEEE80211_ACTION_MESH_MCCA_TRDOWN = 8,	/* MCCA Teardown */
362 	IEEE80211_ACTION_MESH_TBTT_REQ	= 9,	/* TBTT Adjustment Request */
363 	IEEE80211_ACTION_MESH_TBTT_RES	= 10,	/* TBTT Adjustment Response */
364 	/* 11-255 reserved */
365 };
366 
367 /*
368  * Different mesh control structures based on the AE
369  * (Address Extension) bits.
370  */
371 struct ieee80211_meshcntl {
372 	uint8_t		mc_flags;	/* Address Extension 00 */
373 	uint8_t		mc_ttl;		/* TTL */
374 	uint8_t		mc_seq[4];	/* Sequence No. */
375 	/* NB: more addresses may follow */
376 } __packed;
377 
378 struct ieee80211_meshcntl_ae01 {
379 	uint8_t		mc_flags;	/* Address Extension 01 */
380 	uint8_t		mc_ttl;		/* TTL */
381 	uint8_t		mc_seq[4];	/* Sequence No. */
382 	uint8_t		mc_addr4[IEEE80211_ADDR_LEN];
383 } __packed;
384 
385 struct ieee80211_meshcntl_ae10 {
386 	uint8_t		mc_flags;	/* Address Extension 10 */
387 	uint8_t		mc_ttl;		/* TTL */
388 	uint8_t		mc_seq[4];	/* Sequence No. */
389 	uint8_t		mc_addr5[IEEE80211_ADDR_LEN];
390 	uint8_t		mc_addr6[IEEE80211_ADDR_LEN];
391 } __packed;
392 
393 #define IEEE80211_MESH_AE_MASK		0x03
394 enum {
395 	IEEE80211_MESH_AE_00		= 0,	/* MC has no AE subfield */
396 	IEEE80211_MESH_AE_01		= 1,	/* MC contain addr4 */
397 	IEEE80211_MESH_AE_10		= 2,	/* MC contain addr5 & addr6 */
398 	IEEE80211_MESH_AE_11		= 3,	/* RESERVED */
399 };
400 
401 #ifdef _KERNEL
402 MALLOC_DECLARE(M_80211_MESH_PREQ);
403 MALLOC_DECLARE(M_80211_MESH_PREP);
404 MALLOC_DECLARE(M_80211_MESH_PERR);
405 
406 MALLOC_DECLARE(M_80211_MESH_RT);
407 MALLOC_DECLARE(M_80211_MESH_GT_RT);
408 /*
409  * Basic forwarding information:
410  * o Destination MAC
411  * o Next-hop MAC
412  * o Precursor list (not implemented yet)
413  * o Path timeout
414  * The rest is part of the active Mesh path selection protocol.
415  * XXX: to be moved out later.
416  */
417 struct ieee80211_mesh_route {
418 	TAILQ_ENTRY(ieee80211_mesh_route)	rt_next;
419 	struct ieee80211vap	*rt_vap;
420 	ieee80211_rte_lock_t	rt_lock;	/* fine grained route lock */
421 	struct callout		rt_discovery;	/* discovery timeout */
422 	int			rt_updtime;	/* last update time */
423 	uint8_t			rt_dest[IEEE80211_ADDR_LEN];
424 	uint8_t			rt_mesh_gate[IEEE80211_ADDR_LEN]; /* meshDA */
425 	uint8_t			rt_nexthop[IEEE80211_ADDR_LEN];
426 	uint32_t		rt_metric;	/* path metric */
427 	uint16_t		rt_nhops;	/* number of hops */
428 	uint16_t		rt_flags;
429 #define	IEEE80211_MESHRT_FLAGS_DISCOVER	0x01	/* path discovery */
430 #define	IEEE80211_MESHRT_FLAGS_VALID	0x02	/* path discovery complete */
431 #define	IEEE80211_MESHRT_FLAGS_PROXY	0x04	/* proxy entry */
432 #define	IEEE80211_MESHRT_FLAGS_GATE	0x08	/* mesh gate entry */
433 	uint32_t		rt_lifetime;	/* route timeout */
434 	uint32_t		rt_lastmseq;	/* last seq# seen dest */
435 	uint32_t		rt_ext_seq;	/* proxy seq number */
436 	void			*rt_priv;	/* private data */
437 };
438 #define	IEEE80211_MESH_ROUTE_PRIV(rt, cast)	((cast *)rt->rt_priv)
439 
440 /*
441  * Stored information about known mesh gates.
442  */
443 struct ieee80211_mesh_gate_route {
444 	TAILQ_ENTRY(ieee80211_mesh_gate_route)	gr_next;
445 	uint8_t				gr_addr[IEEE80211_ADDR_LEN];
446 	uint32_t			gr_lastseq;
447 	struct ieee80211_mesh_route 	*gr_route;
448 };
449 
450 #define	IEEE80211_MESH_PROTO_DSZ	12	/* description size */
451 /*
452  * Mesh Path Selection Protocol.
453  */
454 enum ieee80211_state;
455 struct ieee80211_mesh_proto_path {
456 	uint8_t		mpp_active;
457 	char 		mpp_descr[IEEE80211_MESH_PROTO_DSZ];
458 	uint8_t		mpp_ie;
459 	struct ieee80211_node *
460 	    		(*mpp_discover)(struct ieee80211vap *,
461 				const uint8_t [IEEE80211_ADDR_LEN],
462 				struct mbuf *);
463 	void		(*mpp_peerdown)(struct ieee80211_node *);
464 	void		(*mpp_senderror)(struct ieee80211vap *,
465 				const uint8_t [IEEE80211_ADDR_LEN],
466 				struct ieee80211_mesh_route *, int);
467 	void		(*mpp_vattach)(struct ieee80211vap *);
468 	void		(*mpp_vdetach)(struct ieee80211vap *);
469 	int		(*mpp_newstate)(struct ieee80211vap *,
470 			    enum ieee80211_state, int);
471 	const size_t	mpp_privlen;	/* size required in the routing table
472 					   for private data */
473 	int		mpp_inact;	/* inact. timeout for invalid routes
474 					   (ticks) */
475 };
476 
477 /*
478  * Mesh Link Metric Report Protocol.
479  */
480 struct ieee80211_mesh_proto_metric {
481 	uint8_t		mpm_active;
482 	char		mpm_descr[IEEE80211_MESH_PROTO_DSZ];
483 	uint8_t		mpm_ie;
484 	uint32_t	(*mpm_metric)(struct ieee80211_node *);
485 };
486 
487 #ifdef notyet
488 /*
489  * Mesh Authentication Protocol.
490  */
491 struct ieee80211_mesh_proto_auth {
492 	uint8_t		mpa_ie[4];
493 };
494 
495 struct ieee80211_mesh_proto_congestion {
496 };
497 
498 struct ieee80211_mesh_proto_sync {
499 };
500 #endif
501 
502 typedef uint32_t ieee80211_mesh_seq;
503 #define	IEEE80211_MESH_SEQ_LEQ(a, b)	((int32_t)((a)-(b)) <= 0)
504 #define	IEEE80211_MESH_SEQ_GEQ(a, b)	((int32_t)((a)-(b)) >= 0)
505 
506 struct ieee80211_mesh_state {
507 	int				ms_idlen;
508 	uint8_t				ms_id[IEEE80211_MESHID_LEN];
509 	ieee80211_mesh_seq		ms_seq;	/* seq no for meshcntl */
510 	uint16_t			ms_neighbors;
511 	uint8_t				ms_ttl;	/* mesh ttl set in packets */
512 #define IEEE80211_MESHFLAGS_AP		0x01	/* accept peers */
513 #define IEEE80211_MESHFLAGS_GATE	0x02	/* mesh gate role */
514 #define IEEE80211_MESHFLAGS_FWD		0x04	/* forward packets */
515 #define IEEE80211_MESHFLAGS_ROOT	0x08	/* configured as root */
516 	uint8_t				ms_flags;
517 	ieee80211_rt_lock_t		ms_rt_lock;
518 	struct callout			ms_cleantimer;
519 	struct callout			ms_gatetimer;
520 	ieee80211_mesh_seq		ms_gateseq;
521 	TAILQ_HEAD(, ieee80211_mesh_gate_route) ms_known_gates;
522 	TAILQ_HEAD(, ieee80211_mesh_route)  ms_routes;
523 	struct ieee80211_mesh_proto_metric *ms_pmetric;
524 	struct ieee80211_mesh_proto_path   *ms_ppath;
525 };
526 void		ieee80211_mesh_attach(struct ieee80211com *);
527 void		ieee80211_mesh_detach(struct ieee80211com *);
528 
529 struct ieee80211_mesh_route *
530 		ieee80211_mesh_rt_find(struct ieee80211vap *,
531 		    const uint8_t [IEEE80211_ADDR_LEN]);
532 struct ieee80211_mesh_route *
533                 ieee80211_mesh_rt_add(struct ieee80211vap *,
534 		    const uint8_t [IEEE80211_ADDR_LEN]);
535 void		ieee80211_mesh_rt_del(struct ieee80211vap *,
536 		    const uint8_t [IEEE80211_ADDR_LEN]);
537 void		ieee80211_mesh_rt_flush(struct ieee80211vap *);
538 void		ieee80211_mesh_rt_flush_peer(struct ieee80211vap *,
539 		    const uint8_t [IEEE80211_ADDR_LEN]);
540 int		ieee80211_mesh_rt_update(struct ieee80211_mesh_route *rt, int);
541 void		ieee80211_mesh_proxy_check(struct ieee80211vap *,
542 		    const uint8_t [IEEE80211_ADDR_LEN]);
543 
544 int		ieee80211_mesh_register_proto_path(const
545 		    struct ieee80211_mesh_proto_path *);
546 int		ieee80211_mesh_register_proto_metric(const
547 		    struct ieee80211_mesh_proto_metric *);
548 
549 uint8_t *	ieee80211_add_meshid(uint8_t *, struct ieee80211vap *);
550 uint8_t *	ieee80211_add_meshconf(uint8_t *, struct ieee80211vap *);
551 uint8_t *	ieee80211_add_meshpeer(uint8_t *, uint8_t, uint16_t, uint16_t,
552 		    uint16_t);
553 uint8_t *	ieee80211_add_meshlmetric(uint8_t *, uint8_t, uint32_t);
554 uint8_t *	ieee80211_add_meshgate(uint8_t *,
555 		    struct ieee80211_meshgann_ie *);
556 
557 void		ieee80211_mesh_node_init(struct ieee80211vap *,
558 		    struct ieee80211_node *);
559 void		ieee80211_mesh_node_cleanup(struct ieee80211_node *);
560 void		ieee80211_parse_meshid(struct ieee80211_node *,
561 		    const uint8_t *);
562 struct ieee80211_scanparams;
563 void		ieee80211_mesh_init_neighbor(struct ieee80211_node *,
564 		   const struct ieee80211_frame *,
565 		   const struct ieee80211_scanparams *);
566 void		ieee80211_mesh_update_beacon(struct ieee80211vap *,
567 		    struct ieee80211_beacon_offsets *);
568 struct ieee80211_mesh_gate_route *
569 		ieee80211_mesh_mark_gate(struct ieee80211vap *,
570 		    const uint8_t *, struct ieee80211_mesh_route *);
571 void		ieee80211_mesh_forward_to_gates(struct ieee80211vap *,
572 		    struct ieee80211_mesh_route *);
573 struct ieee80211_node *
574 		ieee80211_mesh_find_txnode(struct ieee80211vap *,
575 		    const uint8_t [IEEE80211_ADDR_LEN]);
576 
577 /*
578  * Return non-zero if proxy operation is enabled.
579  */
580 static __inline int
581 ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
582 {
583 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
584 	return (ms->ms_flags &
585 	    (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_GATE)) != 0;
586 }
587 
588 /*
589  * Process an outbound frame: if a path is known to the
590  * destination then return a reference to the next hop
591  * for immediate transmission.  Otherwise initiate path
592  * discovery and, if possible queue the packet to be
593  * sent when path discovery completes.
594  */
595 static __inline struct ieee80211_node *
596 ieee80211_mesh_discover(struct ieee80211vap *vap,
597     const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
598 {
599 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
600 	return ms->ms_ppath->mpp_discover(vap, dest, m);
601 }
602 
603 #endif /* _KERNEL */
604 #endif /* !_NET80211_IEEE80211_MESH_H_ */
605