svn commit: r193009 - projects/mesh11s/sys/net80211
Rui Paulo
rpaulo at FreeBSD.org
Fri May 29 00:14:59 UTC 2009
Author: rpaulo
Date: Fri May 29 00:14:59 2009
New Revision: 193009
URL: http://svn.freebsd.org/changeset/base/193009
Log:
* add hwmp_send_action() function that will handle all mesh path action
frames
* add place holders for preq, prep, perr and rann action frames
* make ieee80211_send_setup() global
* use ieee80211_send_setup() in hwmp_send_action() thereby reducing code
size
* inline functions that just call hwmp_send_action()
* don't use zerobssid. The standard says bssid = addr2 (sa) for non
multhop action frames
* add IEEE80211_IOC_HWMP_TABLE to fetch/set the HWMP forwarding table
(not yet handled)
Sponsored by: The FreeBSD Foundation
Modified:
projects/mesh11s/sys/net80211/ieee80211_hwmp.c
projects/mesh11s/sys/net80211/ieee80211_ioctl.h
projects/mesh11s/sys/net80211/ieee80211_mesh.h
projects/mesh11s/sys/net80211/ieee80211_output.c
projects/mesh11s/sys/net80211/ieee80211_proto.h
Modified: projects/mesh11s/sys/net80211/ieee80211_hwmp.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_hwmp.c Thu May 28 23:23:49 2009 (r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_hwmp.c Fri May 29 00:14:59 2009 (r193009)
@@ -78,16 +78,31 @@ struct ieee80211_hwmp_fi {
};
TAILQ_HEAD(, ieee80211_hwmp_fi) ieee80211_hwmp_ft;
+static int ieee80211_hwmp_send_action(struct ieee80211_node *,
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+ const uint8_t *, size_t);
static void hwmp_recv_preq(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_meshpreq_ie *);
+static int hwmp_send_preq(struct ieee80211_node *,
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshpreq_ie *);
static void hwmp_recv_prep(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_meshprep_ie *);
static int hwmp_send_prep(struct ieee80211_node *,
- const uint8_t addr1[IEEE80211_ADDR_LEN],
- const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
const struct ieee80211_meshprep_ie *);
static void hwmp_recv_perr(struct ieee80211vap *, struct ieee80211_node *,
const struct ieee80211_meshperr_ie *);
+static int hwmp_send_perr(struct ieee80211_node *,
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshperr_ie *);
+static void hwmp_recv_rann(struct ieee80211vap *, struct ieee80211_node *,
+ const struct ieee80211_meshrann_ie *);
+#ifdef notyet
+static int hwmp_send_rann(struct ieee80211_node *,
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshrann_ie *);
+#endif
static int ieee80211_hwmp_maxhops = 31;
#ifdef notyet
@@ -142,6 +157,7 @@ ieee80211_hwmp_recv_action(struct ieee80
struct ieee80211_meshpreq_ie *meshpreq = NULL;
struct ieee80211_meshprep_ie *meshprep = NULL;
struct ieee80211_meshperr_ie *meshperr = NULL;
+ struct ieee80211_meshrann_ie *meshrann = NULL;
wh = mtod(m0, struct ieee80211_frame *);
ia = (struct ieee80211_action *) &wh[1];
@@ -178,6 +194,12 @@ ieee80211_hwmp_recv_action(struct ieee80
case IEEE80211_ELEMID_MESHPERR:
meshperr = (struct ieee80211_meshperr_ie *) frm;
break;
+ case IEEE80211_ELEMID_MESHRANN:
+ meshrann = (struct ieee80211_meshrann_ie *) frm;
+ meshrann->rann_seq = LE_READ_4(&meshrann->rann_seq);
+ meshrann->rann_metric =
+ LE_READ_4(&meshrann->rann_metric);
+ break;
}
frm += frm[1] + 2;
}
@@ -213,6 +235,16 @@ ieee80211_hwmp_recv_action(struct ieee80
}
hwmp_recv_perr(vap, ni, meshperr);
break;
+ case IEEE80211_ACTION_MESHPATH_RANN:
+ if (meshrann == NULL) {
+ IEEE80211_DISCARD(vap,
+ IEEE80211_MSG_ACTION | IEEE80211_MSG_MESH,
+ wh, NULL, "%s", "RANN without IE");
+ vap->iv_stats.is_rx_mgtdiscard++;
+ return;
+ }
+ hwmp_recv_rann(vap, ni, meshrann);
+ break;
default:
IEEE80211_DISCARD_MAC(vap, IEEE80211_MSG_MESH,
ni->ni_macaddr, NULL,
@@ -221,6 +253,88 @@ ieee80211_hwmp_recv_action(struct ieee80
}
+static int
+ieee80211_hwmp_send_action(struct ieee80211_node *ni,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const uint8_t *ie, size_t len)
+{
+ struct ieee80211vap *vap = ni->ni_vap;
+ struct ieee80211com *ic = ni->ni_ic;
+ struct ieee80211_bpf_params params;
+ struct mbuf *m;
+ uint8_t *frm;
+
+ if (vap->iv_state == IEEE80211_S_CAC) {
+ IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
+ "block %s frame in CAC state", "probe request");
+ vap->iv_stats.is_tx_badstate++;
+ return EIO; /* XXX */
+ }
+
+ 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.
+ */
+ 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);
+ ieee80211_ref_node(ni);
+
+ m = ieee80211_getmgtframe(&frm,
+ ic->ic_headroom + sizeof(struct ieee80211_frame),
+ sizeof(struct ieee80211_action) + len
+ );
+ if (m == NULL) {
+ ieee80211_free_node(ni);
+ vap->iv_stats.is_tx_nobuf++;
+ return ENOMEM;
+ }
+ *frm++ = IEEE80211_ACTION_CAT_MESHPATH;
+ switch (*ie) {
+ case IEEE80211_ELEMID_MESHPREQ:
+ *frm++ = IEEE80211_ACTION_MESHPATH_REQ;
+ break;
+ case IEEE80211_ELEMID_MESHPREP:
+ *frm++ = IEEE80211_ACTION_MESHPATH_REP;
+ frm = ieee80211_add_meshprep(frm,
+ (struct ieee80211_meshprep_ie *)&ie);
+ break;
+ case IEEE80211_ELEMID_MESHPERR:
+ *frm++ = IEEE80211_ACTION_MESHPATH_ERR;
+ break;
+ case IEEE80211_ELEMID_MESHRANN:
+ *frm++ = IEEE80211_ACTION_MESHPATH_RANN;
+ break;
+ }
+
+ m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
+ M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
+ if (m == NULL) {
+ ieee80211_free_node(ni);
+ vap->iv_stats.is_tx_nobuf++;
+ return ENOMEM;
+ }
+ ieee80211_send_setup(ni, m,
+ IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_ACTION,
+ IEEE80211_NONQOS_TID, addr1, addr2, addr2);
+
+ m->m_flags |= M_ENCAP; /* mark encapsulated */
+ IEEE80211_NODE_STAT(ni, tx_mgmt);
+
+ memset(¶ms, 0, sizeof(params));
+ params.ibp_pri = WME_AC_VO;
+ params.ibp_rate0 = ni->ni_txparms->mgmtrate;
+ /* XXX: NB: we know all frames are unicast */
+ params.ibp_try0 = ni->ni_txparms->maxretry;
+ params.ibp_power = ni->ni_txpower;
+
+ return ic->ic_raw_xmit(ni, m, ¶ms);
+}
#define ADDWORD(frm, v) do { \
frm[0] = (v) & 0xff; \
@@ -334,6 +448,25 @@ hwmp_recv_preq(struct ieee80211vap *vap,
#undef PREQ_TADDR
#undef PREQ_TSEQ
+static inline int
+hwmp_send_preq(struct ieee80211_node *ni,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshpreq_ie *preq)
+{
+ /*
+ * mesh preq action frame format
+ * [6] addr1
+ * [6] addr2
+ * [6] addr3 = addr2
+ * [1] action
+ * [1] category
+ * [tlv] mesh path request
+ */
+ return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&preq,
+ sizeof(*preq));
+}
+
static void
hwmp_recv_prep(struct ieee80211vap *vap, struct ieee80211_node *ni,
const struct ieee80211_meshprep_ie *prep)
@@ -389,104 +522,81 @@ hwmp_recv_prep(struct ieee80211vap *vap,
}
-static int
+
+static inline int
hwmp_send_prep(struct ieee80211_node *ni,
const uint8_t addr1[IEEE80211_ADDR_LEN],
const uint8_t addr2[IEEE80211_ADDR_LEN],
const struct ieee80211_meshprep_ie *prep)
{
- struct ieee80211vap *vap = ni->ni_vap;
- struct ieee80211com *ic = ni->ni_ic;
- struct ieee80211_frame *wh;
- struct ieee80211_bpf_params params;
- struct mbuf *m;
- ieee80211_seq seqno;
- uint8_t *frm;
-
- if (vap->iv_state == IEEE80211_S_CAC) {
- IEEE80211_NOTE(vap, IEEE80211_MSG_OUTPUT, ni,
- "block %s frame in CAC state", "probe request");
- vap->iv_stats.is_tx_badstate++;
- return EIO; /* XXX */
- }
-
- 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.
- */
- 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);
- ieee80211_ref_node(ni);
-
-
/*
* mesh prep action frame format
* [6] addr1
* [6] addr2
- * [6] addr2
+ * [6] addr3 = addr2
* [1] action
* [1] category
* [tlv] mesh path reply
*/
- m = ieee80211_getmgtframe(&frm,
- ic->ic_headroom + sizeof(struct ieee80211_frame),
- sizeof(struct ieee80211_action) +
- sizeof(struct ieee80211_meshprep_ie)
- );
- if (m == NULL) {
- ieee80211_free_node(ni);
- vap->iv_stats.is_tx_nobuf++;
- return ENOMEM;
- }
- *frm++ = IEEE80211_ACTION_CAT_MESHPATH;
- *frm++ = IEEE80211_ACTION_MESHPATH_REP;
- frm = ieee80211_add_meshprep(frm, prep);
- m->m_pkthdr.len = m->m_len = frm - mtod(m, uint8_t *);
- M_PREPEND(m, sizeof(struct ieee80211_frame), M_DONTWAIT);
- if (m == NULL) {
- ieee80211_free_node(ni);
- vap->iv_stats.is_tx_nobuf++;
- return ENOMEM;
- }
- wh = mtod(m, struct ieee80211_frame *);
- wh->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_MGT |
- IEEE80211_FC0_SUBTYPE_ACTION;
- wh->i_fc[1] = IEEE80211_FC1_DIR_DSTODS;
- IEEE80211_ADDR_COPY(wh->i_addr1, addr1);
- IEEE80211_ADDR_COPY(wh->i_addr2, addr2);
- IEEE80211_ADDR_COPY(wh->i_addr3, addr2);
- *(uint16_t *)&wh->i_dur[0] = 0;
- seqno = ni->ni_txseqs[IEEE80211_NONQOS_TID]++;
- *(uint16_t *)&wh->i_seq[0] = htole16(seqno << IEEE80211_SEQ_SEQ_SHIFT);
- M_SEQNO_SET(m, seqno);
- if (IEEE80211_IS_MULTICAST(wh->i_addr1))
- m->m_flags |= M_MCAST;
+ return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&prep,
+ sizeof(*prep));
+}
- m->m_flags |= M_ENCAP; /* mark encapsulated */
- IEEE80211_NODE_STAT(ni, tx_mgmt);
+static void
+hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
+ const struct ieee80211_meshperr_ie *perr)
+{
- memset(¶ms, 0, sizeof(params));
- params.ibp_pri = WME_AC_VO;
- params.ibp_rate0 = ni->ni_txparms->mgmtrate;
- /* XXX: NB: we know all frames are unicast */
- params.ibp_try0 = ni->ni_txparms->maxretry;
- params.ibp_power = ni->ni_txpower;
+}
- return ic->ic_raw_xmit(ni, m, ¶ms);
+
+static inline int
+hwmp_send_perr(struct ieee80211_node *ni,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshperr_ie *perr)
+{
+ /*
+ * mesh perr action frame format
+ * [6] addr1
+ * [6] addr2
+ * [6] addr3 = addr2
+ * [1] action
+ * [1] category
+ * [tlv] mesh path error
+ */
+ return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&perr,
+ sizeof(*perr));
}
static void
-hwmp_recv_perr(struct ieee80211vap *vap, struct ieee80211_node *ni,
- const struct ieee80211_meshperr_ie *perr)
+hwmp_recv_rann(struct ieee80211vap *vap, struct ieee80211_node *ni,
+ const struct ieee80211_meshrann_ie *rann)
{
}
+#ifdef notyet
+static int
+hwmp_send_rann(struct ieee80211_node *ni,
+ const uint8_t addr1[IEEE80211_ADDR_LEN],
+ const uint8_t addr2[IEEE80211_ADDR_LEN],
+ const struct ieee80211_meshrann_ie *rann)
+{
+ /*
+ * mesh rann action frame format
+ * [6] addr1
+ * [6] addr2
+ * [6] addr3 = addr2
+ * [1] action
+ * [1] category
+ * [tlv] root annoucement
+ */
+ return ieee80211_hwmp_send_action(ni, addr1, addr2, (uint8_t *)&rann,
+ sizeof(*rann));
+}
+#endif
+
static int
hwmp_ioctl_get80211(struct ieee80211vap *vap, struct ieee80211req *ireq)
{
@@ -494,11 +604,9 @@ hwmp_ioctl_get80211(struct ieee80211vap
error = 0;
switch (ireq->i_type) {
-#ifdef notyet
- case IEEE80211_IOC_HWMPFI:
+ case IEEE80211_IOC_HWMP_TABLE:
if (vap->iv_opmode != IEEE80211_M_MBSS)
return EINVAL;
-#endif
default:
return ENOSYS;
}
@@ -514,9 +622,9 @@ hwmp_ioctl_set80211(struct ieee80211vap
error = 0;
switch (ireq->i_type) {
-#ifdef notyet
- case IEEE80211_IOC_HWMPFI:
-#endif
+ case IEEE80211_IOC_HWMP_TABLE:
+ if (vap->iv_opmode != IEEE80211_M_MBSS)
+ return EINVAL;
default:
return ENOSYS;
}
Modified: projects/mesh11s/sys/net80211/ieee80211_ioctl.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_ioctl.h Thu May 28 23:23:49 2009 (r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_ioctl.h Fri May 29 00:14:59 2009 (r193009)
@@ -634,6 +634,7 @@ struct ieee80211req {
#define IEEE80211_IOC_RIFS 111 /* RIFS config (on, off) */
#define IEEE80211_IOC_MESH_ID 190 /* Mesh identifier */
+#define IEEE80211_IOC_HWMP_TABLE 195 /* HWMP Forwarding Table */
#define IEEE80211_IOC_TDMA_SLOT 201 /* TDMA: assigned slot */
#define IEEE80211_IOC_TDMA_SLOTCNT 202 /* TDMA: slots in bss */
Modified: projects/mesh11s/sys/net80211/ieee80211_mesh.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_mesh.h Thu May 28 23:23:49 2009 (r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_mesh.h Fri May 29 00:14:59 2009 (r193009)
@@ -217,6 +217,7 @@ struct ieee80211_meshrann_ie {
uint8_t rann_ie; /* IEEE80211_ELEMID_MESHRANN */
uint8_t rann_len;
uint8_t rann_flags;
+#define IEEE80211_MESHRANN_FLAGS_PR 0x01 /* Portal Role */
uint8_t rann_hopcount;
uint8_t rann_ttl;
uint8_t rann_addr[IEEE80211_ADDR_LEN];
@@ -324,7 +325,8 @@ enum {
IEEE80211_ACTION_MESHPATH_REQ = 0,
IEEE80211_ACTION_MESHPATH_REP = 1,
IEEE80211_ACTION_MESHPATH_ERR = 2,
- /* 3-255 reserved */
+ IEEE80211_ACTION_MESHPATH_RANN = 3,
+ /* 4-255 reserved */
};
/*
Modified: projects/mesh11s/sys/net80211/ieee80211_output.c
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_output.c Thu May 28 23:23:49 2009 (r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_output.c Fri May 29 00:14:59 2009 (r193009)
@@ -457,7 +457,7 @@ bad:
* frame. Note this should be called early on in constructing
* a frame as it sets i_fc[1]; other bits can then be or'd in.
*/
-static void
+void
ieee80211_send_setup(
struct ieee80211_node *ni,
struct mbuf *m,
@@ -467,7 +467,6 @@ ieee80211_send_setup(
const uint8_t bssid[IEEE80211_ADDR_LEN])
{
#define WH4(wh) ((struct ieee80211_frame_addr4 *)wh)
- static const uint8_t zerobssid[IEEE80211_ADDR_LEN];
struct ieee80211vap *vap = ni->ni_vap;
struct ieee80211_frame *wh = mtod(m, struct ieee80211_frame *);
ieee80211_seq seqno;
@@ -510,7 +509,7 @@ ieee80211_send_setup(
IEEE80211_ADDR_COPY(wh->i_addr1, da);
IEEE80211_ADDR_COPY(wh->i_addr2, sa);
if (vap->iv_opmode == IEEE80211_M_MBSS)
- IEEE80211_ADDR_COPY(wh->i_addr3, zerobssid);
+ IEEE80211_ADDR_COPY(wh->i_addr3, sa);
else
IEEE80211_ADDR_COPY(wh->i_addr3, bssid);
}
Modified: projects/mesh11s/sys/net80211/ieee80211_proto.h
==============================================================================
--- projects/mesh11s/sys/net80211/ieee80211_proto.h Thu May 28 23:23:49 2009 (r193008)
+++ projects/mesh11s/sys/net80211/ieee80211_proto.h Fri May 29 00:14:59 2009 (r193009)
@@ -76,6 +76,9 @@ int ieee80211_raw_xmit(struct ieee80211_
const struct ieee80211_bpf_params *);
int ieee80211_output(struct ifnet *, struct mbuf *,
struct sockaddr *, struct route *ro);
+void ieee80211_send_setup(struct ieee80211_node *, struct mbuf *, int, int,
+ const uint8_t [IEEE80211_ADDR_LEN], const uint8_t [IEEE80211_ADDR_LEN],
+ const uint8_t [IEEE80211_ADDR_LEN]);
void ieee80211_start(struct ifnet *);
int ieee80211_send_nulldata(struct ieee80211_node *);
int ieee80211_classify(struct ieee80211_node *, struct mbuf *m);
More information about the svn-src-projects
mailing list