From owner-svn-src-all@FreeBSD.ORG Tue May 1 16:11:48 2012 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 8D52E1065677; Tue, 1 May 2012 16:11:48 +0000 (UTC) (envelope-from monthadar@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 6E9E18FC18; Tue, 1 May 2012 16:11:48 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q41GBmbF033975; Tue, 1 May 2012 16:11:48 GMT (envelope-from monthadar@svn.freebsd.org) Received: (from monthadar@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q41GBmeN033973; Tue, 1 May 2012 16:11:48 GMT (envelope-from monthadar@svn.freebsd.org) Message-Id: <201205011611.q41GBmeN033973@svn.freebsd.org> From: Monthadar Al Jaberi Date: Tue, 1 May 2012 16:11:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r234889 - head/sys/net80211 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 May 2012 16:11:48 -0000 Author: monthadar Date: Tue May 1 16:11:47 2012 New Revision: 234889 URL: http://svn.freebsd.org/changeset/base/234889 Log: * Modified PERR acceptance criteria according to amendment; * Modified how PERR is handled and propagated according to amendment; Approved by: adrian Modified: head/sys/net80211/ieee80211_hwmp.c Modified: head/sys/net80211/ieee80211_hwmp.c ============================================================================== --- head/sys/net80211/ieee80211_hwmp.c Tue May 1 16:10:32 2012 (r234888) +++ head/sys/net80211/ieee80211_hwmp.c Tue May 1 16:11:47 2012 (r234889) @@ -1450,7 +1450,7 @@ hwmp_peerdown(struct ieee80211_node *ni) PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_USN; PERR_DFLAGS(0) |= IEEE80211_MESHPERR_DFLAGS_RC; IEEE80211_ADDR_COPY(PERR_DADDR(0), rt->rt_dest); - PERR_DSEQ(0) = hr->hr_seq; + PERR_DSEQ(0) = ++hr->hr_seq; PERR_DRCODE(0) = IEEE80211_REASON_MESH_PERR_DEST_UNREACH; /* NB: flush everything passing through peer */ ieee80211_mesh_rt_flush_peer(vap, ni->ni_macaddr); @@ -1461,60 +1461,117 @@ hwmp_peerdown(struct ieee80211_node *ni) #undef PERR_DSEQ #undef PERR_DRCODE -#define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags -#define PERR_DADDR(n) perr->perr_dests[n].dest_addr -#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq -#define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode +#define PERR_DFLAGS(n) perr->perr_dests[n].dest_flags +#define PERR_DADDR(n) perr->perr_dests[n].dest_addr +#define PERR_DSEQ(n) perr->perr_dests[n].dest_seq +#define PERR_DEXTADDR(n) perr->perr_dests[n].dest_ext_addr +#define PERR_DRCODE(n) perr->perr_dests[n].dest_rcode 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_mesh_route *rt = NULL; + struct ieee80211_mesh_route *rt_ext = NULL; struct ieee80211_hwmp_route *hr; - struct ieee80211_meshperr_ie pperr; - int i, forward = 0; + struct ieee80211_meshperr_ie *pperr = NULL; + int i, j = 0, forward = 0; - /* - * Acceptance criteria: check if we received a PERR from a - * neighbor and forwarding is enabled. - */ if (ni == vap->iv_bss || - ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED || - !(ms->ms_flags & IEEE80211_MESHFLAGS_FWD)) + ni->ni_mlstate != IEEE80211_NODE_MESH_ESTABLISHED) return; + + IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, + "received PERR from %6D", wh->i_addr2, ":"); + + /* + * if forwarding is true, prepare pperr + */ + if (ms->ms_flags & IEEE80211_MESHFLAGS_FWD) { + forward = 1; + pperr = malloc(sizeof(*perr) + 31*sizeof(*perr->perr_dests), + M_80211_MESH_PERR, M_NOWAIT); /* XXX: magic number, 32 err dests */ + } + /* - * Find all routing entries that match and delete them. + * Acceptance criteria: check if we have forwarding information + * stored about destination, and that nexthop == TA of this PERR. + * NB: we also build a new PERR to propagate in case we should forward. */ for (i = 0; i < perr->perr_ndests; i++) { rt = ieee80211_mesh_rt_find(vap, PERR_DADDR(i)); - if (rt == NULL) + if (rt == NULL || rt->rt_flags & IEEE80211_MESHRT_FLAGS_VALID) continue; + if (!IEEE80211_ADDR_EQ(rt->rt_nexthop, wh->i_addr2)) + continue; + + /* found and accepted a PERR ndest element, process it... */ + if (forward) + memcpy(&pperr->perr_dests[j], &perr->perr_dests[i], + sizeof(*perr->perr_dests)); hr = IEEE80211_MESH_ROUTE_PRIV(rt, struct ieee80211_hwmp_route); - if (!(PERR_DFLAGS(0) & IEEE80211_MESHPERR_DFLAGS_USN) && - HWMP_SEQ_GEQ(PERR_DSEQ(i), hr->hr_seq)) { - ieee80211_mesh_rt_del(vap, rt->rt_dest); - ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest); - rt = NULL; - forward = 1; + switch(PERR_DFLAGS(i)) { + case (IEEE80211_REASON_MESH_PERR_NO_FI): + if (PERR_DSEQ(i) == 0) { + hr->hr_seq++; + if (forward) { + pperr->perr_dests[j].dest_seq = + hr->hr_seq; + } + } else { + hr->hr_seq = PERR_DSEQ(i); + } + rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID; + j++; + break; + case (IEEE80211_REASON_MESH_PERR_DEST_UNREACH): + if(HWMP_SEQ_GT(PERR_DSEQ(i), hr->hr_seq)) { + hr->hr_seq = PERR_DSEQ(i); + rt->rt_flags &= ~IEEE80211_MESHRT_FLAGS_VALID; + j++; + } + break; + case (IEEE80211_REASON_MESH_PERR_NO_PROXY): + rt_ext = ieee80211_mesh_rt_find(vap, PERR_DEXTADDR(i)); + if (rt_ext != NULL) { + rt_ext->rt_flags &= + ~IEEE80211_MESHRT_FLAGS_VALID; + j++; + } + break; + default: + IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, + "PERR, unknown reason code %u\n", PERR_DFLAGS(i)); + goto done; /* XXX: stats?? */ } + ieee80211_mesh_rt_flush_peer(vap, rt->rt_dest); + KASSERT(j < 32, ("PERR, error ndest >= 32 (%u)", j)); + } + if (j == 0) { + IEEE80211_DISCARD(vap, IEEE80211_MSG_HWMP, wh, NULL, "%s", + "PERR not accepted"); + goto done; /* XXX: stats?? */ } + /* * Propagate the PERR if we previously found it on our routing table. - * XXX handle ndest > 1 */ if (forward && perr->perr_ttl > 1) { IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP, ni, "propagate PERR from %6D", wh->i_addr2, ":"); - memcpy(&pperr, perr, sizeof(*perr)); - pperr.perr_ttl--; + pperr->perr_ndests = j; + pperr->perr_ttl--; hwmp_send_perr(vap->iv_bss, vap->iv_myaddr, broadcastaddr, - &pperr); + pperr); } +done: + if (pperr != NULL) + free(pperr, M_80211_MESH_PERR); } #undef PERR_DFLAGS #undef PEER_DADDR #undef PERR_DSEQ +#undef PERR_DEXTADDR #undef PERR_DRCODE static int