Date: Fri, 29 May 2009 00:14:59 +0000 (UTC) From: Rui Paulo <rpaulo@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r193009 - projects/mesh11s/sys/net80211 Message-ID: <200905290014.n4T0ExQl054307@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200905290014.n4T0ExQl054307>