svn commit: r195108 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Sat Jun 27 16:28:43 UTC 2009
Author: rpaulo
Date: Sat Jun 27 16:28:42 2009
New Revision: 195108
URL: http://svn.freebsd.org/changeset/base/195108
Log:
* handle path errors
* reduce code duplication in ioctl handling.
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_hwmp.c
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Sat Jun 27 16:26:59 2009 (r195107)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Sat Jun 27 16:28:42 2009 (r195108)
@@ -69,6 +69,8 @@ static struct ieee80211_hwmp_fi *
static struct ieee80211_hwmp_fi *
hwmp_rt_add(struct ieee80211vap *,
const uint8_t [IEEE80211_ADDR_LEN]);
+static void hwmp_rt_del(struct ieee80211vap *,
+ const uint8_t [IEEE80211_ADDR_LEN]);
static void hwmp_rt_flush(struct ieee80211vap *);
static int ieee80211_hwmp_send_action(struct ieee80211_node *,
const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
@@ -179,6 +181,25 @@ hwmp_rt_add(struct ieee80211vap *vap, co
}
static void
+hwmp_rt_del(struct ieee80211vap *vap, const uint8_t dest[IEEE80211_ADDR_LEN])
+{
+ struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
+ struct ieee80211_hwmp_fi *fi, *next;
+
+ KASSERT(hs != NULL, ("no HWMP state"));
+ HWMP_LOCK(hs);
+ TAILQ_FOREACH_SAFE(fi, &hs->hs_head, fi_next, next) {
+ if (IEEE80211_ADDR_EQ(fi->fi_dest, dest)) {
+ TAILQ_REMOVE(&hs->hs_head, fi, fi_next);
+ free(fi, M_80211_HWMP);
+ HWMP_UNLOCK(hs);
+ return;
+ }
+ }
+ HWMP_UNLOCK(hs);
+}
+
+static void
hwmp_rt_flush(struct ieee80211vap *vap)
{
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
@@ -850,34 +871,45 @@ hwmp_send_prep(struct ieee80211_node *ni
}
#define PERR_DADDR(n) perr->perr_dests[n].dest_addr
-#define PREQ_DSEQ(n) perr->perr_dests[n].dest_seq
+#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq
static void
hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_frame *wh, const struct ieee80211_meshperr_ie *perr)
{
struct ieee80211_mesh_state *ms = vap->iv_mesh;
struct ieee80211_hwmp_fi *fi = NULL;
-/* struct ieee80211_meshperr_ie pperr;*/
+ struct ieee80211_meshperr_ie pperr;
+ int i;
/*
* Acceptance criteria: check if we received a PERR from a
- * neighbor and forwarding is 1.
+ * neighbor and forwarding is enabled.
*/
if (ni == vap->iv_bss ||
ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED ||
!(ms->ms_flags & IEEE80211_MESHFLAGS_FWD))
return;
- fi = hwmp_rt_find(vap, PERR_DADDR(0));
-
- if (fi == NULL)
- return;
-
+ for (i = 0; i < perr->perr_ndests; i++) {
+ fi = hwmp_rt_find(vap, PERR_DADDR(i));
+ if (fi == NULL)
+ break;
+ if (PERR_DSEQ(i) > fi->fi_seq) {
+ hwmp_rt_del(vap, fi->fi_dest);
+ fi = NULL;
+ }
+ }
/*
* Propagate the PERR.
+ * XXX handle ndest > 1
*/
-
+ IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
+ "propagating PERR from %s", ether_sprintf(wh->i_addr2));
+ memcpy(&pperr, perr, sizeof(*perr));
+ hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &pperr);
}
+#undef PEER_DADDR
+#undef PERR_DSEQ
static inline int
hwmp_send_perr(struct ieee80211_node *ni,
@@ -1053,6 +1085,7 @@ ieee80211_hwmp_discover(struct ieee80211
ni = ieee80211_find_txnode(vap, fi->fi_nexthop);
} else {
ni = ieee80211_find_txnode(vap, dest);
+ return ni;
}
done:
if (ni == NULL && m != NULL) {
@@ -1161,7 +1194,6 @@ static int
hwmp_ioctl_set80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
- struct ieee80211_hwmp_fi *fi, *next;
int error;
if (vap->iv_opmode != IEEE80211_M_MBSS)
@@ -1176,24 +1208,10 @@ hwmp_ioctl_set80211(struct ieee80211vap
hwmp_rt_flush(vap);
break;
case IEEE80211_HWMP_CMD_ADD:
- HWMP_LOCK(hs);
- TAILQ_FOREACH(fi, &hs->hs_head, fi_next) {
- if (IEEE80211_ADDR_EQ(fi->fi_dest,
- ireq->i_data))
- return EINVAL;
- }
- HWMP_UNLOCK(hs);
+ hwmp_rt_add(vap, ireq->i_data);
break;
case IEEE80211_HWMP_CMD_DELETE:
- HWMP_LOCK(hs);
- TAILQ_FOREACH_SAFE(fi, &hs->hs_head, fi_next, next) {
- if (IEEE80211_ADDR_EQ(fi->fi_dest,
- ireq->i_data)) {
- TAILQ_REMOVE(&hs->hs_head, fi, fi_next);
- free(fi, M_80211_HWMP);
- }
- }
- HWMP_UNLOCK(hs);
+ hwmp_rt_del(vap, ireq->i_data);
break;
default:
return ENOSYS;
More information about the svn-src-projects
mailing list