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