Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 30 Oct 2009 19:59:50 +0000 (UTC)
From:      Rui Paulo <rpaulo@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org
Subject:   svn commit: r198699 - in stable/8/sys: . amd64/include/xen cddl/contrib/opensolaris contrib/dev/acpica contrib/pf dev/xen/xenpci net80211
Message-ID:  <200910301959.n9UJxocG056188@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rpaulo
Date: Fri Oct 30 19:59:50 2009
New Revision: 198699
URL: http://svn.freebsd.org/changeset/base/198699

Log:
  MFC r198230, r198242, r198260, r198346, r198369, r198384:
  
      More mesh fixes to comply with latest draft.

Modified:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)
  stable/8/sys/net80211/ieee80211_hwmp.c
  stable/8/sys/net80211/ieee80211_mesh.c
  stable/8/sys/net80211/ieee80211_mesh.h
  stable/8/sys/net80211/ieee80211_output.c
  stable/8/sys/net80211/ieee80211_proto.h

Modified: stable/8/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- stable/8/sys/net80211/ieee80211_hwmp.c	Fri Oct 30 19:25:13 2009	(r198698)
+++ stable/8/sys/net80211/ieee80211_hwmp.c	Fri Oct 30 19:59:50 2009	(r198699)
@@ -148,7 +148,7 @@ typedef uint32_t ieee80211_hwmp_seq;
 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_targetseq;	/* seq. no. on our latest PREQ*/
+	ieee80211_hwmp_seq	hr_origseq;	/* seq. no. on our latest PREQ*/
 	int			hr_preqretries;
 };
 struct ieee80211_hwmp_state {
@@ -548,7 +548,7 @@ hwmp_add_meshperr(uint8_t *frm, const st
 	*frm++ = perr->perr_ttl;
 	*frm++ = perr->perr_ndests;
 	for (i = 0; i < perr->perr_ndests; i++) {
-		*frm += perr->perr_dests[i].dest_flags;
+		*frm++ = perr->perr_dests[i].dest_flags;
 		IEEE80211_ADDR_COPY(frm, perr->perr_dests[i].dest_addr);
 		frm += 6;
 		ADDWORD(frm, perr->perr_dests[i].dest_seq);
@@ -653,6 +653,7 @@ hwmp_rootmode_rann_cb(void *arg)
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, vap->iv_bss,
 	    "%s", "send broadcast RANN");
 
+	rann.rann_flags = 0;
 	if (ms->ms_flags & IEEE80211_MESHFLAGS_PORTAL)
 		rann.rann_flags |= IEEE80211_MESHRANN_FLAGS_PR;
 	rann.rann_hopcount = 0;
@@ -733,12 +734,12 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		prep.prep_flags = 0;
 		prep.prep_hopcount = 0;
 		prep.prep_ttl = ms->ms_ttl;
-		IEEE80211_ADDR_COPY(prep.prep_targetaddr, preq->preq_origaddr);
-		prep.prep_targetseq = preq->preq_origseq;
+		IEEE80211_ADDR_COPY(prep.prep_targetaddr, vap->iv_myaddr);
+		prep.prep_targetseq = ++hs->hs_seq;
 		prep.prep_lifetime = preq->preq_lifetime;
 		prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
-		IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr);
-		prep.prep_origseq = ++hs->hs_seq;
+		IEEE80211_ADDR_COPY(prep.prep_origaddr, preq->preq_origaddr);
+		prep.prep_origseq = preq->preq_origseq;
 		hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep);
 		/*
 		 * Build the reverse path, if we don't have it already.
@@ -784,13 +785,13 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			prep.prep_flags = 0;
 			prep.prep_hopcount = 0;
 			prep.prep_ttl = ms->ms_ttl;
-			IEEE80211_ADDR_COPY(prep.prep_origaddr, vap->iv_myaddr);
+			IEEE80211_ADDR_COPY(prep.prep_origaddr, rootmac);
 			prep.prep_origseq = preq->preq_origseq;
-			prep.prep_targetseq = ++hs->hs_seq;
 			prep.prep_lifetime = preq->preq_lifetime;
 			prep.prep_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
-			IEEE80211_ADDR_COPY(prep.prep_targetaddr, rootmac);
-			prep.prep_targetseq = PREQ_TSEQ(0);
+			IEEE80211_ADDR_COPY(prep.prep_targetaddr,
+			    vap->iv_myaddr);
+			prep.prep_targetseq = ++hs->hs_seq;
 			hwmp_send_prep(vap->iv_bss, vap->iv_myaddr,
 			    broadcastaddr, &prep);
 		}
@@ -848,13 +849,13 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				prep.prep_hopcount = rt->rt_nhops + 1;
 				prep.prep_ttl = ms->ms_ttl;
 				IEEE80211_ADDR_COPY(&prep.prep_targetaddr,
-				    preq->preq_origaddr);
+				    PREQ_TADDR(0));
 				prep.prep_targetseq = hrorig->hr_seq;
 				prep.prep_lifetime = preq->preq_lifetime;
 				prep.prep_metric = rt->rt_metric +
 				    ms->ms_pmetric->mpm_metric(ni);
 				IEEE80211_ADDR_COPY(&prep.prep_origaddr,
-				    PREQ_TADDR(0));
+				    preq->preq_origaddr);
 				prep.prep_origseq = hrorig->hr_seq;
 				hwmp_send_prep(ni, vap->iv_myaddr,
 				    broadcastaddr, &prep);
@@ -951,19 +952,19 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		return;
 
 	IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
-	    "received PREP from %s", ether_sprintf(prep->prep_origaddr));
+	    "received PREP from %s", ether_sprintf(prep->prep_targetaddr));
 
-	rt = ieee80211_mesh_rt_find(vap, prep->prep_origaddr);
+	rt = ieee80211_mesh_rt_find(vap, prep->prep_targetaddr);
 	if (rt == NULL) {
 		/*
 		 * If we have no entry this could be a reply to a root PREQ.
 		 */
 		if (hs->hs_rootmode != IEEE80211_HWMP_ROOTMODE_DISABLED) {
-			rt = ieee80211_mesh_rt_add(vap, prep->prep_origaddr);
+			rt = ieee80211_mesh_rt_add(vap, prep->prep_targetaddr);
 			if (rt == NULL) {
 				IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP,
 				    ni, "unable to add PREP path to %s",
-				    ether_sprintf(prep->prep_origaddr));
+				    ether_sprintf(prep->prep_targetaddr));
 				vap->iv_stats.is_mesh_rtaddfailed++;
 				return;
 			}
@@ -974,7 +975,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 			rt->rt_flags |= IEEE80211_MESHRT_FLAGS_VALID;
 			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 			    "add root path to %s nhops %d metric %d (PREP)",
-			    ether_sprintf(prep->prep_origaddr),
+			    ether_sprintf(prep->prep_targetaddr),
 			    rt->rt_nhops, rt->rt_metric);
 			return;
 		} 
@@ -984,30 +985,30 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 	 * Sequence number validation.
 	 */
 	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
-	if (HWMP_SEQ_LEQ(prep->prep_origseq, hr->hr_seq)) {
+	if (HWMP_SEQ_LEQ(prep->prep_targetseq, hr->hr_seq)) {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "discard PREP from %s, old seq no %u <= %u",
-		    ether_sprintf(prep->prep_origaddr),
-		    prep->prep_origseq, hr->hr_seq);
+		    ether_sprintf(prep->prep_targetaddr),
+		    prep->prep_targetseq, hr->hr_seq);
 		return;
 	}
-	hr->hr_seq = prep->prep_origseq;
+	hr->hr_seq = prep->prep_targetseq;
 	/*
 	 * If it's NOT for us, propagate the PREP.
 	 */
-	if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_targetaddr) &&
+	if (!IEEE80211_ADDR_EQ(vap->iv_myaddr, prep->prep_origaddr) &&
 	    prep->prep_ttl > 1 && prep->prep_hopcount < hs->hs_maxhops) {
 		struct ieee80211_meshprep_ie pprep; /* propagated PREP */
 
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "propagate PREP from %s",
-		    ether_sprintf(prep->prep_origaddr));
+		    ether_sprintf(prep->prep_targetaddr));
 
 		memcpy(&pprep, prep, sizeof(pprep));
 		pprep.prep_hopcount += 1;
 		pprep.prep_ttl -= 1;
 		pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni);
-		IEEE80211_ADDR_COPY(pprep.prep_origaddr, vap->iv_myaddr);
+		IEEE80211_ADDR_COPY(pprep.prep_targetaddr, vap->iv_myaddr);
 		hwmp_send_prep(ni, vap->iv_myaddr, broadcastaddr, &pprep);
 	}
 	hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route);
@@ -1015,9 +1016,9 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		/* NB: never clobber a proxy entry */;
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "discard PREP for %s, route is marked PROXY",
-		    ether_sprintf(prep->prep_origaddr));
+		    ether_sprintf(prep->prep_targetaddr));
 		vap->iv_stats.is_hwmp_proxy++;
-	} else if (prep->prep_targetseq == hr->hr_targetseq) {
+	} else if (prep->prep_origseq == hr->hr_origseq) {
 		/*
 		 * Check if we already have a path to this node.
 		 * If we do, check if this path reply contains a
@@ -1041,14 +1042,14 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		} else {
 			IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 			    "ignore PREP for %s, hopcount %d:%d metric %d:%d",
-			    ether_sprintf(prep->prep_origaddr),
+			    ether_sprintf(prep->prep_targetaddr),
 			    rt->rt_nhops, prep->prep_hopcount,
 			    rt->rt_metric, prep->prep_metric);
 		}
 	} else {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "discard PREP for %s, wrong seqno %u != %u",
-		    ether_sprintf(prep->prep_origaddr), prep->prep_targetseq,
+		    ether_sprintf(prep->prep_targetaddr), prep->prep_origseq,
 		    hr->hr_seq);
 		vap->iv_stats.is_hwmp_wrongseq++;
 	} 
@@ -1114,6 +1115,7 @@ hwmp_peerdown(struct ieee80211_node *ni)
 	    "%s", "delete route entry");
 	perr.perr_ttl = ms->ms_ttl;
 	perr.perr_ndests = 1;
+	PERR_DFLAGS(0) = 0;
 	if (hr->hr_seq == 0)
 		PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN;
 	PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC;
@@ -1223,7 +1225,8 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 	struct ieee80211_meshrann_ie prann;
 
 	if (ni == vap->iv_bss ||
-	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED)
+	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED ||
+	    IEEE80211_ADDR_EQ(rann->rann_addr, vap->iv_myaddr))
 		return;
 
 	rt = ieee80211_mesh_rt_find(vap, rann->rann_addr);
@@ -1305,8 +1308,8 @@ hwmp_discover(struct ieee80211vap *vap,
 		hr = IEEE80211_MESH_ROUTE_PRIV(rt,
 		    struct ieee80211_hwmp_route);
 		if ((rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) == 0) {
-			if (hr->hr_targetseq == 0)
-				hr->hr_targetseq = ++hs->hs_seq;
+			if (hr->hr_origseq == 0)
+				hr->hr_origseq = ++hs->hs_seq;
 			rt->rt_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
 			rt->rt_lifetime =
 			    ticks_to_msecs(ieee80211_hwmp_pathtimeout);
@@ -1324,7 +1327,7 @@ hwmp_discover(struct ieee80211vap *vap,
 			preq.preq_ttl = ms->ms_ttl;
 			preq.preq_id = ++hs->hs_preqid;
 			IEEE80211_ADDR_COPY(preq.preq_origaddr, vap->iv_myaddr);
-			preq.preq_origseq = hr->hr_targetseq;
+			preq.preq_origseq = hr->hr_origseq;
 			preq.preq_lifetime = rt->rt_lifetime;
 			preq.preq_metric = rt->rt_metric;
 			preq.preq_tcount = 1;

Modified: stable/8/sys/net80211/ieee80211_mesh.c
==============================================================================
--- stable/8/sys/net80211/ieee80211_mesh.c	Fri Oct 30 19:25:13 2009	(r198698)
+++ stable/8/sys/net80211/ieee80211_mesh.c	Fri Oct 30 19:59:50 2009	(r198699)
@@ -388,8 +388,6 @@ mesh_select_proto_path(struct ieee80211v
 	for (i = 0; i < N(mesh_proto_paths); i++) {
 		if (strcasecmp(mesh_proto_paths[i].mpp_descr, name) == 0) {
 			ms->ms_ppath = &mesh_proto_paths[i];
-			if (vap->iv_state == IEEE80211_S_RUN)
-				vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
 			return 0;
 		}
 	}
@@ -405,8 +403,6 @@ mesh_select_proto_metric(struct ieee8021
 	for (i = 0; i < N(mesh_proto_metrics); i++) {
 		if (strcasecmp(mesh_proto_metrics[i].mpm_descr, name) == 0) {
 			ms->ms_pmetric = &mesh_proto_metrics[i];
-			if (vap->iv_state == IEEE80211_S_RUN)
-				vap->iv_newstate(vap, IEEE80211_S_INIT, 0);
 			return 0;
 		}
 	}
@@ -739,10 +735,12 @@ mesh_linkchange(struct ieee80211_node *n
 	    ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) {
 		KASSERT(ms->ms_neighbors < 65535, ("neighbor count overflow"));
 		ms->ms_neighbors++;
+		ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF);
 	} else if (ni->ni_mlstate == IEEE80211_NODE_MESH_ESTABLISHED &&
 	    state != IEEE80211_NODE_MESH_ESTABLISHED) {
 		KASSERT(ms->ms_neighbors > 0, ("neighbor count 0"));
 		ms->ms_neighbors--;
+		ieee80211_beacon_notify(vap, IEEE80211_BEACON_MESHCONF);
 	}
 	ni->ni_mlstate = state;
 	switch (state) {
@@ -2552,6 +2550,18 @@ ieee80211_mesh_init_neighbor(struct ieee
 	ieee80211_parse_meshid(ni, sp->meshid);
 }
 
+void
+ieee80211_mesh_update_beacon(struct ieee80211vap *vap,
+	struct ieee80211_beacon_offsets *bo)
+{
+	KASSERT(vap->iv_opmode == IEEE80211_M_MBSS, ("not a MBSS vap"));
+
+	if (isset(bo->bo_flags, IEEE80211_BEACON_MESHCONF)) {
+		(void)ieee80211_add_meshconf(bo->bo_meshconf, vap);
+		clrbit(bo->bo_flags, IEEE80211_BEACON_MESHCONF);
+	}
+}
+
 static int
 mesh_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
 {

Modified: stable/8/sys/net80211/ieee80211_mesh.h
==============================================================================
--- stable/8/sys/net80211/ieee80211_mesh.h	Fri Oct 30 19:25:13 2009	(r198698)
+++ stable/8/sys/net80211/ieee80211_mesh.h	Fri Oct 30 19:59:50 2009	(r198699)
@@ -470,6 +470,8 @@ struct ieee80211_scanparams;
 void		ieee80211_mesh_init_neighbor(struct ieee80211_node *,
 		   const struct ieee80211_frame *,
 		   const struct ieee80211_scanparams *);
+void		ieee80211_mesh_update_beacon(struct ieee80211vap *,
+		    struct ieee80211_beacon_offsets *);
 
 /*
  * Return non-zero if proxy operation is enabled.

Modified: stable/8/sys/net80211/ieee80211_output.c
==============================================================================
--- stable/8/sys/net80211/ieee80211_output.c	Fri Oct 30 19:25:13 2009	(r198698)
+++ stable/8/sys/net80211/ieee80211_output.c	Fri Oct 30 19:59:50 2009	(r198699)
@@ -2658,6 +2658,7 @@ ieee80211_beacon_construct(struct mbuf *
 #ifdef IEEE80211_SUPPORT_MESH
 	if (vap->iv_opmode == IEEE80211_M_MBSS) {
 		frm = ieee80211_add_meshid(frm, vap);
+		bo->bo_meshconf = frm;
 		frm = ieee80211_add_meshconf(frm, vap);
 	}
 #endif
@@ -2763,13 +2764,7 @@ ieee80211_beacon_alloc(struct ieee80211_
 	*(uint16_t *)wh->i_dur = 0;
 	IEEE80211_ADDR_COPY(wh->i_addr1, ifp->if_broadcastaddr);
 	IEEE80211_ADDR_COPY(wh->i_addr2, vap->iv_myaddr);
-#ifdef IEEE80211_SUPPORT_MESH
-	if (vap->iv_opmode == IEEE80211_M_MBSS) {
-		static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
-		IEEE80211_ADDR_COPY(wh->i_addr3, zerobssid);
-	} else
-#endif
-		IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
+	IEEE80211_ADDR_COPY(wh->i_addr3, ni->ni_bssid);
 	*(uint16_t *)wh->i_seq = 0;
 
 	return m;
@@ -2874,6 +2869,11 @@ ieee80211_beacon_update(struct ieee80211
 		ieee80211_tdma_update_beacon(vap, bo);
 	}
 #endif
+#ifdef IEEE80211_SUPPORT_MESH
+	if (vap->iv_opmode == IEEE80211_M_MBSS)
+		ieee80211_mesh_update_beacon(vap, bo);
+#endif
+
 	if (vap->iv_opmode == IEEE80211_M_HOSTAP ||
 	    vap->iv_opmode == IEEE80211_M_MBSS) {	/* NB: no IBSS support*/
 		struct ieee80211_tim_ie *tie =
@@ -2928,6 +2928,9 @@ ieee80211_beacon_update(struct ieee80211
 #ifdef IEEE80211_TDMA_SUPPORT
 				bo->bo_tdma += adjust;
 #endif
+#ifdef IEEE80211_MESH_SUPPORT
+				bo->bo_meshconf += adjust;
+#endif
 				bo->bo_appie += adjust;
 				bo->bo_wme += adjust;
 				bo->bo_csa += adjust;
@@ -2979,6 +2982,9 @@ ieee80211_beacon_update(struct ieee80211
 #ifdef IEEE80211_TDMA_SUPPORT
 				bo->bo_tdma += sizeof(*csa);
 #endif
+#ifdef IEEE80211_MESH_SUPPORT
+				bo->bo_meshconf += sizeof(*csa);
+#endif
 				bo->bo_appie += sizeof(*csa);
 				bo->bo_csa_trailer_len += sizeof(*csa);
 				bo->bo_tim_trailer_len += sizeof(*csa);

Modified: stable/8/sys/net80211/ieee80211_proto.h
==============================================================================
--- stable/8/sys/net80211/ieee80211_proto.h	Fri Oct 30 19:25:13 2009	(r198698)
+++ stable/8/sys/net80211/ieee80211_proto.h	Fri Oct 30 19:59:50 2009	(r198699)
@@ -317,7 +317,8 @@ struct ieee80211_beacon_offsets {
 	uint16_t	bo_appie_len;	/* AppIE length in bytes */
 	uint16_t	bo_csa_trailer_len;;
 	uint8_t		*bo_csa;	/* start of CSA element */
-	uint8_t		*bo_spare[4];
+	uint8_t		*bo_meshconf;	/* start of MESHCONF element */
+	uint8_t		*bo_spare[3];
 };
 struct mbuf *ieee80211_beacon_alloc(struct ieee80211_node *,
 		struct ieee80211_beacon_offsets *);
@@ -345,6 +346,7 @@ enum {
 	IEEE80211_BEACON_CSA	= 7,	/* Channel Switch Announcement */
 	IEEE80211_BEACON_TDMA	= 9,	/* TDMA Info */
 	IEEE80211_BEACON_ATH	= 10,	/* ATH parameters */
+	IEEE80211_BEACON_MESHCONF = 11,	/* Mesh Configuration */
 };
 int	ieee80211_beacon_update(struct ieee80211_node *,
 		struct ieee80211_beacon_offsets *, struct mbuf *, int mcast);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200910301959.n9UJxocG056188>