mac80211: IEEE802.11e/WMM TS management and DLS support
Subsystems (2)
PATCH 2/3 mac80211: IEEE802.11e/WMM TS management and DLS support
This patch adds IEEE802.11e/WMM Traffic Stream (TS) Management and Direct Link Setup (DLS) non-AP QSTA mode support for mac80211.
--- include/linux/ieee80211.h | 10 + net/mac80211/ieee80211.c | 18 +- net/mac80211/ieee80211_i.h | 53 +++ net/mac80211/ieee80211_iface.c | 8 + net/mac80211/ieee80211_sta.c | 813 +++++++++++++++++++++++++++++++++++++++- net/mac80211/sta_info.c | 34 ++- net/mac80211/sta_info.h | 10 +- net/mac80211/wme.c | 38 ++- 8 files changed, 963 insertions(+), 21 deletions(-)
include/linux/ieee80211.h +10 -0
@@ -401,6 +401,16 @@ enum ieee80211_reasoncode { WLAN_REASON_QSTA_CIPHER_NOT_SUPP = 45, }; + +/* Category Code */ +enum ieee80211_category { +WLAN_CATEGORY_SPECTRUM_MGMT =0 , +WLAN_CATEGORY_QOS =1 , +WLAN_CATEGORY_DLS =2 , +WLAN_CATEGORY_BACK =3 , +WLAN_CATEGORY_WMM =17 , +}; +/* QoS Action Code */ enum ieee80211_qos_actioncode {WLAN_ACTION_QOS_ADDTS_REQ =0 ,
net/mac80211/ieee80211.c +13 -5
@@ -1557,11 +1557,18 @@ static int ieee80211_subif_start_xmit(struct sk_buff *skb,memcpy (hdr.addr4, skb->data +ETH_ALEN ,ETH_ALEN ); hdrlen =30 ; }else if (sdata->type ==IEEE80211_IF_TYPE_STA ) { - fc |=IEEE80211_FCTL_TODS ; -/* BSSID SA DA */ -memcpy (hdr.addr1, sdata->u.sta.bssid,ETH_ALEN ); -memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); -memcpy (hdr.addr3, skb->data,ETH_ALEN ); +if (dls_link_status (local, skb->data) ==DLS_STATUS_OK ){ +/* DA SA BSSID */ +memcpy (hdr.addr1, skb->data,ETH_ALEN ); +memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); +memcpy (hdr.addr3, sdata->u.sta.bssid,ETH_ALEN ); + }else { + fc |=IEEE80211_FCTL_TODS ; +/* BSSID SA DA */ +memcpy (hdr.addr1, sdata->u.sta.bssid,ETH_ALEN ); +memcpy (hdr.addr2, skb->data +ETH_ALEN ,ETH_ALEN ); +memcpy (hdr.addr3, skb->data,ETH_ALEN ); + } hdrlen =24 ; }else if (sdata->type ==IEEE80211_IF_TYPE_IBSS ) {/* DA SA BSSID */
@@ -2281,6 +2288,7 @@ static void ieee80211_if_shutdown(struct net_device *dev)case IEEE80211_IF_TYPE_IBSS : sdata->u.sta.state =IEEE80211_DISABLED ;del_timer_sync (&sdata->u.sta.timer); +del_timer_sync (&sdata->u.sta.admit_timer);skb_queue_purge (&sdata->u.sta.skb_queue);if (!local->ops->hw_scan && local->scan_dev == sdata->dev) {
net/mac80211/ieee80211_i.h +53 -0
95 lines not on this page · raw message
net/mac80211/ieee80211_iface.c +8 -0
@@ -182,6 +182,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) (unsigned long) sdata);skb_queue_head_init (&ifsta->skb_queue); +init_timer (&ifsta->admit_timer); + ifsta->admit_timer.data = (unsigned long ) dev; + ifsta->admit_timer.function = ieee80211_admit_refresh; + ifsta->capab =WLAN_CAPABILITY_ESS ; ifsta->auth_algs =IEEE80211_AUTH_ALG_OPEN |IEEE80211_AUTH_ALG_SHARED_KEY ;
@@ -190,6 +194,10 @@ void ieee80211_if_set_type(struct net_device *dev, int type) ifsta->auto_channel_sel =1 ; ifsta->auto_bssid_sel =1 ; +/* Initialize non-AP QSTA QoS Params */ + ifsta->dot11EDCAAveragingPeriod =5 ; + ifsta->MPDUExchangeTime =0 ; + msdata =IEEE80211_DEV_TO_SUB_IF (sdata->local->mdev); sdata->bss = &msdata->u.ap;break ;
net/mac80211/ieee80211_sta.c +809 -4
874 lines not on this page · raw message
net/mac80211/sta_info.c +30 -4
@@ -33,7 +33,7 @@ static void sta_info_hash_add(struct ieee80211_local *local,/* Caller must hold local->sta_lock */ static void sta_info_hash_del (struct ieee80211_local *local, -struct sta_info *sta) +struct sta_info *sta,int dls) {struct sta_info *s;
@@ -41,15 +41,19 @@ static void sta_info_hash_del(struct ieee80211_local *local,if (!s)return ;if (memcmp (s->addr, sta->addr,ETH_ALEN ) ==0 ) { +if (dls && !s->dls_sta) +return ; local->sta_hash[STA_HASH (sta->addr)] = s->hnext;return ; }while (s->hnext &&memcmp (s->hnext->addr, sta->addr,ETH_ALEN ) !=0 ) s = s->hnext; -if (s->hnext) +if (s->hnext) { +if (dls && !s->hnext->dls_sta) +return ; s->hnext = s->hnext->hnext; -else + }else printk (KERN_ERR "%s: could not remove STA " MAC_FMT " from " "hash table\n" , local->mdev->name,MAC_ARG (sta->addr)); }
@@ -78,6 +82,28 @@ struct sta_info *sta_info_get(struct ieee80211_local *local, u8 *addr) }EXPORT_SYMBOL (sta_info_get); +struct sta_info *dls_info_get (struct ieee80211_local *local,u8 *addr) +{ +struct sta_info *sta; + +spin_lock_bh (&local->sta_lock); + sta = local->sta_hash[STA_HASH (addr)]; +while (sta) { +if (memcmp (sta->addr, addr,ETH_ALEN ) ==0 ) { +if (!sta->dls_sta) { + sta =NULL ; +break ; + } +__sta_info_get (sta); +break ; + } + sta = sta->hnext; + } +spin_unlock_bh (&local->sta_lock); + +return sta; +} +int sta_info_min_txrate_get (struct ieee80211_local *local) {struct sta_info *sta;
@@ -218,7 +244,7 @@ static void sta_info_remove(struct sta_info *sta)struct ieee80211_local *local = sta->local;struct ieee80211_sub_if_data *sdata; -sta_info_hash_del (local, sta); +sta_info_hash_del (local, sta,0 );list_del (&sta->list); sdata =IEEE80211_DEV_TO_SUB_IF (sta->dev);if (sta->flags &WLAN_STA_PS ) {
net/mac80211/sta_info.h +8 -2
@@ -101,8 +101,14 @@ struct sta_info {#ifdef CONFIG_MAC80211_DEBUGFS int debugfs_registered;#endif -int assoc_ap;/* whether this is an AP that we are -* associated with as a client */ + int assoc_ap:1; /* whether this is an AP that we are +* associated with as a client */ + int dls_sta:1; /* whether this stations is a DLS peer of us */ + +#define DLS_STATUS_OK 0 +#define DLS_STATUS_NOLINK 1 +int dls_status; +u32 dls_timeout;#ifdef CONFIG_MAC80211_DEBUG_COUNTERS unsigned int wme_rx_queue[NUM_RX_DATA_QUEUES ];
net/mac80211/wme.c +32 -6
@@ -158,11 +158,13 @@ static inline int wme_downgrade_ac(struct sk_buff *skb)static inline int classify80211 (struct sk_buff *skb,struct Qdisc *qd) {struct ieee80211_local *local =wdev_priv (qd->dev->ieee80211_ptr); +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (qd->dev); +struct ieee80211_if_sta *ifsta = &sdata->u.sta;struct ieee80211_tx_packet_data *pkt_data = (struct ieee80211_tx_packet_data *) skb->cb;struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;unsigned short fc =le16_to_cpu (hdr->frame_control); -int qos; +int qos, tsid, dir;const int ieee802_1d_to_ac[8 ] = {2 ,3 ,3 ,2 ,1 ,1 ,0 ,0 };/* see if frame is data or non data frame */
@@ -189,14 +191,38 @@ static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) }/* use the data classifier to determine what 802.1d tag the -* data frame has */ +* data frame has */ skb->priority =classify_1d (skb, qd); + tsid =8 + skb->priority; + +/* FIXME: only uplink needs to be checked for Tx */ + dir =STA_TS_UPLINK ; + +if ((sdata->type ==IEEE80211_IF_TYPE_STA ) && + (local->wmm_acm &BIT (skb->priority))) { +switch (ifsta->ts_data[tsid][dir].status) { +case TS_STATUS_ACTIVE : +/* if TS Management is enabled, update used_time */ + ifsta->ts_data[tsid][dir].used_time_usec += + ifsta->MPDUExchangeTime; +break ; +case TS_STATUS_THROTTLING : +/* if admitted time is used up, refuse to send more */ +if (net_ratelimit ()) +printk (KERN_DEBUG "QoS packet throttling\n" ); +break ; +default : +break ; + } + } -/* incase we are a client verify acm is not set for this ac */ -while (unlikely (local->wmm_acm &BIT (skb->priority))) { +/* in case we are a client verify acm is not set for this ac */ +while ((local->wmm_acm &BIT (skb->priority)) && + !((sdata->type ==IEEE80211_IF_TYPE_STA ) && + (ifsta->ts_data[skb->priority +EDCA_TSID_MIN ][dir].status + ==TS_STATUS_ACTIVE ))) {if (wme_downgrade_ac (skb)) { -/* No AC with lower priority has acm=0, -* drop packet. */ +/* No AC with lower priority has acm=0, drop packet. */ return -1 ; } }
Signature · 1 line
1.5.0.rc2.g73a2
Johannes Berg
maintainerSome nitpicking below :)
net/mac80211/ieee80211.c static int ieee80211_subif_start_xmit(struct sk_buff *skb, · line 1560
Quoted 1 line
net/mac80211/ieee80211.c +1
-0+if (dls_link_status (local, skb->data) ==DLS_STATUS_OK ){
missing space there, but maybe the line is too long with it?
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 199
Quoted 5 lines
net/mac80211/ieee80211_sta.c +5
-0+case WIFI_OUI_STYPE_WMM_TSPEC : +if (elen !=61 ) { +printk (KERN_ERR "Wrong " +"TSPEC size.\n" ); +break ;
That printk should be rate limited.
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 207
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+default : +//printk(KERN_ERR "Unsupported " +// "WiFi OUI %d\n", pos[4]); +break ;
And maybe that should be there for the debug case (rate limited as well)?
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 227
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+case WLAN_EID_TSPEC : +if (elen !=55 ) { +printk (KERN_ERR "Wrong TSPEC size.\n" ); +break ;
Ditto.
net/mac80211/ieee80211_sta.c static void ieee80211_send_disassoc(struct net_device *dev, · line 805
Quoted 2 lines
net/mac80211/ieee80211_sta.c +2
-0+if (ifsta->ts_data[tsid][index].status ==TS_STATUS_UNUSED ) { + printk(KERN_DEBUG "%s: Tring to delete an ACM disabled TS "
typo "Tring".
Can this be invoked by somebody requesting you to do it? If so it should be rate limited as well. I haven't quite understood the code flow here yet.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1756
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems) + == ParseFailed) { +printk (KERN_DEBUG "%s: failed to parse TSPEC\n" , dev->name); +return ;
Wants rate limiting too, afaict.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1789
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_DEBUG "Receive DLS request from " +"%02X:%02X:%02X:%02X:%02X:%02X\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ]);
Again?
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1798
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (ieee802_11_parse_elems (mgmt->u.action.u.dls_req.variable, + len - baselen, &elems) == ParseFailed) { +printk (KERN_ERR "DLS Parse support rates failed.\n" ); +return ;
and again?
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1863
Quoted 9 lines
net/mac80211/ieee80211_sta.c +9
-0+printk (KERN_DEBUG "Receive DLS response from " +"%02X:%02X:%02X:%02X:%02X:%02X\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ]); + +if (mgmt->u.action.u.dls_resp.status_code) { +printk (KERN_ERR "DLS setup refused by peer. Reason %d\n" , + mgmt->u.action.u.dls_resp.status_code); +return ; + }
I suppose these are ok since we're not going to request DLS a lot, right?
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1920
Quoted 8 lines
net/mac80211/ieee80211_sta.c +8
-0+printk (KERN_DEBUG "DLS Teardown received from " +"%02X:%02X:%02X:%02X:%02X:%02X. Reason %d\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ], + mgmt->u.action.u.dls_teardown.reason_code); + + dls =dls_info_get (local, src); +if (dls) +sta_info_free (dls,0 );
Do we really want to free the sta info here? Shouldn't we have a sta info item for the DLS peer anyway, and then we can't free it here but rather reset the DLS status?
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2432
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (len <24 +4 ) { +printk (KERN_DEBUG "%s: too short (%zd) QoS category " +"frame received from " MAC_FMT " - ignored\n" , + dev->name, len,MAC_ARG (mgmt->sa));
rate limit.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2466
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_ERR "%s: unsupported QoS action code %d\n" , + dev->name, + mgmt->u.action.u.wme_action.action_code);
rate limit.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2475
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_DEBUG "%s: too short (%zd) DLS category " +"frame received from " MAC_FMT " - ignored\n" , + dev->name, len,MAC_ARG (mgmt->sa));
ditto.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2490
Quoted 2 lines
net/mac80211/ieee80211_sta.c +2
-0+printk (KERN_ERR "%s: unsupported DLS action code %d\n" , + dev->name, mgmt->u.action.u.dls_req.action_code);
ditto.
Quoted 1 line
+struct
sta_info*dls_info_get(structieee80211_local*local, u8 *addr)
Ok, I don't understand the DLS info stuff. Basically it's a sta info, but why not just do sta_info_get() on the regular one and then set the dls peer bit?
net/mac80211/wme.c static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) · line 212
Quoted 2 lines
net/mac80211/wme.c +2
-0+if (net_ratelimit ()) +printk (KERN_DEBUG "QoS packet throttling\n" );
Hey! :)
johannes
Quoted 5 lines · Johannes Berg
Some nitpicking below :)
net/mac80211/ieee80211.c static int ieee80211_subif_start_xmit(struct sk_buff *skb, · line 1560
Quoted 1 line
net/mac80211/ieee80211.c +1
-0+if (dls_link_status (local, skb->data) ==DLS_STATUS_OK ){missing space there, but maybe the line is too long with it?
Yup. The line happens to be 80 originally before Michael pointed a bug here. I forgot to add the space back after that.
Quoted 7 lines
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 199
Quoted 5 lines
net/mac80211/ieee80211_sta.c +5
-0+case WIFI_OUI_STYPE_WMM_TSPEC : +if (elen !=61 ) { +printk (KERN_ERR "Wrong " +"TSPEC size.\n" ); +break ;That printk should be rate limited.
Umm, I followed the same way as other MLME parsing functions ie. ieee80211_rx_mgmt_assoc_resp. It seems they also didn't rate limit these cases. This only happens on broken APs. Do you think we really need to rate limit here?
Quoted 7 lines
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 207
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+default : +//printk(KERN_ERR "Unsupported " +// "WiFi OUI %d\n", pos[4]); +break ;And maybe that should be there for the debug case (rate limited as well)?
I got a lot of this message during my testing. The APs use some (private) OUIs we don't support now. I guess there will be quite a lot messages even if we rate limit here.
Quoted 11 lines
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 227
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+case WLAN_EID_TSPEC : +if (elen !=55 ) { +printk (KERN_ERR "Wrong TSPEC size.\n" ); +break ;Ditto.
net/mac80211/ieee80211_sta.c static void ieee80211_send_disassoc(struct net_device *dev, · line 805
Quoted 2 lines
net/mac80211/ieee80211_sta.c +2
-0+if (ifsta->ts_data[tsid][index].status ==TS_STATUS_UNUSED ) { + printk(KERN_DEBUG "%s: Tring to delete an ACM disabled TS "typo "Tring".
Thanks!
Quoted 10 lines
Can this be invoked by somebody requesting you to do it? If so it should be rate limited as well. I haven't quite understood the code flow here yet.
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1756
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems) + == ParseFailed) { +printk (KERN_DEBUG "%s: failed to parse TSPEC\n" , dev->name); +return ;Wants rate limiting too, afaict.
mac80211 doesn't rate limit ParseFailed cases in other parts. ie. ieee80211_rx_mgmt_assoc_resp, etc.
Quoted 5 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1789
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_DEBUG "Receive DLS request from " +"%02X:%02X:%02X:%02X:%02X:%02X\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ]);Again?
This management packet is sent from the AP. Not from the STA user requests DLS connection directly. So can I compare this to the following line in ieee80211_rx_mgmt_assoc_resp().
printk(KERN_DEBUG "%s: RX %sssocResp from " MAC_FMT " (capab=0x%x "
"status=%d aid=%d)\n",
dev->name, reassoc ? "Rea" : "A", MAC_ARG(mgmt->sa),
capab_info, status_code, aid);Quoted 6 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1798
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (ieee802_11_parse_elems (mgmt->u.action.u.dls_req.variable, + len - baselen, &elems) == ParseFailed) { +printk (KERN_ERR "DLS Parse support rates failed.\n" ); +return ;and again?
See above.
Quoted 4 lines
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+printk (KERN_DEBUG "Receive DLS response from " +"%02X:%02X:%02X:%02X:%02X:%02X\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ]); +
Quoted 8 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1863
Quoted 5 lines
net/mac80211/ieee80211_sta.c +5
-0+if (mgmt->u.action.u.dls_resp.status_code) { +printk (KERN_ERR "DLS setup refused by peer. Reason %d\n" , + mgmt->u.action.u.dls_resp.status_code); +return ; + }I suppose these are ok since we're not going to request DLS a lot, right?
Yup.
Quoted 4 lines
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+printk (KERN_DEBUG "DLS Teardown received from " +"%02X:%02X:%02X:%02X:%02X:%02X. Reason %d\n" , + src[0 ], src[1 ], src[2 ], src[3 ], src[4 ], src[5 ], + mgmt->u.action.u.dls_teardown.reason_code);
Quoted 8 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev, · line 1920
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+ + dls =dls_info_get (local, src); +if (dls) +sta_info_free (dls,0 );Do we really want to free the sta info here? Shouldn't we have a sta info item for the DLS peer anyway, and then we can't free it here but rather reset the DLS status?
Yes we can do this. But free it here helps to shrink the hash table size. The problem is: the original sta_info doesn't a status -- if a sta_info appears in the hash table, it is active; otherwise it is not. But since DLS requires setup stage, I added the status code to distinguish setuping and active. But for inactive state, we can either set the DLS status to inactive or remove the sta_info completely. Since normally a DLS connection won't be setup and teardown that often, I select to free the sta_info to indicate it as inactive.
Quoted 6 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2432
Quoted 4 lines
net/mac80211/ieee80211_sta.c +4
-0+if (len <24 +4 ) { +printk (KERN_DEBUG "%s: too short (%zd) QoS category " +"frame received from " MAC_FMT " - ignored\n" , + dev->name, len,MAC_ARG (mgmt->sa));rate limit.
See the following code in ieee80211_rx_mgmt_auth()
if (len < 24 + 6) {
printk(KERN_DEBUG "%s: too short (%zd) authentication
frame "
"received from " MAC_FMT " - ignored\n",
dev->name, len, MAC_ARG(mgmt->sa));
return;
}Quoted 5 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2466
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_ERR "%s: unsupported QoS action code %d\n" , + dev->name, + mgmt->u.action.u.wme_action.action_code);rate limit.
There is no other QoS action code not supported by mac80211. If we see any, we can fix it.
Quoted 5 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2475
Quoted 3 lines
net/mac80211/ieee80211_sta.c +3
-0+printk (KERN_DEBUG "%s: too short (%zd) DLS category " +"frame received from " MAC_FMT " - ignored\n" , + dev->name, len,MAC_ARG (mgmt->sa));ditto.
see above.
Quoted 5 lines
net/mac80211/ieee80211_sta.c static void ieee80211_rx_mgmt_probe_req(struct net_device *dev, · line 2490
Quoted 3 lines
net/mac80211/ieee80211_sta.c +2
-0+printk (KERN_ERR "%s: unsupported DLS action code %d\n" , + dev->name, mgmt->u.action.u.dls_req.action_code);ditto.
see above.
Quoted 5 lines
Quoted 1 line
+struct
sta_info*dls_info_get(structieee80211_local*local, u8 *addr)Ok, I don't understand the DLS info stuff. Basically it's a sta info, but why not just do
sta_info_get()on the regular one and then set the dls peer bit?
Do you mean below code instead?
struct sta_info *dls_info_get()
{
sta = sta_info_get(local, addr);
if (sta)
if (sta->dls_sta)
return sta;
else
sta_info_put(sta);
return NULL;
}This is not optimized in the (sta && !sta->dls_sta) case.
Quoted 4 lines
net/mac80211/wme.c static inline int classify80211(struct sk_buff *skb, struct Qdisc *qd) · line 212
Quoted 2 lines
net/mac80211/wme.c +2
-0+if (net_ratelimit ()) +printk (KERN_DEBUG "QoS packet throttling\n" );Hey! :)
Yeah, that's a hot path.
Thanks for your feedbacks!
-yi
Johannes Berg
maintainerQuoted 8 lines · Zhu Yi
Quoted 7 lines
net/mac80211/ieee80211_sta.c static ParseRes ieee802_11_parse_elems(u8 *start, size_t len, · line 199
Quoted 5 lines
net/mac80211/ieee80211_sta.c +5
-0+case WIFI_OUI_STYPE_WMM_TSPEC : +if (elen !=61 ) { +printk (KERN_ERR "Wrong " +"TSPEC size.\n" ); +break ;That printk should be rate limited.
Quoted 4 lines
Umm, I followed the same way as other MLME parsing functions ie.
ieee80211_rx_mgmt_assoc_resp. It seems they also didn't rate limit these cases. This only happens on broken APs. Do you think we really need to rate limit here?
Ok, wrt. all the rate limiting I thought of. You rightfully pointed out that the current code is just as broken, hence I'm ok with adding these like this and I'll go through and fix them later. My rationale with many of these is that somebody could inject random packets appearing to come from our AP and cause us to write a log line for every packet they inject by intentionally injecting malformed packets. We should protect against that.
Quoted 3 lines
I got a lot of this message during my testing. The APs use some (private) OUIs we don't support now. I guess there will be quite a lot messages even if we rate limit here.
Oh right, like those Broadcom IEs they use for a-mpdu even on .11G...
Quoted 8 lines
Yes we can do this. But free it here helps to shrink the hash table size. The problem is: the original
sta_infodoesn't a status -- if asta_infoappears in the hash table, it is active; otherwise it is not. But since DLS requires setup stage, I added the status code to distinguish setuping and active. But for inactive state, we can either set the DLS status to inactive or remove thesta_infocompletely. Since normally a DLS connection won't be setup and teardown that often, I select to free thesta_infoto indicate it as inactive.
Makes sense. I thought we had a sta info item for each peer we ever discovered but I guess that isn't true.
johannes