madwifi: fix some potential null pointer derefs with wds
[openwrt-10.03/.git] / package / madwifi / patches / 387-maxassoc.patch
1 --- a/net80211/ieee80211_var.h
2 +++ b/net80211/ieee80211_var.h
3 @@ -198,6 +198,7 @@ struct ieee80211vap {
4         u_int32_t iv_debug;                             /* debug msg flags */
5         struct ieee80211_stats iv_stats;                /* statistics */
6  
7 +       int iv_max_nodes;
8         int iv_monitor_nods_only;                       /* in monitor mode only nods traffic */
9         int iv_monitor_txf_len;                         /* in monitor mode, truncate tx packets */
10         int iv_monitor_phy_errors;                      /* in monitor mode, accept phy errors */
11 --- a/net80211/ieee80211_ioctl.h
12 +++ b/net80211/ieee80211_ioctl.h
13 @@ -650,6 +650,7 @@ enum {
14         IEEE80211_PARAM_RSSI_DIS_THR    = 80,   /* rssi threshold for disconnection */
15         IEEE80211_PARAM_RSSI_DIS_COUNT  = 81,   /* counter for rssi threshold */
16         IEEE80211_PARAM_WDS_SEP                 = 82,   /* move wds stations into separate interfaces */
17 +       IEEE80211_PARAM_MAXASSOC                = 83,   /* maximum associated stations */
18  };
19  
20  #define        SIOCG80211STATS                 (SIOCDEVPRIVATE+2)
21 --- a/net80211/ieee80211_wireless.c
22 +++ b/net80211/ieee80211_wireless.c
23 @@ -2875,6 +2875,12 @@ ieee80211_ioctl_setparam(struct net_devi
24                 else
25                         vap->iv_flags_ext &= ~IEEE80211_FEXT_WDSSEP;
26                 break;
27 +       case IEEE80211_PARAM_MAXASSOC:
28 +               if (vap->iv_opmode != IEEE80211_M_HOSTAP)
29 +                       retv = -EINVAL;
30 +               else
31 +                       vap->iv_max_nodes = value;
32 +               break;
33  #ifdef ATH_REVERSE_ENGINEERING
34         case IEEE80211_PARAM_DUMPREGS:
35                 ieee80211_dump_registers(dev, info, w, extra);
36 @@ -3234,6 +3240,9 @@ ieee80211_ioctl_getparam(struct net_devi
37         case IEEE80211_PARAM_WDS_SEP:
38                 param[0] = !!(vap->iv_flags_ext & IEEE80211_FEXT_WDSSEP);
39                 break;
40 +       case IEEE80211_PARAM_MAXASSOC:
41 +               param[0] = vap->iv_max_nodes;
42 +               break;
43         default:
44                 return -EOPNOTSUPP;
45         }
46 @@ -5789,6 +5798,10 @@ static const struct iw_priv_args ieee802
47          IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "wdssep"},
48         { IEEE80211_PARAM_WDS_SEP,
49          0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_wdssep"},
50 +       { IEEE80211_PARAM_MAXASSOC,
51 +        IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "maxassoc"},
52 +       { IEEE80211_PARAM_MAXASSOC,
53 +        0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "get_maxassoc"},
54  
55  #ifdef ATH_REVERSE_ENGINEERING
56         /*
57 --- a/net80211/ieee80211_input.c
58 +++ b/net80211/ieee80211_input.c
59 @@ -4020,7 +4020,26 @@ ieee80211_recv_mgmt(struct ieee80211vap 
60                         vap->iv_stats.is_rx_assoc_norate++;
61                         return;
62                 }
63 +               if (vap->iv_max_nodes > 0) {
64 +                       unsigned int active_nodes = 0;
65 +                       struct ieee80211_node *tni;
66 +
67 +                       IEEE80211_NODE_TABLE_LOCK_IRQ(&ic->ic_sta);
68 +                       TAILQ_FOREACH(tni, &ic->ic_sta.nt_node, ni_list) {
69 +                               if (tni->ni_vap != vap)
70 +                                       continue;
71 +                               if (tni->ni_associd == 0)
72 +                                       continue;
73 +                               active_nodes++;
74 +                       }
75 +                       IEEE80211_NODE_TABLE_UNLOCK_IRQ(&ic->ic_sta);
76  
77 +                       if (active_nodes >= vap->iv_max_nodes) {
78 +                               /* too many nodes connected */
79 +                               ieee80211_node_leave(ni);
80 +                               return;
81 +                       }
82 +               }
83                 if (ni->ni_associd != 0 &&
84                     IEEE80211_IS_CHAN_ANYG(ic->ic_bsschan)) {
85                         if ((ni->ni_capinfo & IEEE80211_CAPINFO_SHORT_SLOTTIME)