diff options
author | monthadar <monthadar@FreeBSD.org> | 2013-02-07 21:26:40 +0000 |
---|---|---|
committer | monthadar <monthadar@FreeBSD.org> | 2013-02-07 21:26:40 +0000 |
commit | f3631fce3f3e16db66e87041ac6b159a0fe005e0 (patch) | |
tree | 7d8d62618527b645835d807e6f9d1a9ec2ef9f5f /sys/net80211/ieee80211_hwmp.c | |
parent | 9cc12d2c5f7a100b44e6de96a1d195b962db14d3 (diff) | |
download | FreeBSD-src-f3631fce3f3e16db66e87041ac6b159a0fe005e0.zip FreeBSD-src-f3631fce3f3e16db66e87041ac6b159a0fe005e0.tar.gz |
HWMP: ic->raw_xmit didn't always point to correct ni.
This is a code re-write. ic->raw_xmit need a pointer to ieee80211_node
for the destination node (da). I have reorganized the code so that
a pointer to the da node is searched for in the end & in one place.
* Make mesh_find_txnode public to be used by HWMP, renamed to
ieee80211_mesh_finx_txnode;
* changed the argument from ieee80211_node to ieee80211vap for all
hwmp_send_* functions;
* removed the 'sa' argument from hwmp_send_* functions as all HWMP frames
have the source address equal to vap->iv_myaddr;
* Modified hwmp_send_action so that if da is MULTCAST ni=vap->iv_bss
otherwise we called ieee80211_mesh_find_txnode. Also no need to hold
a reference in this functions if da is not MULTICAST as by finding the
node it became referenced in ieee80211_find_txnode;
Approved by: adrian (mentor)
Diffstat (limited to 'sys/net80211/ieee80211_hwmp.c')
-rw-r--r-- | sys/net80211/ieee80211_hwmp.c | 119 |
1 files changed, 51 insertions, 68 deletions
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c index 52a3152..50e4a1e 100644 --- a/sys/net80211/ieee80211_hwmp.c +++ b/sys/net80211/ieee80211_hwmp.c @@ -68,8 +68,7 @@ static void hwmp_vattach(struct ieee80211vap *); static void hwmp_vdetach(struct ieee80211vap *); static int hwmp_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int hwmp_send_action(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], +static int hwmp_send_action(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], uint8_t *, size_t); static uint8_t * hwmp_add_meshpreq(uint8_t *, @@ -86,23 +85,20 @@ static void hwmp_rootmode_rann_cb(void *); static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_meshpreq_ie *); -static int hwmp_send_preq(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], +static int hwmp_send_preq(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], struct ieee80211_meshpreq_ie *, struct timeval *, struct timeval *); static void hwmp_recv_prep(struct ieee80211vap *, struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_meshprep_ie *); -static int hwmp_send_prep(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], +static int hwmp_send_prep(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], struct ieee80211_meshprep_ie *); static void hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_meshperr_ie *); -static int hwmp_send_perr(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], +static int hwmp_send_perr(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], struct ieee80211_meshperr_ie *); static void hwmp_senderror(struct ieee80211vap *, @@ -111,8 +107,7 @@ static void hwmp_senderror(struct ieee80211vap *, static void hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *, const struct ieee80211_frame *, const struct ieee80211_meshrann_ie *); -static int hwmp_send_rann(struct ieee80211_node *, - const uint8_t [IEEE80211_ADDR_LEN], +static int hwmp_send_rann(struct ieee80211vap *, const uint8_t [IEEE80211_ADDR_LEN], struct ieee80211_meshrann_ie *); static struct ieee80211_node * @@ -588,17 +583,30 @@ hwmp_recv_action_meshpath(struct ieee80211_node *ni, } static int -hwmp_send_action(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], +hwmp_send_action(struct ieee80211vap *vap, const uint8_t da[IEEE80211_ADDR_LEN], uint8_t *ie, size_t len) { - struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; + struct ieee80211_node *ni; + struct ieee80211com *ic; struct ieee80211_bpf_params params; struct mbuf *m; uint8_t *frm; + if (IEEE80211_IS_MULTICAST(da)) { + ni = ieee80211_ref_node(vap->iv_bss); +#ifdef IEEE80211_DEBUG_REFCNT + IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, + "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", + __func__, __LINE__, + ni, ether_sprintf(ni->ni_macaddr), + ieee80211_node_refcnt(ni)+1); +#endif + ieee80211_ref_node(ni); + } + else + ni = ieee80211_mesh_find_txnode(vap, da); + if (vap->iv_state == IEEE80211_S_CAC) { IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni, "block %s frame in CAC state", "HWMP action"); @@ -607,19 +615,7 @@ hwmp_send_action(struct ieee80211_node *ni, } KASSERT(ni != NULL, ("null node")); - /* - * Hold a reference on the node so it doesn't go away until after - * the xmit is complete all the way in the driver. On error we - * will remove our reference. - */ -#ifdef IEEE80211_DEBUG_REFCNT - IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE, - "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n", - __func__, __LINE__, - ni, ether_sprintf(ni->ni_macaddr), - ieee80211_node_refcnt(ni)+1); -#endif - ieee80211_ref_node(ni); + ic = ni->ni_ic; m = ieee80211_getmgtframe(&frm, ic->ic_headroom + sizeof(struct ieee80211_frame), @@ -660,7 +656,7 @@ hwmp_send_action(struct ieee80211_node *ni, } ieee80211_send_setup(ni, m, IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION, - IEEE80211_NONQOS_TID, sa, da, sa); + IEEE80211_NONQOS_TID, vap->iv_myaddr, da, vap->iv_myaddr); m->m_flags |= M_ENCAP; /* mark encapsulated */ IEEE80211_NODE_STAT(ni, tx_mgmt); @@ -862,8 +858,8 @@ hwmp_rootmode_cb(void *arg) IEEE80211_MESHPREQ_TFLAGS_USN; PREQ_TSEQ(0) = 0; vap->iv_stats.is_hwmp_rootreqs++; - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq, - NULL, NULL); /* NB: we enforce rate check ourself */ + /* NB: we enforce rate check ourself */ + hwmp_send_preq(vap, broadcastaddr, &preq, NULL, NULL); hwmp_rootmode_setup(vap); } #undef PREQ_TFLAGS @@ -896,7 +892,7 @@ hwmp_rootmode_rann_cb(void *arg) rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL; vap->iv_stats.is_hwmp_rootrann++; - hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &rann); + hwmp_send_rann(vap, broadcastaddr, &rann); hwmp_rootmode_setup(vap); } @@ -1060,7 +1056,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "reply to %6D", preq->preq_origaddr, ":"); - hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep); + hwmp_send_prep(vap, wh->i_addr2, &prep); return; } /* we may update our proxy information for the orig external */ @@ -1119,8 +1115,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr); prep.prep_targetseq = ++hs->hs_seq; - hwmp_send_prep(vap->iv_bss, vap->iv_myaddr, - rtorig->rt_nexthop, &prep); + hwmp_send_prep(vap, rtorig->rt_nexthop, &prep); } } @@ -1161,8 +1156,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, IEEE80211_ADDR_COPY(&prep.prep_origaddr, preq->preq_origaddr); prep.prep_origseq = hrorig->hr_seq; - hwmp_send_prep(ni, vap->iv_myaddr, - rtorig->rt_nexthop, &prep); + hwmp_send_prep(vap, rtorig->rt_nexthop, &prep); /* * Set TO and unset RF bits because we have @@ -1181,8 +1175,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni); /* don't do PREQ ratecheck when we propagate */ - hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr, - &ppreq, NULL, NULL); + hwmp_send_preq(vap, broadcastaddr, &ppreq, NULL, NULL); } } #undef PREQ_TFLAGS @@ -1190,8 +1183,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni, #undef PREQ_TSEQ static int -hwmp_send_preq(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], +hwmp_send_preq(struct ieee80211vap *vap, const uint8_t da[IEEE80211_ADDR_LEN], struct ieee80211_meshpreq_ie *preq, struct timeval *last, struct timeval *minint) @@ -1220,7 +1212,7 @@ hwmp_send_preq(struct ieee80211_node *ni, preq->preq_len = (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE ? IEEE80211_MESHPREQ_BASE_SZ_AE : IEEE80211_MESHPREQ_BASE_SZ) + preq->preq_tcount * IEEE80211_MESHPREQ_TRGT_SZ; - return hwmp_send_action(ni, sa, da, (uint8_t *)preq, preq->preq_len+2); + return hwmp_send_action(vap, da, (uint8_t *)preq, preq->preq_len+2); } static void @@ -1354,7 +1346,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, pprep.prep_hopcount += 1; pprep.prep_ttl -= 1; pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni); - hwmp_send_prep(ni, vap->iv_myaddr, rtorig->rt_nexthop, &pprep); + hwmp_send_prep(vap, rtorig->rt_nexthop, &pprep); /* precursor list for the Target Mesh STA Address is updated */ } @@ -1436,8 +1428,7 @@ hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni, } static int -hwmp_send_prep(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], +hwmp_send_prep(struct ieee80211vap *vap, const uint8_t da[IEEE80211_ADDR_LEN], struct ieee80211_meshprep_ie *prep) { @@ -1455,8 +1446,7 @@ hwmp_send_prep(struct ieee80211_node *ni, prep->prep_ie = IEEE80211_ELEMID_MESHPREP; prep->prep_len = prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE ? IEEE80211_MESHPREP_BASE_SZ_AE : IEEE80211_MESHPREP_BASE_SZ; - return hwmp_send_action(ni, sa, da, (uint8_t *)prep, - prep->prep_len + 2); + return hwmp_send_action(vap, da, (uint8_t *)prep, prep->prep_len + 2); } #define PERR_DFLAGS(n) perr.perr_dests[n].dest_flags @@ -1489,7 +1479,7 @@ hwmp_peerdown(struct ieee80211_node *ni) PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH; /* NB: flush everything passing through peer */ ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr); - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr); + hwmp_send_perr(vap, broadcastaddr, &perr); } #undef PERR_DFLAGS #undef PERR_DADDR @@ -1592,8 +1582,7 @@ hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni, "propagate PERR from %6D", wh->i_addr2, ":"); pperr->perr_ndests = j; pperr->perr_ttl--; - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, - pperr); + hwmp_send_perr(vap, broadcastaddr, pperr); } done: if (pperr != NULL) @@ -1606,12 +1595,11 @@ done: #undef PERR_DRCODE static int -hwmp_send_perr(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], +hwmp_send_perr(struct ieee80211vap *vap, const uint8_t da[IEEE80211_ADDR_LEN], struct ieee80211_meshperr_ie *perr) { - struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp; + struct ieee80211_hwmp_state *hs = vap->iv_hwmp; int i; uint8_t length = 0; @@ -1642,7 +1630,7 @@ hwmp_send_perr(struct ieee80211_node *ni, length += IEEE80211_MESHPERR_DEST_SZ; } perr->perr_len =length; - return hwmp_send_action(ni, sa, da, (uint8_t *)perr, perr->perr_len+2); + return hwmp_send_action(vap, da, (uint8_t *)perr, perr->perr_len+2); } /* @@ -1695,7 +1683,7 @@ hwmp_senderror(struct ieee80211vap *vap, default: KASSERT(0, ("unknown reason code for HWMP PERR (%u)", rcode)); } - hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr); + hwmp_send_perr(vap, broadcastaddr, &perr); } #undef PERR_DFLAGS #undef PEER_DADDR @@ -1782,8 +1770,8 @@ hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni, IEEE80211_ADDR_COPY(preq.preq_targets[0].target_addr, rann->rann_addr); preq.preq_targets[0].target_seq = rann->rann_seq; /* XXX: if rootconfint have not passed, we built this preq in vain */ - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, wh->i_addr2, &preq, - &hr->hr_lastrootconf, &ieee80211_hwmp_rootconfint); + hwmp_send_preq(vap, wh->i_addr2, &preq, &hr->hr_lastrootconf, + &ieee80211_hwmp_rootconfint); /* propagate a RANN */ if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID && @@ -1794,14 +1782,12 @@ hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni, 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); + hwmp_send_rann(vap, broadcastaddr, &prann); } } static int -hwmp_send_rann(struct ieee80211_node *ni, - const uint8_t sa[IEEE80211_ADDR_LEN], +hwmp_send_rann(struct ieee80211vap *vap, const uint8_t da[IEEE80211_ADDR_LEN], struct ieee80211_meshrann_ie *rann) { @@ -1816,8 +1802,7 @@ hwmp_send_rann(struct ieee80211_node *ni, */ rann->rann_ie = IEEE80211_ELEMID_MESHRANN; rann->rann_len = IEEE80211_MESHRANN_BASE_SZ; - return hwmp_send_action(ni, sa, da, (uint8_t *)rann, - rann->rann_len + 2); + return hwmp_send_action(vap, da, (uint8_t *)rann, rann->rann_len + 2); } #define PREQ_TFLAGS(n) preq.preq_targets[n].target_flags @@ -1872,9 +1857,8 @@ hwmp_rediscover_cb(void *arg) PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN; PREQ_TSEQ(0) = 0; /* RESERVED when USN flag is set */ /* XXX check return value */ - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &preq, &hr->hr_lastpreq, - &ieee80211_hwmp_preqminint); + hwmp_send_preq(vap, broadcastaddr, &preq, &hr->hr_lastpreq, + &ieee80211_hwmp_preqminint); callout_reset(&rt->rt_discovery, ieee80211_hwmp_net_diameter_traversaltime * 2, hwmp_rediscover_cb, rt); @@ -1970,9 +1954,8 @@ hwmp_discover(struct ieee80211vap *vap, PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN; PREQ_TSEQ(0) = 0; /* RESERVED when USN flag is set */ /* XXX check return value */ - hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, - broadcastaddr, &preq, &hr->hr_lastpreq, - &ieee80211_hwmp_preqminint); + hwmp_send_preq(vap, broadcastaddr, &preq, + &hr->hr_lastpreq, &ieee80211_hwmp_preqminint); callout_reset(&rt->rt_discovery, ieee80211_hwmp_net_diameter_traversaltime * 2, hwmp_rediscover_cb, rt); |