X-Git-Url: https://git.rohieb.name/openwrt.git/blobdiff_plain/f78a2712af346531cb3246884f692d884304286f..bc0aaef0c37c1ede1f7fe755bd33e9007538c136:/package/madwifi/patches/371-wds_sta_separation.patch diff --git a/package/madwifi/patches/371-wds_sta_separation.patch b/package/madwifi/patches/371-wds_sta_separation.patch index 57b62b089..917859490 100644 --- a/package/madwifi/patches/371-wds_sta_separation.patch +++ b/package/madwifi/patches/371-wds_sta_separation.patch @@ -17,14 +17,20 @@ if (skb->len < hdrspace) { IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "data", "too short: len %u, expecting %u", -@@ -446,15 +447,20 @@ +@@ -445,16 +446,24 @@ + } switch (vap->iv_opmode) { case IEEE80211_M_STA: - if ((dir != IEEE80211_FC1_DIR_FROMDS) && +- if ((dir != IEEE80211_FC1_DIR_FROMDS) && - (!((vap->iv_flags_ext & IEEE80211_FEXT_WDS) && - (dir == IEEE80211_FC1_DIR_DSTODS)))) { -+ (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS) && -+ (dir == IEEE80211_FC1_DIR_DSTODS))) { ++ switch(dir) { ++ case IEEE80211_FC1_DIR_FROMDS: ++ break; ++ case IEEE80211_FC1_DIR_DSTODS: ++ if (vap->iv_flags_ext & IEEE80211_FEXT_WDS) ++ break; ++ default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "data", "invalid dir 0x%x", dir); vap->iv_stats.is_rx_wrongdir++; @@ -34,14 +40,13 @@ - if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + /* ignore 3-addr mcast if we're WDS STA */ -+ if ((vap->iv_flags_ext & IEEE80211_FEXT_WDS) && -+ (dir != IEEE80211_FC1_DIR_DSTODS)) ++ if (vap->iv_flags_ext & IEEE80211_FEXT_WDS) + goto out; + /* Discard multicast if IFF_MULTICAST not set */ if ((0 != memcmp(wh->i_addr3, dev->broadcast, ETH_ALEN)) && (0 == (dev->flags & IFF_MULTICAST))) { -@@ -482,24 +488,6 @@ +@@ -482,24 +491,10 @@ vap->iv_stats.is_rx_mcastecho++; goto out; } @@ -63,10 +68,26 @@ - goto out; - } - } ++ } else { ++ /* Same BSSID, but not meant for us to receive */ ++ if (!IEEE80211_ADDR_EQ(wh->i_addr1, vap->iv_myaddr)) ++ goto out; } break; case IEEE80211_M_IBSS: -@@ -548,7 +536,7 @@ +@@ -541,6 +536,11 @@ + vap->iv_stats.is_rx_notassoc++; + goto err; + } ++ ++ /* subif isn't fully set up yet, drop the frame */ ++ if (ni->ni_subif == ni->ni_vap) ++ goto err; ++ + /* + * If we're a 4 address packet, make sure we have an entry in + * the node table for the packet source address (addr4). +@@ -548,9 +548,16 @@ */ /* check for wds link first */ @@ -74,14 +95,17 @@ + if ((dir == IEEE80211_FC1_DIR_DSTODS) && !ni->ni_subif) { struct ieee80211vap *avp; - TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) { -@@ -562,11 +550,13 @@ - if (ni_wds != NULL) { - ieee80211_unref_node(&ni); - ni = ieee80211_ref_node(ni_wds); -+ } else if (vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP) { ++ if (vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP) { + ieee80211_wds_addif(ni); - } ++ /* we must drop frames here until the interface has ++ * been fully separated, otherwise a bridge might get ++ * confused */ ++ goto err; ++ } + TAILQ_FOREACH(avp, &vap->iv_wdslinks, iv_wdsnext) { + if (!memcmp(avp->wds_mac, wh->i_addr2, IEEE80211_ADDR_LEN)) { + IEEE80211_LOCK_IRQ(ni->ni_ic); +@@ -566,7 +573,7 @@ } /* XXX: Useless node mgmt API; make better */ @@ -90,7 +114,7 @@ struct ieee80211_node_table *nt = &ic->ic_sta; struct ieee80211_frame_addr4 *wh4; -@@ -626,6 +616,11 @@ +@@ -626,6 +633,11 @@ goto out; } @@ -102,7 +126,7 @@ /* * Handle privacy requirements. Note that we * must not be preempted from here until after -@@ -698,8 +693,12 @@ +@@ -698,8 +710,12 @@ if (! accept_data_frame(vap, ni, key, skb, eh)) goto out; @@ -117,7 +141,7 @@ IEEE80211_NODE_STAT(ni, rx_data); IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len); ic->ic_lastdata = jiffies; -@@ -1132,6 +1131,13 @@ +@@ -1132,6 +1148,13 @@ dev = vap->iv_xrvap->iv_dev; #endif @@ -131,14 +155,23 @@ /* perform as a bridge within the vap */ /* XXX intra-vap bridging only */ if (vap->iv_opmode == IEEE80211_M_HOSTAP && -@@ -1157,6 +1163,7 @@ +@@ -1157,7 +1180,16 @@ if (ni1 != NULL) { if (ni1->ni_vap == vap && ieee80211_node_is_authorized(ni1) && -+ !ni->ni_subif && ++ !ni1->ni_subif && ni1 != vap->iv_bss) { ++ ++ /* tried to bridge to a subif, drop the packet */ ++ if (ni->ni_subif) { ++ ieee80211_unref_node(&ni1); ++ ieee80211_dev_kfree_skb(&skb); ++ return; ++ } ++ skb1 = skb; skb = NULL; + } --- a/net80211/ieee80211_ioctl.h +++ b/net80211/ieee80211_ioctl.h @@ -649,6 +649,7 @@ @@ -218,7 +251,25 @@ default: return -EOPNOTSUPP; } -@@ -5767,6 +5778,10 @@ +@@ -4447,6 +4458,8 @@ + struct ieee80211vap *vap = ni->ni_vap; + size_t ielen; + ++ if (req->vap->iv_wdsnode && ni->ni_subif) ++ vap = ni->ni_subif; + if (vap != req->vap && vap != req->vap->iv_xrvap) /* only entries for this vap */ + return; + if ((vap->iv_opmode == IEEE80211_M_HOSTAP || +@@ -4466,6 +4479,8 @@ + size_t ielen, len; + u_int8_t *cp; + ++ if (req->vap->iv_wdsnode && ni->ni_subif) ++ vap = ni->ni_subif; + if (vap != req->vap && vap != req->vap->iv_xrvap) /* only entries for this vap (or) xrvap */ + return; + if ((vap->iv_opmode == IEEE80211_M_HOSTAP || +@@ -5767,6 +5782,10 @@ 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_minrate"}, { IEEE80211_IOCTL_SETSCANLIST, IW_PRIV_TYPE_CHAR | 255, 0, "setscanlist"}, @@ -229,7 +280,7 @@ #ifdef ATH_REVERSE_ENGINEERING /* -@@ -5890,6 +5905,8 @@ +@@ -5890,6 +5909,8 @@ ieee80211_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) { struct ieee80211vap *vap = dev->priv; @@ -238,7 +289,7 @@ switch (cmd) { case SIOCG80211STATS: -@@ -5898,8 +5915,20 @@ +@@ -5898,8 +5919,20 @@ case SIOC80211IFDESTROY: if (!capable(CAP_NET_ADMIN)) return -EPERM; @@ -739,7 +790,7 @@ hdrsize = sizeof(struct ieee80211_frame); SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE)); -+ if (!SKB_CB(skb)->auth_pkt && ni->ni_subif) ++ if (ni->ni_subif) + vap = ni->ni_subif; switch (vap->iv_opmode) {