summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormonthadar <monthadar@FreeBSD.org>2012-05-01 16:12:39 +0000
committermonthadar <monthadar@FreeBSD.org>2012-05-01 16:12:39 +0000
commit730d2de83b0e430a8391d9bf541db9868ccf1394 (patch)
tree9646b9dc3267150145013ed887e0862a4a5fdfe8
parent1b62f837a74de5f2bce3d3333e5b82ecae62a36e (diff)
downloadFreeBSD-src-730d2de83b0e430a8391d9bf541db9868ccf1394.zip
FreeBSD-src-730d2de83b0e430a8391d9bf541db9868ccf1394.tar.gz
PERR update to be called from mesh code.
* Added mpp_senderror for Mesh Path Selection protocol; * Added hwmp_senderror that will send an HWMP PERR according to the supplied reason code; * Call mpp_senderror when deleting a route with correct reason code for whether the route is marked proxy or not; * Call mpp_senderror when trying to forward an individually addressed frame and there is no forwarding information; Approved by: adrian
-rw-r--r--sys/net80211/ieee80211_hwmp.c64
-rw-r--r--sys/net80211/ieee80211_mesh.c11
-rw-r--r--sys/net80211/ieee80211_mesh.h3
3 files changed, 76 insertions, 2 deletions
diff --git a/sys/net80211/ieee80211_hwmp.c b/sys/net80211/ieee80211_hwmp.c
index 8fee349..61a92c0 100644
--- a/sys/net80211/ieee80211_hwmp.c
+++ b/sys/net80211/ieee80211_hwmp.c
@@ -105,6 +105,9 @@ static int hwmp_send_perr(struct ieee80211_node *,
const uint8_t [IEEE80211_ADDR_LEN],
const uint8_t [IEEE80211_ADDR_LEN],
struct ieee80211_meshperr_ie *);
+static void hwmp_senderror(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN],
+ struct ieee80211_mesh_route *, int);
static void hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_frame *,
const struct ieee80211_meshrann_ie *);
@@ -206,6 +209,7 @@ static struct ieee80211_mesh_proto_path mesh_proto_hwmp = {
.mpp_ie = IEEE80211_MESHCONF_PATH_HWMP,
.mpp_discover = hwmp_discover,
.mpp_peerdown = hwmp_peerdown,
+ .mpp_senderror = hwmp_senderror,
.mpp_vattach = hwmp_vattach,
.mpp_vdetach = hwmp_vdetach,
.mpp_newstate = hwmp_newstate,
@@ -1569,7 +1573,7 @@ done:
free(pperr, M_80211_MESH_PERR);
}
#undef PERR_DFLAGS
-#undef PEER_DADDR
+#undef PERR_DADDR
#undef PERR_DSEQ
#undef PERR_DEXTADDR
#undef PERR_DRCODE
@@ -1614,6 +1618,64 @@ hwmp_send_perr(struct ieee80211_node *ni,
return hwmp_send_action(ni, sa, da, (uint8_t *)perr, perr->perr_len+2);
}
+/*
+ * Called from the rest of the net80211 code (mesh code for example).
+ * NB: IEEE80211_REASON_MESH_PERR_DEST_UNREACH can be trigger by the fact that
+ * a mesh STA is unable to forward an MSDU/MMPDU to a next-hop mesh STA.
+ */
+#define PERR_DFLAGS(n) perr.perr_dests[n].dest_flags
+#define PERR_DADDR(n) perr.perr_dests[n].dest_addr
+#define PERR_DSEQ(n) perr.perr_dests[n].dest_seq
+#define PERR_DEXTADDR(n) perr.perr_dests[n].dest_ext_addr
+#define PERR_DRCODE(n) perr.perr_dests[n].dest_rcode
+static void
+hwmp_senderror(struct ieee80211vap *vap,
+ const uint8_t addr[IEEE80211_ADDR_LEN],
+ struct ieee80211_mesh_route *rt, int rcode)
+{
+ struct ieee80211_mesh_state *ms = vap->iv_mesh;
+ struct ieee80211_hwmp_route *hr = NULL;
+ struct ieee80211_meshperr_ie perr;
+
+ if (rt != NULL)
+ hr = IEEE80211_MESH_ROUTE_PRIV(rt,
+ struct ieee80211_hwmp_route);
+
+ perr.perr_ndests = 1;
+ perr.perr_ttl = ms->ms_ttl;
+ PERR_DFLAGS(0) = 0;
+ PERR_DRCODE(0) = rcode;
+
+ switch (rcode) {
+ case IEEE80211_REASON_MESH_PERR_NO_FI:
+ IEEE80211_ADDR_COPY(PERR_DADDR(0), addr);
+ PERR_DSEQ(0) = 0; /* reserved */
+ break;
+ case IEEE80211_REASON_MESH_PERR_NO_PROXY:
+ KASSERT(rt != NULL, ("no proxy info for sending PERR"));
+ KASSERT(rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY,
+ ("route is not marked proxy"));
+ PERR_DFLAGS(0) |= IEEE80211_MESHPERR_FLAGS_AE;
+ IEEE80211_ADDR_COPY(PERR_DADDR(0), vap->iv_myaddr);
+ PERR_DSEQ(0) = rt->rt_ext_seq;
+ IEEE80211_ADDR_COPY(PERR_DEXTADDR(0), addr);
+ break;
+ case IEEE80211_REASON_MESH_PERR_DEST_UNREACH:
+ KASSERT(rt != NULL, ("no route info for sending PERR"));
+ IEEE80211_ADDR_COPY(PERR_DADDR(0), addr);
+ PERR_DSEQ(0) = hr->hr_seq;
+ break;
+ default:
+ KASSERT(0, ("unknown reason code for HWMP PERR (%u)", rcode));
+ }
+ hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
+}
+#undef PERR_DFLAGS
+#undef PEER_DADDR
+#undef PERR_DSEQ
+#undef PERR_DEXTADDR
+#undef PERR_DRCODE
+
static void
hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_meshrann_ie *rann)
diff --git a/sys/net80211/ieee80211_mesh.c b/sys/net80211/ieee80211_mesh.c
index c533491..3cc0d3e 100644
--- a/sys/net80211/ieee80211_mesh.c
+++ b/sys/net80211/ieee80211_mesh.c
@@ -344,6 +344,13 @@ ieee80211_mesh_rt_del(struct ieee80211vap *vap,
MESH_RT_LOCK(ms);
TAILQ_FOREACH_SAFE(rt, &ms->ms_routes, rt_next, next) {
if (IEEE80211_ADDR_EQ(rt->rt_dest, dest)) {
+ if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_PROXY) {
+ ms->ms_ppath->mpp_senderror(vap, dest, rt,
+ IEEE80211_REASON_MESH_PERR_NO_PROXY);
+ } else {
+ ms->ms_ppath->mpp_senderror(vap, dest, rt,
+ IEEE80211_REASON_MESH_PERR_DEST_UNREACH);
+ }
mesh_rt_del(ms, rt);
MESH_RT_UNLOCK(ms);
return;
@@ -972,10 +979,12 @@ mesh_forward(struct ieee80211vap *vap, struct mbuf *m,
* [Optional] any of the following three actions:
* o silently discard
* o trigger a path discovery
- * o inform TA that meshDA is unreachable.
+ * o inform TA that meshDA is unknown.
*/
IEEE80211_NOTE_FRAME(vap, IEEE80211_MSG_MESH, wh,
"%s", "frame not fwd'd, no path");
+ ms->ms_ppath->mpp_senderror(vap, whcopy->i_addr3, NULL,
+ IEEE80211_REASON_MESH_PERR_NO_FI);
vap->iv_stats.is_mesh_fwd_nopath++;
m_freem(mcopy);
return;
diff --git a/sys/net80211/ieee80211_mesh.h b/sys/net80211/ieee80211_mesh.h
index 7501faf..c69764c 100644
--- a/sys/net80211/ieee80211_mesh.h
+++ b/sys/net80211/ieee80211_mesh.h
@@ -449,6 +449,9 @@ struct ieee80211_mesh_proto_path {
const uint8_t [IEEE80211_ADDR_LEN],
struct mbuf *);
void (*mpp_peerdown)(struct ieee80211_node *);
+ void (*mpp_senderror)(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN],
+ struct ieee80211_mesh_route *, int);
void (*mpp_vattach)(struct ieee80211vap *);
void (*mpp_vdetach)(struct ieee80211vap *);
int (*mpp_newstate)(struct ieee80211vap *,
OpenPOWER on IntegriCloud