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