some more fixes for wds sta separation
authorFelix Fietkau <nbd@openwrt.org>
Tue, 5 Aug 2008 07:19:07 +0000 (07:19 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 5 Aug 2008 07:19:07 +0000 (07:19 +0000)
SVN-Revision: 12127

package/madwifi/patches/371-wds_sta_separation.patch
package/madwifi/patches/372-queue_vif.patch

index 57b62b089b90a596194616d40942d4687e8e525b..aded93b25f79768cd10bcf14be19ecf00bf91717 100644 (file)
                        }
                        break;
                case IEEE80211_M_IBSS:
-@@ -548,7 +536,7 @@
+@@ -541,6 +529,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 +541,16 @@
                         */
  
                        /* check for wds link first */
 +                      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 +566,7 @@
                        }
  
                        /* XXX: Useless node mgmt API; make better */
                                struct ieee80211_node_table *nt = &ic->ic_sta;
                                struct ieee80211_frame_addr4 *wh4;
  
-@@ -626,6 +616,11 @@
+@@ -626,6 +626,11 @@
                        goto out;
                }
  
                /*
                 * Handle privacy requirements.  Note that we
                 * must not be preempted from here until after
-@@ -698,8 +693,12 @@
+@@ -698,8 +703,12 @@
                if (! accept_data_frame(vap, ni, key, skb, eh))
                        goto out;
  
                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 +1141,13 @@
                dev = vap->iv_xrvap->iv_dev;
  #endif
  
        /* 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 +1173,15 @@
                        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_dev_kfree_skb(&skb);
++                                              return;
++                                      }
++
                                        skb1 = skb;
                                        skb = NULL;
+                               }
 --- a/net80211/ieee80211_ioctl.h
 +++ b/net80211/ieee80211_ioctl.h
 @@ -649,6 +649,7 @@
        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"},
  
  #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;
  
        switch (cmd) {
        case SIOCG80211STATS:
-@@ -5898,8 +5915,20 @@
+@@ -5898,8 +5919,20 @@
        case SIOC80211IFDESTROY:
                if (!capable(CAP_NET_ADMIN))
                        return -EPERM;
index 1a86bea1b186bc2ad7ca02ca3ad9ee5870da455f..9b05a3f0765505ede8f64b5e92eedf8f73370040 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net80211/ieee80211_input.c
 +++ b/net80211/ieee80211_input.c
-@@ -1174,6 +1174,7 @@
+@@ -1191,6 +1191,7 @@
                }
                if (skb1 != NULL) {
                        struct ieee80211_node *ni_tmp;
@@ -8,7 +8,7 @@
                        skb1->dev = dev;
                        skb_reset_mac_header(skb1);
                        skb_set_network_header(skb1, sizeof(struct ether_header));
-@@ -1181,7 +1182,12 @@
+@@ -1198,7 +1199,12 @@
                        skb1->protocol = __constant_htons(ETH_P_802_2);
                        /* XXX insert vlan tag before queue it? */
                        ni_tmp = SKB_CB(skb1)->ni; /* remember node so we can free it */