Author: korli Date: 2011-04-11 20:43:16 +0200 (Mon, 11 Apr 2011) New Revision: 41236 Changeset: https://dev.haiku-os.org/changeset/41236 Added: haiku/vendor/freebsd/current/net80211/ieee80211_ratectl.c haiku/vendor/freebsd/current/net80211/ieee80211_ratectl.h haiku/vendor/freebsd/current/net80211/ieee80211_ratectl_none.c Modified: haiku/vendor/freebsd/current/net80211/ieee80211.c haiku/vendor/freebsd/current/net80211/ieee80211_action.c haiku/vendor/freebsd/current/net80211/ieee80211_adhoc.c haiku/vendor/freebsd/current/net80211/ieee80211_amrr.c haiku/vendor/freebsd/current/net80211/ieee80211_amrr.h haiku/vendor/freebsd/current/net80211/ieee80211_crypto_tkip.c haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.c haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.h haiku/vendor/freebsd/current/net80211/ieee80211_hostap.c haiku/vendor/freebsd/current/net80211/ieee80211_hwmp.c haiku/vendor/freebsd/current/net80211/ieee80211_input.c haiku/vendor/freebsd/current/net80211/ieee80211_ioctl.c haiku/vendor/freebsd/current/net80211/ieee80211_mesh.c haiku/vendor/freebsd/current/net80211/ieee80211_mesh.h haiku/vendor/freebsd/current/net80211/ieee80211_node.c haiku/vendor/freebsd/current/net80211/ieee80211_node.h haiku/vendor/freebsd/current/net80211/ieee80211_output.c haiku/vendor/freebsd/current/net80211/ieee80211_proto.c haiku/vendor/freebsd/current/net80211/ieee80211_proto.h haiku/vendor/freebsd/current/net80211/ieee80211_rssadapt.c haiku/vendor/freebsd/current/net80211/ieee80211_rssadapt.h haiku/vendor/freebsd/current/net80211/ieee80211_scan_sta.c haiku/vendor/freebsd/current/net80211/ieee80211_sta.c haiku/vendor/freebsd/current/net80211/ieee80211_tdma.c haiku/vendor/freebsd/current/net80211/ieee80211_var.h haiku/vendor/freebsd/current/net80211/ieee80211_wds.c Log: updating to FreeBSD 8.2 release Modified: haiku/vendor/freebsd/current/net80211/ieee80211.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -49,6 +49,7 @@ #ifdef IEEE80211_SUPPORT_SUPERG #include <net80211/ieee80211_superg.h> #endif +#include <net80211/ieee80211_ratectl.h> #include <net/bpf.h> @@ -391,11 +392,10 @@ ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; ifp->if_start = ieee80211_start; ifp->if_ioctl = ieee80211_ioctl; - ifp->if_watchdog = NULL; /* NB: no watchdog routine */ ifp->if_init = ieee80211_init; /* NB: input+output filled in by ether_ifattach */ - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; + IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); + ifp->if_snd.ifq_drv_maxlen = ifqmaxlen; IFQ_SET_READY(&ifp->if_snd); vap->iv_ifp = ifp; @@ -441,6 +441,9 @@ /* auto-enable s/w beacon miss support */ if (flags & IEEE80211_CLONE_NOBEACONS) vap->iv_flags_ext |= IEEE80211_FEXT_SWBMISS; + /* auto-generated or user supplied MAC address */ + if (flags & (IEEE80211_CLONE_BSSID|IEEE80211_CLONE_MACADDR)) + vap->iv_flags_ext |= IEEE80211_FEXT_UNIQMAC; /* * Enable various functionality by default if we're * capable; the driver can override us if it knows better. @@ -482,6 +485,7 @@ ieee80211_scan_vattach(vap); ieee80211_regdomain_vattach(vap); ieee80211_radiotap_vattach(vap); + ieee80211_ratectl_set(vap, IEEE80211_RATECTL_NONE); return 0; } Modified: haiku/vendor/freebsd/current/net80211/ieee80211_action.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_action.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_action.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -105,7 +105,7 @@ meshlm_send_action[act] = f; return 0; case IEEE80211_ACTION_CAT_MESHPATH: - if (act > N(hwmp_send_action)) + if (act >= N(hwmp_send_action)) break; hwmp_send_action[act] = f; return 0; Modified: haiku/vendor/freebsd/current/net80211/ieee80211_adhoc.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_adhoc.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_adhoc.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -293,7 +293,7 @@ struct ieee80211_frame *wh; struct ieee80211_key *key; struct ether_header *eh; - int hdrspace, need_tap; + int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ uint8_t dir, type, subtype, qos; uint8_t *bssid; uint16_t rxseq; @@ -318,7 +318,6 @@ KASSERT(ni != NULL, ("null node")); ni->ni_inact = ni->ni_inact_reload; - need_tap = 1; /* mbuf need to be tapped. */ type = -1; /* undefined */ if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { Modified: haiku/vendor/freebsd/current/net80211/ieee80211_amrr.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_amrr.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_amrr.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -1,6 +1,7 @@ /* $OpenBSD: ieee80211_amrr.c,v 1.1 2006/06/17 19:07:19 damien Exp $ */ /*- + * Copyright (c) 2010 Rui Paulo <rpaulo@xxxxxxxxxxx> * Copyright (c) 2006 * Damien Bergamini <damien.bergamini@xxxxxxx> * @@ -46,6 +47,7 @@ #include <net80211/ieee80211_var.h> #include <net80211/ieee80211_amrr.h> +#include <net80211/ieee80211_ratectl.h> #define is_success(amn) \ ((amn)->amn_retrycnt < (amn)->amn_txcnt / 10) @@ -54,15 +56,45 @@ #define is_enough(amn) \ ((amn)->amn_txcnt > 10) -static void amrr_sysctlattach(struct ieee80211_amrr *amrr, - struct sysctl_ctx_list *ctx, struct sysctl_oid *tree); +static void amrr_setinterval(const struct ieee80211vap *, int); +static void amrr_init(struct ieee80211vap *); +static void amrr_deinit(struct ieee80211vap *); +static void amrr_node_init(struct ieee80211_node *); +static void amrr_node_deinit(struct ieee80211_node *); +static int amrr_update(struct ieee80211_amrr *, + struct ieee80211_amrr_node *, struct ieee80211_node *); +static int amrr_rate(struct ieee80211_node *, void *, uint32_t); +static void amrr_tx_complete(const struct ieee80211vap *, + const struct ieee80211_node *, int, + void *, void *); +static void amrr_tx_update(const struct ieee80211vap *vap, + const struct ieee80211_node *, void *, void *, void *); +static void amrr_sysctlattach(struct ieee80211vap *, + struct sysctl_ctx_list *, struct sysctl_oid *); /* number of references from net80211 layer */ static int nrefs = 0; -void -ieee80211_amrr_setinterval(struct ieee80211_amrr *amrr, int msecs) +static const struct ieee80211_ratectl amrr = { + .ir_name = "amrr", + .ir_attach = NULL, + .ir_detach = NULL, + .ir_init = amrr_init, + .ir_deinit = amrr_deinit, + .ir_node_init = amrr_node_init, + .ir_node_deinit = amrr_node_deinit, + .ir_rate = amrr_rate, + .ir_tx_complete = amrr_tx_complete, + .ir_tx_update = amrr_tx_update, + .ir_setinterval = amrr_setinterval, +}; +IEEE80211_RATECTL_MODULE(amrr, 1); +IEEE80211_RATECTL_ALG(amrr, IEEE80211_RATECTL_AMRR, amrr); + +static void +amrr_setinterval(const struct ieee80211vap *vap, int msecs) { + struct ieee80211_amrr *amrr = vap->iv_rs; int t; if (msecs < 100) @@ -71,29 +103,49 @@ amrr->amrr_interval = (t < 1) ? 1 : t; } -void -ieee80211_amrr_init(struct ieee80211_amrr *amrr, - struct ieee80211vap *vap, int amin, int amax, int interval) +static void +amrr_init(struct ieee80211vap *vap) { - /* XXX bounds check? */ - amrr->amrr_min_success_threshold = amin; - amrr->amrr_max_success_threshold = amax; - ieee80211_amrr_setinterval(amrr, interval); + struct ieee80211_amrr *amrr; - amrr_sysctlattach(amrr, vap->iv_sysctl, vap->iv_oid); + KASSERT(vap->iv_rs == NULL, ("%s called multiple times", __func__)); + + amrr = vap->iv_rs = malloc(sizeof(struct ieee80211_amrr), + M_80211_RATECTL, M_NOWAIT|M_ZERO); + if (amrr == NULL) { + if_printf(vap->iv_ifp, "couldn't alloc ratectl structure\n"); + return; + } + amrr->amrr_min_success_threshold = IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD; + amrr->amrr_max_success_threshold = IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD; + amrr_setinterval(vap, 500 /* ms */); + amrr_sysctlattach(vap, vap->iv_sysctl, vap->iv_oid); } -void -ieee80211_amrr_cleanup(struct ieee80211_amrr *amrr) +static void +amrr_deinit(struct ieee80211vap *vap) { + free(vap->iv_rs, M_80211_RATECTL); } -void -ieee80211_amrr_node_init(struct ieee80211_amrr *amrr, - struct ieee80211_amrr_node *amn, struct ieee80211_node *ni) +static void +amrr_node_init(struct ieee80211_node *ni) { const struct ieee80211_rateset *rs = &ni->ni_rates; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211_amrr *amrr = vap->iv_rs; + struct ieee80211_amrr_node *amn; + if (ni->ni_rctls == NULL) { + ni->ni_rctls = amn = malloc(sizeof(struct ieee80211_amrr_node), + M_80211_RATECTL, M_NOWAIT|M_ZERO); + if (amn == NULL) { + if_printf(vap->iv_ifp, "couldn't alloc per-node ratectl " + "structure\n"); + return; + } + } else + amn = ni->ni_rctls; amn->amn_amrr = amrr; amn->amn_success = 0; amn->amn_recovery = 0; @@ -112,6 +164,12 @@ "AMRR initial rate %d", ni->ni_txrate); } +static void +amrr_node_deinit(struct ieee80211_node *ni) +{ + free(ni->ni_rctls, M_80211_RATECTL); +} + static int amrr_update(struct ieee80211_amrr *amrr, struct ieee80211_amrr_node *amn, struct ieee80211_node *ni) @@ -168,10 +226,10 @@ * Update our internal state if it's been long enough. * If the rate changes we also update ni_txrate to match. */ -int -ieee80211_amrr_choose(struct ieee80211_node *ni, - struct ieee80211_amrr_node *amn) +static int +amrr_rate(struct ieee80211_node *ni, void *arg __unused, uint32_t iarg __unused) { + struct ieee80211_amrr_node *amn = ni->ni_rctls; struct ieee80211_amrr *amrr = amn->amn_amrr; int rix; @@ -189,27 +247,65 @@ return rix; } +/* + * Update statistics with tx complete status. Ok is non-zero + * if the packet is known to be ACK'd. Retries has the number + * retransmissions (i.e. xmit attempts - 1). + */ +static void +amrr_tx_complete(const struct ieee80211vap *vap, + const struct ieee80211_node *ni, int ok, + void *arg1, void *arg2 __unused) +{ + struct ieee80211_amrr_node *amn = ni->ni_rctls; + int retries = *(int *)arg1; + + amn->amn_txcnt++; + if (ok) + amn->amn_success++; + amn->amn_retrycnt += retries; +} + +/* + * Set tx count/retry statistics explicitly. Intended for + * drivers that poll the device for statistics maintained + * in the device. + */ +static void +amrr_tx_update(const struct ieee80211vap *vap, const struct ieee80211_node *ni, + void *arg1, void *arg2, void *arg3) +{ + struct ieee80211_amrr_node *amn = ni->ni_rctls; + int txcnt = *(int *)arg1, success = *(int *)arg2, retrycnt = *(int *)arg3; + + amn->amn_txcnt = txcnt; + amn->amn_success = success; + amn->amn_retrycnt = retrycnt; +} + static int amrr_sysctl_interval(SYSCTL_HANDLER_ARGS) { - struct ieee80211_amrr *amrr = arg1; + struct ieee80211vap *vap = arg1; + struct ieee80211_amrr *amrr = vap->iv_rs; int msecs = ticks_to_msecs(amrr->amrr_interval); int error; error = sysctl_handle_int(oidp, &msecs, 0, req); if (error || !req->newptr) return error; - ieee80211_amrr_setinterval(amrr, msecs); + amrr_setinterval(vap, msecs); return 0; } static void -amrr_sysctlattach(struct ieee80211_amrr *amrr, +amrr_sysctlattach(struct ieee80211vap *vap, struct sysctl_ctx_list *ctx, struct sysctl_oid *tree) { + struct ieee80211_amrr *amrr = vap->iv_rs; SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, amrr, + "amrr_rate_interval", CTLTYPE_INT | CTLFLAG_RW, vap, 0, amrr_sysctl_interval, "I", "amrr operation interval (ms)"); /* XXX bounds check values */ SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, @@ -219,8 +315,3 @@ "amrr_min_sucess_threshold", CTLFLAG_RW, &amrr->amrr_min_success_threshold, 0, ""); } - -/* - * Module glue. - */ -IEEE80211_RATE_MODULE(amrr, 1); Modified: haiku/vendor/freebsd/current/net80211/ieee80211_amrr.h =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_amrr.h 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_amrr.h 2011-04-11 18:43:16 UTC (rev 41236) @@ -58,44 +58,4 @@ u_int amn_retrycnt; }; -void ieee80211_amrr_init(struct ieee80211_amrr *, struct ieee80211vap *, - int, int, int); -void ieee80211_amrr_cleanup(struct ieee80211_amrr *); -void ieee80211_amrr_setinterval(struct ieee80211_amrr *, int); -void ieee80211_amrr_node_init(struct ieee80211_amrr *, - struct ieee80211_amrr_node *, struct ieee80211_node *); -int ieee80211_amrr_choose(struct ieee80211_node *, - struct ieee80211_amrr_node *); - -#define IEEE80211_AMRR_SUCCESS 1 -#define IEEE80211_AMRR_FAILURE 0 - -/* - * Update statistics with tx complete status. Ok is non-zero - * if the packet is known to be ACK'd. Retries has the number - * retransmissions (i.e. xmit attempts - 1). - */ -static __inline void -ieee80211_amrr_tx_complete(struct ieee80211_amrr_node *amn, - int ok, int retries) -{ - amn->amn_txcnt++; - if (ok) - amn->amn_success++; - amn->amn_retrycnt += retries; -} - -/* - * Set tx count/retry statistics explicitly. Intended for - * drivers that poll the device for statistics maintained - * in the device. - */ -static __inline void -ieee80211_amrr_tx_update(struct ieee80211_amrr_node *amn, - int txcnt, int success, int retrycnt) -{ - amn->amn_txcnt = txcnt; - amn->amn_success = success; - amn->amn_retrycnt = retrycnt; -} #endif /* _NET80211_IEEE80211_AMRR_H_ */ Modified: haiku/vendor/freebsd/current/net80211/ieee80211_crypto_tkip.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_crypto_tkip.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_crypto_tkip.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -144,6 +144,7 @@ return 0; } k->wk_keytsc = 1; /* TSC starts at 1 */ + ctx->rx_phase1_done = 0; return 1; } Modified: haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -730,6 +730,7 @@ } static eventhandler_tag wlan_bpfevent; +static eventhandler_tag wlan_ifllevent; static void bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach) @@ -756,6 +757,33 @@ } } +static void +wlan_iflladdr(void *arg __unused, struct ifnet *ifp) +{ + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap, *next; + + if (ifp->if_type != IFT_IEEE80211 || ic == NULL) + return; + + IEEE80211_LOCK(ic); + TAILQ_FOREACH_SAFE(vap, &ic->ic_vaps, iv_next, next) { + /* + * If the MAC address has changed on the parent and it was + * copied to the vap on creation then re-sync. + */ + if (vap->iv_ic == ic && + (vap->iv_flags_ext & IEEE80211_FEXT_UNIQMAC) == 0) { + IEEE80211_ADDR_COPY(vap->iv_myaddr, IF_LLADDR(ifp)); + IEEE80211_UNLOCK(ic); + if_setlladdr(vap->iv_ifp, IF_LLADDR(ifp), + IEEE80211_ADDR_LEN); + IEEE80211_LOCK(ic); + } + } + IEEE80211_UNLOCK(ic); +} + /* * Module glue. * @@ -772,6 +800,12 @@ bpf_track, 0, EVENTHANDLER_PRI_ANY); if (wlan_bpfevent == NULL) return ENOMEM; + wlan_ifllevent = EVENTHANDLER_REGISTER(iflladdr_event, + wlan_iflladdr, NULL, EVENTHANDLER_PRI_ANY); + if (wlan_ifllevent == NULL) { + EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); + return ENOMEM; + } if_clone_attach(&wlan_cloner); if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free); return 0; @@ -779,6 +813,7 @@ if_deregister_com_alloc(IFT_IEEE80211); if_clone_detach(&wlan_cloner); EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); + EVENTHANDLER_DEREGISTER(iflladdr_event, wlan_ifllevent); return 0; } return EINVAL; Modified: haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.h =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.h 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_freebsd.h 2011-04-11 18:43:16 UTC (rev 41236) @@ -148,6 +148,16 @@ mtx_assert((&(_as)->as_lock), MA_OWNED) /* + * Scan table definitions. + */ +typedef struct mtx ieee80211_scan_table_lock_t; +#define IEEE80211_SCAN_TABLE_LOCK_INIT(_st, _name) \ + mtx_init(&(_st)->st_lock, _name, "802.11 scan table", MTX_DEF) +#define IEEE80211_SCAN_TABLE_LOCK_DESTROY(_st) mtx_destroy(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_LOCK(_st) mtx_lock(&(_st)->st_lock) +#define IEEE80211_SCAN_TABLE_UNLOCK(_st) mtx_unlock(&(_st)->st_lock) + +/* * Node reference counting definitions. * * ieee80211_node_initref initialize the reference count to 1 @@ -386,14 +396,19 @@ /* * Rate control modules provide tx rate control support. */ -#define IEEE80211_RATE_MODULE(alg, version) \ -_IEEE80211_POLICY_MODULE(rate, alg, version); \ +#define IEEE80211_RATECTL_MODULE(alg, version) \ + _IEEE80211_POLICY_MODULE(ratectl, alg, version); \ + +#define IEEE80211_RATECTL_ALG(name, alg, v) \ static void \ alg##_modevent(int type) \ { \ - /* XXX nothing to do until the rate control framework arrives */\ + if (type == MOD_LOAD) \ + ieee80211_ratectl_register(alg, &v); \ + else \ + ieee80211_ratectl_unregister(alg); \ } \ -TEXT_SET(rate##_set, alg##_modevent) +TEXT_SET(ratectl##_set, alg##_modevent) struct ieee80211req; typedef int ieee80211_ioctl_getfunc(struct ieee80211vap *, Modified: haiku/vendor/freebsd/current/net80211/ieee80211_hostap.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_hostap.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_hostap.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -480,7 +480,7 @@ struct ieee80211_frame *wh; struct ieee80211_key *key; struct ether_header *eh; - int hdrspace, need_tap; + int hdrspace, need_tap = 1; /* mbuf need to be tapped. */ uint8_t dir, type, subtype, qos; uint8_t *bssid; uint16_t rxseq; @@ -505,7 +505,6 @@ KASSERT(ni != NULL, ("null node")); ni->ni_inact = ni->ni_inact_reload; - need_tap = 1; /* mbuf need to be tapped. */ type = -1; /* undefined */ if (m->m_pkthdr.len < sizeof(struct ieee80211_frame_min)) { @@ -884,6 +883,14 @@ wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] &= ~IEEE80211_FC1_WEP; } + /* + * Pass the packet to radiotap before calling iv_recv_mgmt(). + * Otherwise iv_recv_mgmt() might pass another packet to + * radiotap, resulting in out of order packet captures. + */ + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); + need_tap = 0; vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; @@ -1252,7 +1259,7 @@ return IEEE80211_REASON_IE_INVALID; } frm += 6, len -= 4; /* NB: len is payload only */ - /* NB: iswapoui already validated the OUI and type */ + /* NB: iswpaoui already validated the OUI and type */ w = LE_READ_2(frm); if (w != WPA_VERSION) { IEEE80211_DISCARD_IE(vap, Modified: haiku/vendor/freebsd/current/net80211/ieee80211_hwmp.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_hwmp.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_hwmp.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -148,7 +148,7 @@ struct ieee80211_hwmp_route { ieee80211_hwmp_seq hr_seq; /* last HWMP seq seen from dst*/ ieee80211_hwmp_seq hr_preqid; /* last PREQ ID seen from dst */ - ieee80211_hwmp_seq hr_targetseq; /* seq. no. on our latest PREQ*/ + ieee80211_hwmp_seq hr_origseq; /* seq. no. on our latest PREQ*/ int hr_preqretries; }; struct ieee80211_hwmp_state { @@ -548,7 +548,7 @@ *frm++ = perr->perr_ttl; *frm++ = perr->perr_ndests; for (i = 0; i < perr->perr_ndests; i++) { - *frm += perr->perr_dests[i].dest_flags; + *frm++ = perr->perr_dests[i].dest_flags; IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr); frm += 6; ADDWORD(frm, perr->perr_dests[i].dest_seq); @@ -653,6 +653,7 @@ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss, "%s", "send broadcast RANN"); + rann.rann_flags = 0; if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL) rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR; rann.rann_hopcount = 0; @@ -706,6 +707,10 @@ rtorig = ieee80211_mesh_rt_find(vap, preq->preq_origaddr); if (rtorig == NULL) rtorig = ieee80211_mesh_rt_add(vap, preq->preq_origaddr); + if (rtorig == NULL) { + /* XXX stat */ + return; + } hrorig = IEEE80211_MESH_ROUTE_PRIV(rtorig, struct ieee80211_hwmp_route); /* * Sequence number validation. @@ -733,12 +738,12 @@ prep.prep_flags = 0; prep.prep_hopcount = 0; prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, preq->preq_origaddr); - prep.prep_targetseq = preq->preq_origseq; + IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr); + prep.prep_targetseq = ++hs->hs_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr); - prep.prep_origseq = ++hs->hs_seq; + IEEE80211_ADDR_COPY(prep.prep_origaddr, preq->preq_origaddr); + prep.prep_origseq = preq->preq_origseq; hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep); /* * Build the reverse path, if we don't have it already. @@ -784,13 +789,13 @@ prep.prep_flags = 0; prep.prep_hopcount = 0; prep.prep_ttl = ms->ms_ttl; - IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr); + IEEE80211_ADDR_COPY(prep.prep_origaddr, rootmac); prep.prep_origseq = preq->preq_origseq; - prep.prep_targetseq = ++hs->hs_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL; - IEEE80211_ADDR_COPY(prep.prep_targetaddr, rootmac); - prep.prep_targetseq = PREQ_TSEQ(0); + IEEE80211_ADDR_COPY(prep.prep_targetaddr, + vap->iv_myaddr); + prep.prep_targetseq = ++hs->hs_seq; hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &prep); } @@ -848,13 +853,13 @@ prep.prep_hopcount = rt->rt_nhops + 1; prep.prep_ttl = ms->ms_ttl; IEEE80211_ADDR_COPY(&prep.prep_targetaddr, - preq->preq_origaddr); + PREQ_TADDR(0)); prep.prep_targetseq = hrorig->hr_seq; prep.prep_lifetime = preq->preq_lifetime; prep.prep_metric = rt->rt_metric + ms->ms_pmetric->mpm_metric(ni); IEEE80211_ADDR_COPY(&prep.prep_origaddr, - PREQ_TADDR(0)); + preq->preq_origaddr); prep.prep_origseq = hrorig->hr_seq; hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &prep); @@ -951,19 +956,19 @@ return; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, - "received PREP from %s", ether_sprintf(prep->prep_origaddr)); + "received PREP from %s", ether_sprintf(prep->prep_targetaddr)); - rt = ieee80211_mesh_rt_find(vap, prep->prep_origaddr); + rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr); if (rt == NULL) { /* * If we have no entry this could be a reply to a root PREQ. */ if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) { - rt = ieee80211_mesh_rt_add(vap, prep->prep_origaddr); + rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr); if (rt == NULL) { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "unable to add PREP path to %s", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); vap->iv_stats.is_mesh_rtaddfailed++; return; } @@ -974,7 +979,7 @@ rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "add root path to %s nhops %d metric %d (PREP)", - ether_sprintf(prep->prep_origaddr), + ether_sprintf(prep->prep_targetaddr), rt->rt_nhops, rt->rt_metric); return; } @@ -984,30 +989,30 @@ * Sequence number validation. */ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_LEQ(prep->prep_origseq, hr->hr_seq)) { + if (HWMP_SEQ_LEQ(prep->prep_targetseq, hr->hr_seq)) { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP from %s, old seq no %u <= %u", - ether_sprintf(prep->prep_origaddr), - prep->prep_origseq, hr->hr_seq); + ether_sprintf(prep->prep_targetaddr), + prep->prep_targetseq, hr->hr_seq); return; } - hr->hr_seq = prep->prep_origseq; + hr->hr_seq = prep->prep_targetseq; /* * If it's NOT for us, propagate the PREP. */ - if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_targetaddr) && + if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) && prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) { struct ieee80211_meshprep_ie pprep; /* propagated PREP */ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "propagate PREP from %s", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); memcpy(&pprep, prep, sizeof(pprep)); pprep.prep_hopcount += 1; pprep.prep_ttl -= 1; pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); - IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr); + IEEE80211_ADDR_COPY(pprep.prep_targetaddr, vap->iv_myaddr); hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep); } hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); @@ -1015,9 +1020,9 @@ /* NB: never clobber a proxy entry */; IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP for %s, route is marked PROXY", - ether_sprintf(prep->prep_origaddr)); + ether_sprintf(prep->prep_targetaddr)); vap->iv_stats.is_hwmp_proxy++; - } else if (prep->prep_targetseq == hr->hr_targetseq) { + } else if (prep->prep_origseq == hr->hr_origseq) { /* * Check if we already have a path to this node. * If we do, check if this path reply contains a @@ -1041,14 +1046,14 @@ } else { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "ignore PREP for %s, hopcount %d:%d metric %d:%d", - ether_sprintf(prep->prep_origaddr), + ether_sprintf(prep->prep_targetaddr), rt->rt_nhops, prep->prep_hopcount, rt->rt_metric, prep->prep_metric); } } else { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "discard PREP for %s, wrong seqno %u != %u", - ether_sprintf(prep->prep_origaddr), prep->prep_targetseq, + ether_sprintf(prep->prep_targetaddr), prep->prep_origseq, hr->hr_seq); vap->iv_stats.is_hwmp_wrongseq++; } @@ -1114,6 +1119,7 @@ "%s", "delete route entry"); perr.perr_ttl = ms->ms_ttl; perr.perr_ndests = 1; + PERR_DFLAGS(0) = 0; if (hr->hr_seq == 0) PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN; PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC; @@ -1223,7 +1229,8 @@ struct ieee80211_meshrann_ie prann; if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) + ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || + IEEE80211_ADDR_EQ(rann->rann_addr, vap->iv_myaddr)) return; rt = ieee80211_mesh_rt_find(vap, rann->rann_addr); @@ -1236,15 +1243,18 @@ return; } hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq) && rann->rann_ttl > 1 && - rann->rann_hopcount < hs->hs_maxhops && - (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { - memcpy(&prann, rann, sizeof(prann)); - prann.rann_hopcount += 1; - prann.rann_ttl -= 1; - prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); - hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, - &prann); + if (HWMP_SEQ_GT(rann->rann_seq, hr->hr_seq)) { + hr->hr_seq = rann->rann_seq; + if (rann->rann_ttl > 1 && + rann->rann_hopcount < hs->hs_maxhops && + (ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) { + memcpy(&prann, rann, sizeof(prann)); + prann.rann_hopcount += 1; + prann.rann_ttl -= 1; + prann.rann_metric += ms->ms_pmetric->mpm_metric(ni); + hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, + broadcastaddr, &prann); + } } } @@ -1305,8 +1315,8 @@ hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) { - if (hr->hr_targetseq == 0) - hr->hr_targetseq = ++hs->hs_seq; + if (hr->hr_origseq == 0) + hr->hr_origseq = ++hs->hs_seq; rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL; rt->rt_lifetime = ticks_to_msecs(ieee80211_hwmp_pathtimeout); @@ -1324,7 +1334,7 @@ preq.preq_ttl = ms->ms_ttl; preq.preq_id = ++hs->hs_preqid; IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr); - preq.preq_origseq = hr->hr_targetseq; + preq.preq_origseq = hr->hr_origseq; preq.preq_lifetime = rt->rt_lifetime; preq.preq_metric = rt->rt_metric; preq.preq_tcount = 1; Modified: haiku/vendor/freebsd/current/net80211/ieee80211_input.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_input.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_input.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -734,7 +734,8 @@ * Return the bssid of a frame. */ static const uint8_t * -ieee80211_getbssid(struct ieee80211vap *vap, const struct ieee80211_frame *wh) +ieee80211_getbssid(const struct ieee80211vap *vap, + const struct ieee80211_frame *wh) { if (vap->iv_opmode == IEEE80211_M_STA) return wh->i_addr2; @@ -748,7 +749,7 @@ #include <machine/stdarg.h> void -ieee80211_note(struct ieee80211vap *vap, const char *fmt, ...) +ieee80211_note(const struct ieee80211vap *vap, const char *fmt, ...) { char buf[128]; /* XXX */ va_list ap; @@ -761,7 +762,7 @@ } void -ieee80211_note_frame(struct ieee80211vap *vap, +ieee80211_note_frame(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *fmt, ...) { @@ -776,7 +777,7 @@ } void -ieee80211_note_mac(struct ieee80211vap *vap, +ieee80211_note_mac(const struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], const char *fmt, ...) { @@ -790,7 +791,7 @@ } void -ieee80211_discard_frame(struct ieee80211vap *vap, +ieee80211_discard_frame(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *type, const char *fmt, ...) { @@ -811,7 +812,7 @@ } void -ieee80211_discard_ie(struct ieee80211vap *vap, +ieee80211_discard_ie(const struct ieee80211vap *vap, const struct ieee80211_frame *wh, const char *type, const char *fmt, ...) { @@ -830,7 +831,7 @@ } void -ieee80211_discard_mac(struct ieee80211vap *vap, +ieee80211_discard_mac(const struct ieee80211vap *vap, const uint8_t mac[IEEE80211_ADDR_LEN], const char *type, const char *fmt, ...) { Modified: haiku/vendor/freebsd/current/net80211/ieee80211_ioctl.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_ioctl.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_ioctl.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -1590,8 +1590,10 @@ if (list == NULL) return ENOMEM; error = copyin(ireq->i_data, list, ireq->i_len); - if (error) + if (error) { + free(list, M_TEMP); return error; + } nchan = 0; chanlist = list + ireq->i_len; /* NB: zero'd already */ maxchan = ireq->i_len * NBBY; @@ -1607,8 +1609,10 @@ nchan++; } } - if (nchan == 0) + if (nchan == 0) { + free(list, M_TEMP); return EINVAL; + } if (ic->ic_bsschan != IEEE80211_CHAN_ANYC && /* XXX */ isclr(chanlist, ic->ic_bsschan->ic_ieee)) ic->ic_bsschan = IEEE80211_CHAN_ANYC; @@ -3199,15 +3203,18 @@ void *ioctl; IEEE80211_LOCK(ic); - if_purgemaddrs(parent); + if_delallmulti(parent); ioctl = parent->if_ioctl; /* XXX WAR if_allmulti */ parent->if_ioctl = NULL; TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { struct ifnet *ifp = vap->iv_ifp; struct ifmultiaddr *ifma; - TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; (void) if_addmulti(parent, ifma->ifma_addr, NULL); + } } parent->if_ioctl = ioctl; ieee80211_runtask(ic, &ic->ic_mcast_task); Modified: haiku/vendor/freebsd/current/net80211/ieee80211_mesh.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_mesh.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_mesh.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -388,8 +388,6 @@ for (i = 0; i < N(mesh_proto_paths); i++) { if (strcasecmp(mesh_proto_paths[i].mpp_descr, name) == 0) { ms->ms_ppath = &mesh_proto_paths[i]; - if (vap->iv_state == IEEE80211_S_RUN) - vap->iv_newstate(vap, IEEE80211_S_INIT, 0); return 0; } } @@ -405,8 +403,6 @@ for (i = 0; i < N(mesh_proto_metrics); i++) { if (strcasecmp(mesh_proto_metrics[i].mpm_descr, name) == 0) { ms->ms_pmetric = &mesh_proto_metrics[i]; - if (vap->iv_state == IEEE80211_S_RUN) - vap->iv_newstate(vap, IEEE80211_S_INIT, 0); return 0; } } @@ -739,10 +735,12 @@ ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) { KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow")); ms->ms_neighbors++; + ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); } else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED && state != IEEE80211_NODE_MESH_ESTABLISHED) { KASSERT(ms->ms_neighbors > 0, ("neighbor count 0")); ms->ms_neighbors--; + ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF); } ni->ni_mlstate = state; switch (state) { @@ -2552,6 +2550,18 @@ ieee80211_parse_meshid(ni, sp->meshid); } +void +ieee80211_mesh_update_beacon(struct ieee80211vap *vap, + struct ieee80211_beacon_offsets *bo) +{ + KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap")); + + if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) { + (void)ieee80211_add_meshconf(bo->bo_meshconf, vap); + clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF); + } +} + static int mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq) { Modified: haiku/vendor/freebsd/current/net80211/ieee80211_mesh.h =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_mesh.h 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_mesh.h 2011-04-11 18:43:16 UTC (rev 41236) @@ -470,6 +470,8 @@ void ieee80211_mesh_init_neighbor(struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_scanparams *); +void ieee80211_mesh_update_beacon(struct ieee80211vap *, + struct ieee80211_beacon_offsets *); /* * Return non-zero if proxy operation is enabled. Modified: haiku/vendor/freebsd/current/net80211/ieee80211_node.c =================================================================== --- haiku/vendor/freebsd/current/net80211/ieee80211_node.c 2011-04-11 18:09:02 UTC (rev 41235) +++ haiku/vendor/freebsd/current/net80211/ieee80211_node.c 2011-04-11 18:43:16 UTC (rev 41236) @@ -51,6 +51,7 @@ #endif #include <net80211/ieee80211_wds.h> #include <net80211/ieee80211_mesh.h> +#include <net80211/ieee80211_ratectl.h> [... truncated: 1244 lines follow ...]