madwifi: more wds sta related fixes
authorFelix Fietkau <nbd@openwrt.org>
Tue, 19 Aug 2008 18:22:03 +0000 (18:22 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Tue, 19 Aug 2008 18:22:03 +0000 (18:22 +0000)
SVN-Revision: 12341

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

index aded93b25f79768cd10bcf14be19ecf00bf91717..1898918642255471dc43a72c4e345e4368dbad35 100644 (file)
                if (skb->len < hdrspace) {
                        IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
                                wh, "data", "too short: len %u, expecting %u",
                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,26 @@
+               }
                switch (vap->iv_opmode) {
                case IEEE80211_M_STA:
                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)))) {
-+                          (!(vap->iv_flags_ext & IEEE80211_FEXT_WDS) &&
-+                           (dir == IEEE80211_FC1_DIR_DSTODS))) {
-                               IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
-                                       wh, "data", "invalid dir 0x%x", dir);
-                               vap->iv_stats.is_rx_wrongdir++;
-                               goto out;
+-                              IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
+-                                      wh, "data", "invalid dir 0x%x", dir);
+-                              vap->iv_stats.is_rx_wrongdir++;
+-                              goto out;
++                      {
++                              int accept;
++
++                              if (vap->iv_flags_ext & IEEE80211_FEXT_WDS)
++                                      accept = IEEE80211_FC1_DIR_DSTODS;
++                              else
++                                      accept = IEEE80211_FC1_DIR_FROMDS;
++                              if (dir != accept) {
++                                      IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY,
++                                              wh, "data", "invalid dir 0x%x", dir);
++                                      vap->iv_stats.is_rx_wrongdir++;
++                                      goto out;
++                              }
                        }
  
 -                      if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 +                      if (IEEE80211_IS_MULTICAST(wh->i_addr1)) {
 +                              /* ignore 3-addr mcast if we're WDS STA */
                        }
  
 -                      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))) {
 +                                      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 +493,10 @@
                                        vap->iv_stats.is_rx_mcastecho++;
                                        goto out;
                                }
                                        vap->iv_stats.is_rx_mcastecho++;
                                        goto out;
                                }
 -                                              goto out;
 -                                      }
 -                              }
 -                                              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:
                        }
                        break;
                case IEEE80211_M_IBSS:
-@@ -541,6 +529,11 @@
+@@ -541,6 +538,11 @@
                                vap->iv_stats.is_rx_notassoc++;
                                goto err;
                        }
                                vap->iv_stats.is_rx_notassoc++;
                                goto err;
                        }
@@ -78,7 +93,7 @@
                        /*
                         * If we're a 4 address packet, make sure we have an entry in
                         * the node table for the packet source address (addr4).
                        /*
                         * 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 @@
+@@ -548,9 +550,16 @@
                         */
  
                        /* check for wds link first */
                         */
  
                        /* check for wds link first */
                                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);
                                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 @@
+@@ -566,7 +575,7 @@
                        }
  
                        /* XXX: Useless node mgmt API; make better */
                        }
  
                        /* XXX: Useless node mgmt API; make better */
                                struct ieee80211_node_table *nt = &ic->ic_sta;
                                struct ieee80211_frame_addr4 *wh4;
  
                                struct ieee80211_node_table *nt = &ic->ic_sta;
                                struct ieee80211_frame_addr4 *wh4;
  
-@@ -626,6 +626,11 @@
+@@ -626,6 +635,11 @@
                        goto out;
                }
  
                        goto out;
                }
  
                /*
                 * Handle privacy requirements.  Note that we
                 * must not be preempted from here until after
                /*
                 * Handle privacy requirements.  Note that we
                 * must not be preempted from here until after
-@@ -698,8 +703,12 @@
+@@ -698,8 +712,12 @@
                if (! accept_data_frame(vap, ni, key, skb, eh))
                        goto out;
  
                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;
                IEEE80211_NODE_STAT(ni, rx_data);
                IEEE80211_NODE_STAT_ADD(ni, rx_bytes, skb->len);
                ic->ic_lastdata = jiffies;
-@@ -1132,6 +1141,13 @@
+@@ -1132,6 +1150,13 @@
                dev = vap->iv_xrvap->iv_dev;
  #endif
  
                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 &&
        /* perform as a bridge within the vap */
        /* XXX intra-vap bridging only */
        if (vap->iv_opmode == IEEE80211_M_HOSTAP &&
-@@ -1157,7 +1173,15 @@
+@@ -1157,7 +1182,16 @@
                        if (ni1 != NULL) {
                                if (ni1->ni_vap == vap &&
                                    ieee80211_node_is_authorized(ni1) &&
                        if (ni1 != NULL) {
                                if (ni1->ni_vap == vap &&
                                    ieee80211_node_is_authorized(ni1) &&
 +
 +                                      /* tried to bridge to a subif, drop the packet */
 +                                      if (ni->ni_subif) {
 +
 +                                      /* tried to bridge to a subif, drop the packet */
 +                                      if (ni->ni_subif) {
++                                              ieee80211_unref_node(&ni1);
 +                                              ieee80211_dev_kfree_skb(&skb);
 +                                              return;
 +                                      }
 +                                              ieee80211_dev_kfree_skb(&skb);
 +                                              return;
 +                                      }
                hdrsize = sizeof(struct ieee80211_frame);
  
        SKB_CB(skb)->auth_pkt = (eh.ether_type == __constant_htons(ETHERTYPE_PAE));
                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) {
 +              vap = ni->ni_subif;
  
        switch (vap->iv_opmode) {
index 9b05a3f0765505ede8f64b5e92eedf8f73370040..f6903ea2af7cc6c67e6d07578da3d3cdd7e80e3a 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net80211/ieee80211_input.c
 +++ b/net80211/ieee80211_input.c
 --- a/net80211/ieee80211_input.c
 +++ b/net80211/ieee80211_input.c
-@@ -1191,6 +1191,7 @@
+@@ -1201,6 +1201,7 @@
                }
                if (skb1 != NULL) {
                        struct ieee80211_node *ni_tmp;
                }
                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));
                        skb1->dev = dev;
                        skb_reset_mac_header(skb1);
                        skb_set_network_header(skb1, sizeof(struct ether_header));
-@@ -1198,7 +1199,12 @@
+@@ -1208,7 +1209,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 */
                        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 */
index e8b4c22b648965b740330377017d91032eb00eef..1295063c0d52369cc6a5e48cea5b5b48cd3a307f 100644 (file)
@@ -1,6 +1,6 @@
 --- a/net80211/ieee80211_input.c
 +++ b/net80211/ieee80211_input.c
 --- a/net80211/ieee80211_input.c
 +++ b/net80211/ieee80211_input.c
-@@ -3522,6 +3522,11 @@
+@@ -3532,6 +3532,11 @@
                if (ic->ic_flags & IEEE80211_F_SCAN) {
                        ieee80211_add_scan(vap, &scan, wh, subtype, rssi, rtsf);
                }
                if (ic->ic_flags & IEEE80211_F_SCAN) {
                        ieee80211_add_scan(vap, &scan, wh, subtype, rssi, rtsf);
                }