xref: /freebsd/sys/net80211/ieee80211_mesh.h (revision 830940567b49bb0c08dfaed40418999e76616909)
1 /*-
2  * Copyright (c) 2009 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Rui Paulo under sponsorship from the
6  * FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
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.
16  *
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
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31 #ifndef _NET80211_IEEE80211_MESH_H_
32 #define _NET80211_IEEE80211_MESH_H_
33 
34 #define	IEEE80211_MESH_DEFAULT_TTL	31
35 
36 /*
37  * NB: all structures are__packed  so sizeof works on arm, et. al.
38  */
39 /*
40  * 802.11s Information Elements.
41 */
42 /* Mesh Configuration */
43 struct ieee80211_meshconf_ie {
44 	uint8_t		conf_ie;	/* IEEE80211_ELEMID_MESHCONF */
45 	uint8_t		conf_len;
46 	uint8_t		conf_ver;
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 */
53 	uint8_t		conf_cap;
54 } __packed;
55 
56 #define	IEEE80211_MESHCONF_VERSION		1
57 /* Null Protocol */
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 */
96 
97 /* Mesh Identifier */
98 struct ieee80211_meshid_ie {
99 	uint8_t		id_ie;		/* IEEE80211_ELEMID_MESHID */
100 	uint8_t		id_len;
101 } __packed;
102 
103 /* Link Metric Report */
104 struct ieee80211_meshlmetric_ie {
105 	uint8_t		lm_ie;	/* IEEE80211_ELEMID_MESHLINK */
106 	uint8_t		lm_len;
107 	uint32_t	lm_metric;
108 #define	IEEE80211_MESHLMETRIC_INITIALVAL	0
109 } __packed;
110 
111 /* Congestion Notification */
112 struct ieee80211_meshcngst_ie {
113 	uint8_t		cngst_ie;	/* IEEE80211_ELEMID_MESHCNGST */
114 	uint8_t		cngst_len;
115 	uint16_t	cngst_timer[4];	/* Expiration Timers: AC_BK,
116 					   AC_BE, AC_VI, AC_VO */
117 } __packed;
118 
119 /* Peer Version */
120 struct ieee80211_meshpeerver_ie {
121 	uint8_t		peerver_ie;	/* IEEE80211_ELEMID_MESHPEERVER */
122 	uint8_t		peerver_len;
123 	uint8_t		peerver_proto[4];
124 } __packed;
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 }
135 
136 /* Peer Link Management */
137 struct ieee80211_meshpeer_ie {
138 	uint8_t		peer_ie;	/* IEEE80211_ELEMID_MESHPEER */
139 	uint8_t		peer_len;
140 	uint8_t		peer_subtype;
141 	uint16_t	peer_llinkid;	/* Local Link ID */
142 	uint16_t	peer_linkid;	/* Peer Link ID */
143 	uint16_t	peer_rcode;
144 } __packed;
145 
146 enum {
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 */
151 };
152 
153 #ifdef notyet
154 /* Mesh Channel Switch Annoucement */
155 struct ieee80211_meshcsa_ie {
156 	uint8_t		csa_ie;		/* IEEE80211_ELEMID_MESHCSA */
157 	uint8_t		csa_len;
158 	uint8_t		csa_mode;
159 	uint8_t		csa_newclass;	/* New Regulatory Class */
160 	uint8_t		csa_newchan;
161 	uint8_t		csa_precvalue;	/* Precedence Value */
162 	uint8_t		csa_count;
163 } __packed;
164 
165 /* Mesh TIM */
166 /* Equal to the non Mesh version */
167 
168 /* Mesh Awake Window */
169 struct ieee80211_meshawakew_ie {
170 	uint8_t		awakew_ie;		/* IEEE80211_ELEMID_MESHAWAKEW */
171 	uint8_t		awakew_len;
172 	uint8_t		awakew_windowlen;	/* in TUs */
173 } __packed;
174 
175 /* Mesh Beacon Timing */
176 struct ieee80211_meshbeacont_ie {
177 	uint8_t		beacont_ie;		/* IEEE80211_ELEMID_MESHBEACONT */
178 	uint8_t		beacont_len;
179 	struct {
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 */
184 } __packed;
185 #endif
186 
187 /* Portal (MP) Annoucement */
188 struct ieee80211_meshpann_ie {
189 	uint8_t		pann_ie;		/* IEEE80211_ELEMID_MESHPANN */
190 	uint8_t		pann_len;
191 	uint8_t		pann_flags;
192 	uint8_t		pann_hopcount;
193 	uint8_t		pann_ttl;
194 	uint8_t		pann_addr[IEEE80211_ADDR_LEN];
195 	uint8_t		pann_seq;		/* PANN Sequence Number */
196 } __packed;
197 
198 /* Root (MP) Annoucement */
199 struct ieee80211_meshrann_ie {
200 	uint8_t		rann_ie;		/* IEEE80211_ELEMID_MESHRANN */
201 	uint8_t		rann_len;
202 	uint8_t		rann_flags;
203 #define	IEEE80211_MESHRANN_FLAGS_PR	0x01	/* Portal Role */
204 	uint8_t		rann_hopcount;
205 	uint8_t		rann_ttl;
206 	uint8_t		rann_addr[IEEE80211_ADDR_LEN];
207 	uint32_t	rann_seq;		/* HWMP Sequence Number */
208 	uint32_t	rann_metric;
209 } __packed;
210 
211 /* Mesh Path Request */
212 struct ieee80211_meshpreq_ie {
213 	uint8_t		preq_ie;	/* IEEE80211_ELEMID_MESHPREQ */
214 	uint8_t		preq_len;
215 	uint8_t		preq_flags;
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;
221 	uint8_t		preq_ttl;
222 	uint32_t	preq_id;
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 */
229 	struct {
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 */
237 } __packed;
238 
239 /* Mesh Path Reply */
240 struct ieee80211_meshprep_ie {
241 	uint8_t		prep_ie;	/* IEEE80211_ELEMID_MESHPREP */
242 	uint8_t		prep_len;
243 	uint8_t		prep_flags;
244 	uint8_t		prep_hopcount;
245 	uint8_t		prep_ttl;
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 */
253 } __packed;
254 
255 /* Mesh Path Error */
256 struct ieee80211_meshperr_ie {
257 	uint8_t		perr_ie;	/* IEEE80211_ELEMID_MESHPERR */
258 	uint8_t		perr_len;
259 	uint8_t		perr_mode;	/* NB: reserved */
260 	uint8_t		perr_ndests;	/* Number of Destinations */
261 	struct {
262 		uint8_t		dest_addr[IEEE80211_ADDR_LEN];
263 		uint32_t	dest_seq;	/* HWMP Sequence Number */
264 	} __packed perr_dests[1];		/* NB: variable size */
265 } __packed;
266 
267 #ifdef notyet
268 /* Mesh Proxy Update */
269 struct ieee80211_meshpu_ie {
270 	uint8_t		pu_ie;		/* IEEE80211_ELEMID_MESHPU */
271 	uint8_t		pu_len;
272 	uint8_t		pu_flags;
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 */
280 } __packed;
281 
282 /* Mesh Proxy Update Confirmation */
283 struct ieee80211_meshpuc_ie {
284 	uint8_t		puc_ie;		/* IEEE80211_ELEMID_MESHPUC */
285 	uint8_t		puc_len;
286 	uint8_t		puc_flags;
287 	uint8_t		puc_seq;	/* PU Sequence Number */
288 	uint8_t		puc_daddr[IEEE80211_ADDR_LEN];
289 } __packed;
290 #endif
291 
292 /*
293  * 802.11s Action Frames
294  */
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
301 
302 /*
303  * Mesh Peering Action codes.
304  */
305 enum {
306 	IEEE80211_ACTION_MESHPEERING_OPEN	= 0,
307 	IEEE80211_ACTION_MESHPEERING_CONFIRM	= 1,
308 	IEEE80211_ACTION_MESHPEERING_CLOSE	= 2,
309 	/* 3-255 reserved */
310 };
311 
312 /*
313  * Mesh Path Selection Action codes.
314  */
315 enum {
316 	IEEE80211_ACTION_MESHPATH_REQ	= 0,
317 	IEEE80211_ACTION_MESHPATH_REP	= 1,
318 	IEEE80211_ACTION_MESHPATH_ERR	= 2,
319 	IEEE80211_ACTION_MESHPATH_RANN	= 3,
320 	/* 4-255 reserved */
321 };
322 
323 /*
324  * Mesh Link Metric Action codes.
325  */
326 enum {
327 	IEEE80211_ACTION_MESHLMETRIC_REQ = 0,	/* Link Metric Request */
328 	IEEE80211_ACTION_MESHLMETRIC_REP = 1,	/* Link Metric Report */
329 	/* 2-255 reserved */
330 };
331 
332 /*
333  * Mesh Portal Annoucement Action codes.
334  */
335 enum {
336 	IEEE80211_ACTION_MESHPANN	= 0,
337 	/* 1-255 reserved */
338 };
339 
340 /*
341  * Different mesh control structures based on the AE
342  * (Address Extension) bits.
343  */
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 */
349 } __packed;
350 
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];
356 } __packed;
357 
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];
364 } __packed;
365 
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];
373 } __packed;
374 
375 #ifdef _KERNEL
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 */
384 	uint16_t		rt_flags;
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 */
390 };
391 #define	IEEE80211_MESH_ROUTE_PRIV(rt, cast)	((cast *)rt->rt_priv)
392 
393 #define	IEEE80211_MESH_PROTO_DSZ	12	/* description size */
394 /*
395  * Mesh Path Selection Protocol.
396  */
397 enum ieee80211_state;
398 struct ieee80211_mesh_proto_path {
399 	char 		mpp_descr[IEEE80211_MESH_PROTO_DSZ];
400 	uint8_t		mpp_ie[4];
401 	struct ieee80211_node *
402 	    		(*mpp_discover)(struct ieee80211vap *,
403 				const uint8_t [IEEE80211_ADDR_LEN],
404 				struct mbuf *);
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
411 					   for private data */
412 	int		mpp_inact;	/* inact. timeout for invalid routes
413 					   (ticks) */
414 };
415 
416 /*
417  * Mesh Link Metric Report Protocol.
418  */
419 struct ieee80211_mesh_proto_metric {
420 	char		mpm_descr[IEEE80211_MESH_PROTO_DSZ];
421 	uint8_t		mpm_ie[4];
422 	uint32_t	(*mpm_metric)(struct ieee80211_node *);
423 };
424 
425 #ifdef notyet
426 /*
427  * Mesh Authentication Protocol.
428  */
429 struct ieee80211_mesh_proto_auth {
430 	uint8_t		mpa_ie[4];
431 };
432 
433 struct ieee80211_mesh_proto_congestion {
434 };
435 
436 struct ieee80211_mesh_proto_sync {
437 };
438 #endif
439 
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)
443 
444 struct ieee80211_mesh_state {
445 	int				ms_idlen;
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 */
453 	uint8_t				ms_flags;
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;
459 };
460 void		ieee80211_mesh_attach(struct ieee80211com *);
461 void		ieee80211_mesh_detach(struct ieee80211com *);
462 
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]);
476 
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 *);
481 
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,
486 		    uint16_t);
487 uint8_t *	ieee80211_add_meshlmetric(uint8_t *, uint32_t);
488 
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 *,
493 		    const uint8_t *);
494 struct ieee80211_scanparams;
495 void		ieee80211_mesh_init_neighbor(struct ieee80211_node *,
496 		   const struct ieee80211_frame *,
497 		   const struct ieee80211_scanparams *);
498 
499 /*
500  * Return non-zero if proxy operation is enabled.
501  */
502 static __inline int
503 ieee80211_mesh_isproxyena(struct ieee80211vap *vap)
504 {
505 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
506 	return (ms->ms_flags &
507 	    (IEEE80211_MESHFLAGS_AP | IEEE80211_MESHFLAGS_PORTAL)) != 0;
508 }
509 
510 /*
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.
516  */
517 static __inline struct ieee80211_node *
518 ieee80211_mesh_discover(struct ieee80211vap *vap,
519     const uint8_t dest[IEEE80211_ADDR_LEN], struct mbuf *m)
520 {
521 	struct ieee80211_mesh_state *ms = vap->iv_mesh;
522 	return ms->ms_ppath->mpp_discover(vap, dest, m);
523 }
524 
525 #endif /* _KERNEL */
526 #endif /* !_NET80211_IEEE80211_MESH_H_ */
527