svn commit: r246512 - head/sys/net80211

Monthadar Al Jaberi monthadar at FreeBSD.org
Thu Feb 7 21:26:41 UTC 2013


Author: monthadar
Date: Thu Feb  7 21:26:40 2013
New Revision: 246512
URL: http://svnweb.freebsd.org/changeset/base/246512

Log:
  HWMP: ic->raw_xmit didn't always point to correct ni.
  
  This is a code re-write. ic->raw_xmit need a pointer to ieee80211_node
  for the destination node (da). I have reorganized the code so that
  a pointer to the da node is searched for in the end & in one place.
  
  * Make mesh_find_txnode public to be used by HWMP, renamed to
    ieee80211_mesh_finx_txnode;
  * changed the argument from ieee80211_node to ieee80211vap for all
    hwmp_send_* functions;
  * removed the 'sa' argument from hwmp_send_* functions as all HWMP frames
    have the source address equal to vap->iv_myaddr;
  * Modified hwmp_send_action so that if da is MULTCAST ni=vap->iv_bss
    otherwise we called ieee80211_mesh_find_txnode. Also no need to hold
    a reference in this functions if da is not MULTICAST as by finding the
    node it became referenced in ieee80211_find_txnode;
  
  Approved by:	adrian (mentor)

Modified:
  head/sys/net80211/ieee80211_hwmp.c
  head/sys/net80211/ieee80211_mesh.c
  head/sys/net80211/ieee80211_mesh.h

Modified: head/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- head/sys/net80211/ieee80211_hwmp.c	Thu Feb  7 21:26:06 2013	(r246511)
+++ head/sys/net80211/ieee80211_hwmp.c	Thu Feb  7 21:26:40 2013	(r246512)
@@ -68,8 +68,7 @@ static void	hwmp_vattach(struct ieee8021
 static void	hwmp_vdetach(struct ieee80211vap *);
 static int	hwmp_newstate(struct ieee80211vap *,
 		    enum ieee80211_state, int);
-static int	hwmp_send_action(struct ieee80211_node *,
-		    const uint8_t [IEEE80211_ADDR_LEN],
+static int	hwmp_send_action(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    uint8_t *, size_t);
 static uint8_t * hwmp_add_meshpreq(uint8_t *,
@@ -86,23 +85,20 @@ static void	hwmp_rootmode_rann_cb(void *
 static void	hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
 		    const struct ieee80211_frame *,
 		    const struct ieee80211_meshpreq_ie *);
-static int	hwmp_send_preq(struct ieee80211_node *,
-		    const uint8_t [IEEE80211_ADDR_LEN],
+static int	hwmp_send_preq(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    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 *);
-static int	hwmp_send_prep(struct ieee80211_node *,
-		    const uint8_t [IEEE80211_ADDR_LEN],
+static int	hwmp_send_prep(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    struct ieee80211_meshprep_ie *);
 static void	hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *,
 		    const struct ieee80211_frame *,
 		    const struct ieee80211_meshperr_ie *);
-static int	hwmp_send_perr(struct ieee80211_node *,
-		    const uint8_t [IEEE80211_ADDR_LEN],
+static int	hwmp_send_perr(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    struct ieee80211_meshperr_ie *);
 static void	hwmp_senderror(struct ieee80211vap *,
@@ -111,8 +107,7 @@ static void	hwmp_senderror(struct ieee80
 static void	hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *,
 		   const struct ieee80211_frame *,
 		   const struct ieee80211_meshrann_ie *);
-static int	hwmp_send_rann(struct ieee80211_node *,
-		    const uint8_t [IEEE80211_ADDR_LEN],
+static int	hwmp_send_rann(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN],
 		    struct ieee80211_meshrann_ie *);
 static struct ieee80211_node *
@@ -588,17 +583,30 @@ hwmp_recv_action_meshpath(struct ieee802
 }
 
 static int
-hwmp_send_action(struct ieee80211_node *ni,
-    const uint8_t sa[IEEE80211_ADDR_LEN],
+hwmp_send_action(struct ieee80211vap *vap,
     const uint8_t da[IEEE80211_ADDR_LEN],
     uint8_t *ie, size_t len)
 {
-	struct ieee80211vap *vap = ni->ni_vap;
-	struct ieee80211com *ic = ni->ni_ic;
+	struct ieee80211_node *ni;
+	struct ieee80211com *ic;
 	struct ieee80211_bpf_params params;
 	struct mbuf *m;
 	uint8_t *frm;
 
+	if (IEEE80211_IS_MULTICAST(da)) {
+		ni = ieee80211_ref_node(vap->iv_bss);
+#ifdef IEEE80211_DEBUG_REFCNT
+		IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
+		"ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
+		__func__, __LINE__,
+		ni, ether_sprintf(ni->ni_macaddr),
+		ieee80211_node_refcnt(ni)+1);
+#endif
+		ieee80211_ref_node(ni);
+	}
+	else
+		ni = ieee80211_mesh_find_txnode(vap, da);
+
 	if (vap->iv_state == IEEE80211_S_CAC) {
 		IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
 		    "block %s frame in CAC state", "HWMP action");
@@ -607,19 +615,7 @@ hwmp_send_action(struct ieee80211_node *
 	}
 
 	KASSERT(ni != NULL, ("null node"));
-	/*
-	 * Hold a reference on the node so it doesn't go away until after
-	 * the xmit is complete all the way in the driver.  On error we
-	 * will remove our reference.
-	 */
-#ifdef IEEE80211_DEBUG_REFCNT
-	IEEE80211_DPRINTF(vap, IEEE80211_MSG_NODE,
-	    "ieee80211_ref_node (%s:%u) %p<%s> refcnt %d\n",
-	    __func__, __LINE__,
-	    ni, ether_sprintf(ni->ni_macaddr),
-	    ieee80211_node_refcnt(ni)+1);
-#endif
-	ieee80211_ref_node(ni);
+	ic = ni->ni_ic;
 
 	m = ieee80211_getmgtframe(&frm,
 	    ic->ic_headroom + sizeof(struct ieee80211_frame),
@@ -660,7 +656,7 @@ hwmp_send_action(struct ieee80211_node *
 	}
 	ieee80211_send_setup(ni, m,
 	    IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
-	    IEEE80211_NONQOS_TID, sa, da, sa);
+	    IEEE80211_NONQOS_TID, vap->iv_myaddr, da, vap->iv_myaddr);
 
 	m->m_flags |= M_ENCAP;		/* mark encapsulated */
 	IEEE80211_NODE_STAT(ni, tx_mgmt);
@@ -862,8 +858,8 @@ hwmp_rootmode_cb(void *arg)
 	    IEEE80211_MESHPREQ_TFLAGS_USN;
 	PREQ_TSEQ(0) = 0;
 	vap->iv_stats.is_hwmp_rootreqs++;
-	hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &preq,
-	    NULL, NULL);	/* NB: we enforce rate check ourself */
+	/* NB: we enforce rate check ourself */
+	hwmp_send_preq(vap, broadcastaddr, &preq, NULL, NULL);
 	hwmp_rootmode_setup(vap);
 }
 #undef	PREQ_TFLAGS
@@ -896,7 +892,7 @@ hwmp_rootmode_rann_cb(void *arg)
 	rann.rann_metric = IEEE80211_MESHLMETRIC_INITIALVAL;
 
 	vap->iv_stats.is_hwmp_rootrann++;
-	hwmp_send_rann(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &rann);
+	hwmp_send_rann(vap, broadcastaddr, &rann);
 	hwmp_rootmode_setup(vap);
 }
 
@@ -1060,7 +1056,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 
 		IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni,
 		    "reply to %6D", preq->preq_origaddr, ":");
-		hwmp_send_prep(ni, vap->iv_myaddr, wh->i_addr2, &prep);
+		hwmp_send_prep(vap, wh->i_addr2, &prep);
 		return;
 	}
 	/* we may update our proxy information for the orig external */
@@ -1119,8 +1115,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 			IEEE80211_ADDR_COPY(prep.prep_targetaddr,
 			    vap->iv_myaddr);
 			prep.prep_targetseq = ++hs->hs_seq;
-			hwmp_send_prep(vap->iv_bss, vap->iv_myaddr,
-			    rtorig->rt_nexthop, &prep);
+			hwmp_send_prep(vap, rtorig->rt_nexthop, &prep);
 		}
 	}
 
@@ -1161,8 +1156,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 				IEEE80211_ADDR_COPY(&prep.prep_origaddr,
 				    preq->preq_origaddr);
 				prep.prep_origseq = hrorig->hr_seq;
-				hwmp_send_prep(ni, vap->iv_myaddr,
-				    rtorig->rt_nexthop, &prep);
+				hwmp_send_prep(vap, rtorig->rt_nexthop, &prep);
 
 				/*
 				 * Set TO and unset RF bits because we have
@@ -1181,8 +1175,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 		ppreq.preq_metric += ms->ms_pmetric->mpm_metric(ni);
 
 		/* don't do PREQ ratecheck when we propagate */
-		hwmp_send_preq(ni, vap->iv_myaddr, broadcastaddr,
-			&ppreq, NULL, NULL);
+		hwmp_send_preq(vap, broadcastaddr, &ppreq, NULL, NULL);
 	}
 }
 #undef	PREQ_TFLAGS
@@ -1190,8 +1183,7 @@ hwmp_recv_preq(struct ieee80211vap *vap,
 #undef	PREQ_TSEQ
 
 static int
-hwmp_send_preq(struct ieee80211_node *ni,
-    const uint8_t sa[IEEE80211_ADDR_LEN],
+hwmp_send_preq(struct ieee80211vap *vap,
     const uint8_t da[IEEE80211_ADDR_LEN],
     struct ieee80211_meshpreq_ie *preq,
     struct timeval *last, struct timeval *minint)
@@ -1220,7 +1212,7 @@ hwmp_send_preq(struct ieee80211_node *ni
 	preq->preq_len = (preq->preq_flags & IEEE80211_MESHPREQ_FLAGS_AE ?
 	    IEEE80211_MESHPREQ_BASE_SZ_AE : IEEE80211_MESHPREQ_BASE_SZ) +
 	    preq->preq_tcount * IEEE80211_MESHPREQ_TRGT_SZ;
-	return hwmp_send_action(ni, sa, da, (uint8_t *)preq, preq->preq_len+2);
+	return hwmp_send_action(vap, da, (uint8_t *)preq, preq->preq_len+2);
 }
 
 static void
@@ -1354,7 +1346,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 		pprep.prep_hopcount += 1;
 		pprep.prep_ttl -= 1;
 		pprep.prep_metric += ms->ms_pmetric->mpm_metric(ni);
-		hwmp_send_prep(ni, vap->iv_myaddr, rtorig->rt_nexthop, &pprep);
+		hwmp_send_prep(vap, rtorig->rt_nexthop, &pprep);
 
 		/* precursor list for the Target Mesh STA Address is updated */
 	}
@@ -1436,8 +1428,7 @@ hwmp_recv_prep(struct ieee80211vap *vap,
 }
 
 static int
-hwmp_send_prep(struct ieee80211_node *ni,
-    const uint8_t sa[IEEE80211_ADDR_LEN],
+hwmp_send_prep(struct ieee80211vap *vap,
     const uint8_t da[IEEE80211_ADDR_LEN],
     struct ieee80211_meshprep_ie *prep)
 {
@@ -1455,8 +1446,7 @@ hwmp_send_prep(struct ieee80211_node *ni
 	prep->prep_ie = IEEE80211_ELEMID_MESHPREP;
 	prep->prep_len = prep->prep_flags & IEEE80211_MESHPREP_FLAGS_AE ?
 	    IEEE80211_MESHPREP_BASE_SZ_AE : IEEE80211_MESHPREP_BASE_SZ;
-	return hwmp_send_action(ni, sa, da, (uint8_t *)prep,
-	    prep->prep_len + 2);
+	return hwmp_send_action(vap, da, (uint8_t *)prep, prep->prep_len + 2);
 }
 
 #define	PERR_DFLAGS(n)	perr.perr_dests[n].dest_flags
@@ -1489,7 +1479,7 @@ hwmp_peerdown(struct ieee80211_node *ni)
 	PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH;
 	/* NB: flush everything passing through peer */
 	ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr);
-	hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
+	hwmp_send_perr(vap, broadcastaddr, &perr);
 }
 #undef	PERR_DFLAGS
 #undef	PERR_DADDR
@@ -1592,8 +1582,7 @@ hwmp_recv_perr(struct ieee80211vap *vap,
 		    "propagate PERR from %6D", wh->i_addr2, ":");
 		pperr->perr_ndests = j;
 		pperr->perr_ttl--;
-		hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr,
-		    pperr);
+		hwmp_send_perr(vap, broadcastaddr, pperr);
 	}
 done:
 	if (pperr != NULL)
@@ -1606,12 +1595,11 @@ done:
 #undef	PERR_DRCODE
 
 static int
-hwmp_send_perr(struct ieee80211_node *ni,
-    const uint8_t sa[IEEE80211_ADDR_LEN],
+hwmp_send_perr(struct ieee80211vap *vap,
     const uint8_t da[IEEE80211_ADDR_LEN],
     struct ieee80211_meshperr_ie *perr)
 {
-	struct ieee80211_hwmp_state *hs = ni->ni_vap->iv_hwmp;
+	struct ieee80211_hwmp_state *hs = vap->iv_hwmp;
 	int i;
 	uint8_t length = 0;
 
@@ -1642,7 +1630,7 @@ hwmp_send_perr(struct ieee80211_node *ni
 		length += IEEE80211_MESHPERR_DEST_SZ;
 	}
 	perr->perr_len =length;
-	return hwmp_send_action(ni, sa, da, (uint8_t *)perr, perr->perr_len+2);
+	return hwmp_send_action(vap, da, (uint8_t *)perr, perr->perr_len+2);
 }
 
 /*
@@ -1695,7 +1683,7 @@ hwmp_senderror(struct ieee80211vap *vap,
 	default:
 		KASSERT(0, ("unknown reason code for HWMP PERR (%u)", rcode));
 	}
-	hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, &perr);
+	hwmp_send_perr(vap, broadcastaddr, &perr);
 }
 #undef	PERR_DFLAGS
 #undef	PEER_DADDR
@@ -1782,8 +1770,8 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 	IEEE80211_ADDR_COPY(preq.preq_targets[0].target_addr, rann->rann_addr);
 	preq.preq_targets[0].target_seq = rann->rann_seq;
 	/* XXX: if rootconfint have not passed, we built this preq in vain */
-	hwmp_send_preq(vap->iv_bss, vap->iv_myaddr, wh->i_addr2, &preq,
-	    &hr->hr_lastrootconf, &ieee80211_hwmp_rootconfint);
+	hwmp_send_preq(vap, wh->i_addr2, &preq, &hr->hr_lastrootconf,
+	    &ieee80211_hwmp_rootconfint);
 
 	/* propagate a RANN */
 	if (rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID &&
@@ -1794,14 +1782,12 @@ hwmp_recv_rann(struct ieee80211vap *vap,
 		prann.rann_hopcount += 1;
 		prann.rann_ttl -= 1;
 		prann.rann_metric += ms->ms_pmetric->mpm_metric(ni);
-		hwmp_send_rann(vap->iv_bss, vap->iv_myaddr,
-		    broadcastaddr, &prann);
+		hwmp_send_rann(vap, broadcastaddr, &prann);
 	}
 }
 
 static int
-hwmp_send_rann(struct ieee80211_node *ni,
-    const uint8_t sa[IEEE80211_ADDR_LEN],
+hwmp_send_rann(struct ieee80211vap *vap,
     const uint8_t da[IEEE80211_ADDR_LEN],
     struct ieee80211_meshrann_ie *rann)
 {
@@ -1816,8 +1802,7 @@ hwmp_send_rann(struct ieee80211_node *ni
 	 */
 	rann->rann_ie = IEEE80211_ELEMID_MESHRANN;
 	rann->rann_len = IEEE80211_MESHRANN_BASE_SZ;
-	return hwmp_send_action(ni, sa, da, (uint8_t *)rann,
-	    rann->rann_len + 2);
+	return hwmp_send_action(vap, da, (uint8_t *)rann, rann->rann_len + 2);
 }
 
 #define	PREQ_TFLAGS(n)	preq.preq_targets[n].target_flags
@@ -1872,9 +1857,8 @@ hwmp_rediscover_cb(void *arg)
 	PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
 	PREQ_TSEQ(0) = 0; /* RESERVED when USN flag is set */
 	/* XXX check return value */
-	hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
-		broadcastaddr, &preq, &hr->hr_lastpreq,
-		&ieee80211_hwmp_preqminint);
+	hwmp_send_preq(vap, broadcastaddr, &preq, &hr->hr_lastpreq,
+	    &ieee80211_hwmp_preqminint);
 	callout_reset(&rt->rt_discovery,
 		ieee80211_hwmp_net_diameter_traversaltime * 2,
 		hwmp_rediscover_cb, rt);
@@ -1970,9 +1954,8 @@ hwmp_discover(struct ieee80211vap *vap,
 			PREQ_TFLAGS(0) |= IEEE80211_MESHPREQ_TFLAGS_USN;
 			PREQ_TSEQ(0) = 0; /* RESERVED when USN flag is set */
 			/* XXX check return value */
-			hwmp_send_preq(vap->iv_bss, vap->iv_myaddr,
-			    broadcastaddr, &preq, &hr->hr_lastpreq,
-			    &ieee80211_hwmp_preqminint);
+			hwmp_send_preq(vap, broadcastaddr, &preq,
+			    &hr->hr_lastpreq, &ieee80211_hwmp_preqminint);
 			callout_reset(&rt->rt_discovery,
 			    ieee80211_hwmp_net_diameter_traversaltime * 2,
 			    hwmp_rediscover_cb, rt);

Modified: head/sys/net80211/ieee80211_mesh.c
==============================================================================
--- head/sys/net80211/ieee80211_mesh.c	Thu Feb  7 21:26:06 2013	(r246511)
+++ head/sys/net80211/ieee80211_mesh.c	Thu Feb  7 21:26:40 2013	(r246512)
@@ -77,9 +77,6 @@ static void	mesh_checkid(void *, struct 
 static uint32_t	mesh_generateid(struct ieee80211vap *);
 static int	mesh_checkpseq(struct ieee80211vap *,
 		    const uint8_t [IEEE80211_ADDR_LEN], uint32_t);
-static struct ieee80211_node *
-		mesh_find_txnode(struct ieee80211vap *,
-		    const uint8_t [IEEE80211_ADDR_LEN]);
 static void	mesh_transmit_to_gate(struct ieee80211vap *, struct mbuf *,
 		    struct ieee80211_mesh_route *);
 static void	mesh_forward(struct ieee80211vap *, struct mbuf *,
@@ -1005,8 +1002,8 @@ mesh_checkpseq(struct ieee80211vap *vap,
 /*
  * Iterate the routing table and locate the next hop.
  */
-static struct ieee80211_node *
-mesh_find_txnode(struct ieee80211vap *vap,
+struct ieee80211_node *
+ieee80211_mesh_find_txnode(struct ieee80211vap *vap,
     const uint8_t dest[IEEE80211_ADDR_LEN])
 {
 	struct ieee80211_mesh_route *rt;
@@ -1046,7 +1043,7 @@ mesh_transmit_to_gate(struct ieee80211va
 	int error;
 
 	eh = mtod(m, struct ether_header *);
-	ni = mesh_find_txnode(vap, rt_gate->rt_dest);
+	ni = ieee80211_mesh_find_txnode(vap, rt_gate->rt_dest);
 	if (ni == NULL) {
 		ifp->if_oerrors++;
 		m_freem(m);
@@ -1293,7 +1290,7 @@ mesh_forward(struct ieee80211vap *vap, s
 		ni = ieee80211_ref_node(vap->iv_bss);
 		mcopy->m_flags |= M_MCAST;
 	} else {
-		ni = mesh_find_txnode(vap, whcopy->i_addr3);
+		ni = ieee80211_mesh_find_txnode(vap, whcopy->i_addr3);
 		if (ni == NULL) {
 			/*
 			 * [Optional] any of the following three actions:

Modified: head/sys/net80211/ieee80211_mesh.h
==============================================================================
--- head/sys/net80211/ieee80211_mesh.h	Thu Feb  7 21:26:06 2013	(r246511)
+++ head/sys/net80211/ieee80211_mesh.h	Thu Feb  7 21:26:40 2013	(r246512)
@@ -571,6 +571,9 @@ struct ieee80211_mesh_gate_route *
 		    const uint8_t *, struct ieee80211_mesh_route *);
 void		ieee80211_mesh_forward_to_gates(struct ieee80211vap *,
 		    struct ieee80211_mesh_route *);
+struct ieee80211_node *
+		ieee80211_mesh_find_txnode(struct ieee80211vap *,
+		    const uint8_t [IEEE80211_ADDR_LEN]);
 
 /*
  * Return non-zero if proxy operation is enabled.


More information about the svn-src-all mailing list