summaryrefslogtreecommitdiffstats
path: root/sys/net80211/ieee80211_hwmp.c
diff options
context:
space:
mode:
authormonthadar <monthadar@FreeBSD.org>2012-05-01 16:03:27 +0000
committermonthadar <monthadar@FreeBSD.org>2012-05-01 16:03:27 +0000
commit84762f9912d819ed0724d0a481965e50a463957e (patch)
tree6f064c0d83564ebca2a6c8137e31044e3c8edf73 /sys/net80211/ieee80211_hwmp.c
parent3e48b3819f05a81690c262194c3084ce774f1509 (diff)
downloadFreeBSD-src-84762f9912d819ed0724d0a481965e50a463957e.zip
FreeBSD-src-84762f9912d819ed0724d0a481965e50a463957e.tar.gz
Change how we enforce PREQ minimum interval.
* Moved hs_lastpreq to be hr_lastpreq cause this rate check should be per target mesh STA according to amendment (NB: not applicable for PERR); * Modified hwmp_send_preq to use two extra arguments for last sent PREQ and minimum PREQ interval; * hwmp_send_preq is called with last two arguments equal to NULL when sending Proactive PREQs cause the call back task enforces the rate check; Approved by: adrian
Diffstat (limited to 'sys/net80211/ieee80211_hwmp.c')
-rw-r--r--sys/net80211/ieee80211_hwmp.c57
1 files changed, 33 insertions, 24 deletions
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 4ea61b1..54e3c39 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -89,7 +89,8 @@ static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
static int hwmp_send_preq(struct ieee80211_node *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN],
- struct ieee80211_meshpreq_ie *);
+ 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 *);
@@ -152,14 +153,14 @@ 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_origseq; /* seq. no. on our latest PREQ*/
+ struct timeval hr_lastpreq; /* last time we sent a PREQ */
int hr_preqretries;
};
struct ieee80211_hwmp_state {
ieee80211_hwmp_seq hs_seq; /* next seq to be used */
ieee80211_hwmp_seq hs_preqid; /* next PREQ ID to be used */
- struct timeval hs_lastpreq; /* last time we sent a PREQ */
- struct timeval hs_lastperr; /* last time we sent a PERR */
int hs_rootmode; /* proactive HWMP */
+ struct timeval hs_lastperr; /* last time we sent a PERR */
struct callout hs_roottimer;
uint8_t hs_maxhops; /* max hop count */
};
@@ -824,7 +825,8 @@ hwmp_rootmode_cb(void *arg)
IEEE80211_MESHPREQ_TFLAGS_RF;
PREQ_TSEQ(0) = 0;
vap->iv_stats.is_hwmp_rootreqs++;
- hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq);
+ hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq,
+ NULL, NULL); /* NB: we enforce rate check ourself */
hwmp_rootmode_setup(vap);
}
#undef PREQ_TFLAGS
@@ -1051,7 +1053,6 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
hwmp_discover(vap, rootmac, NULL);
return;
}
- rt = ieee80211_mesh_rt_find(vap, PREQ_TADDR(0));
/*
* Forwarding and Intermediate reply for PREQs with 1 target.
@@ -1063,8 +1064,8 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
/*
* We have a valid route to this node.
*/
- if (rt != NULL &&
- (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) {
+ if (rttarg != NULL &&
+ (rttarg->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)) {
if (preq->preq_ttl > 1 &&
preq->preq_hopcount < hs->hs_maxhops) {
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
@@ -1072,7 +1073,7 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
preq->preq_origaddr, ":");
/*
* Propagate the original PREQ.
- * PREQ is unicast now to rt->rt_nexthop
+ * PREQ is unicast now to rttarg->rt_nexthop
*/
ppreq.preq_flags &=
~IEEE80211_MESHPREQ_FLAGS_AM;
@@ -1089,7 +1090,9 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
ppreq.preq_targets[0].target_flags &=
~IEEE80211_MESHPREQ_TFLAGS_RF;
hwmp_send_preq(ni, vap->iv_myaddr,
- rt->rt_nexthop, &ppreq);
+ rttarg->rt_nexthop, &ppreq,
+ &hrtarg->hr_lastpreq,
+ &ieee80211_hwmp_preqminint);
}
/*
* Check if we can send an intermediate Path Reply,
@@ -1122,9 +1125,10 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
*/
} else if (preq->preq_ttl > 1 &&
preq->preq_hopcount < hs->hs_maxhops) {
- if (rt == NULL) {
- rt = ieee80211_mesh_rt_add(vap, PREQ_TADDR(0));
- if (rt == NULL) {
+ if (rttarg == NULL) {
+ rttarg =
+ ieee80211_mesh_rt_add(vap, PREQ_TADDR(0));
+ if (rttarg == NULL) {
IEEE80211_NOTE(vap,
IEEE80211_MSG_HWMP, ni,
"unable to add PREQ path to %6D",
@@ -1133,12 +1137,12 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
return;
}
}
- rt->rt_metric = preq->preq_metric;
- ieee80211_mesh_rt_update(rt, preq->preq_lifetime);
- hrorig = IEEE80211_MESH_ROUTE_PRIV(rt,
+ rttarg->rt_metric = preq->preq_metric;
+ ieee80211_mesh_rt_update(rttarg, preq->preq_lifetime);
+ hrtarg = IEEE80211_MESH_ROUTE_PRIV(rttarg,
struct ieee80211_hwmp_route);
- hrorig->hr_seq = preq->preq_origseq;
- hrorig->hr_preqid = preq->preq_id;
+ hrtarg->hr_seq = PREQ_TSEQ(0);
+ hrtarg->hr_preqid = preq->preq_id;
IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
"forward PREQ from %6D",
@@ -1147,7 +1151,8 @@ hwmp_recv_preq(struct ieee80211vap *vap, struct ieee80211_node *ni,
ppreq.preq_ttl -= 1;
ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni);
hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr,
- &ppreq);
+ &ppreq, &hrtarg->hr_lastpreq,
+ &ieee80211_hwmp_preqminint);
}
}
}
@@ -1159,16 +1164,19 @@ static int
hwmp_send_preq(struct ieee80211_node *ni,
const uint8_t sa[IEEE80211_ADDR_LEN],
const uint8_t da[IEEE80211_ADDR_LEN],
- struct ieee80211_meshpreq_ie *preq)
+ struct ieee80211_meshpreq_ie *preq,
+ struct timeval *last, struct timeval *minint)
{
- struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp;
/*
* Enforce PREQ interval.
+ * NB: Proactive ROOT PREQs rate is handled by cb task.
*/
- if (ratecheck(&hs->hs_lastpreq, &ieee80211_hwmp_preqminint) == 0)
- return EALREADY;
- getmicrouptime(&hs->hs_lastpreq);
+ if (last != NULL && minint != NULL) {
+ if (ratecheck(last, minint) == 0)
+ return EALREADY; /* XXX: we should postpone */
+ getmicrouptime(last);
+ }
/*
* mesh preq action frame format
@@ -1677,7 +1685,8 @@ hwmp_discover(struct ieee80211vap *vap,
PREQ_TSEQ(0) = hr->hr_seq;
/* XXX check return value */
hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
- broadcastaddr, &preq);
+ broadcastaddr, &preq, &hr->hr_lastpreq,
+ &ieee80211_hwmp_preqminint);
}
if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID)
ni = ieee80211_find_txnode(vap, rt->rt_nexthop);
OpenPOWER on IntegriCloud