Message ID | 1383266638-4813-1-git-send-email-Larry.Finger@lwfinger.net |
---|---|
State | Not Applicable, archived |
Delegated to: | David Miller |
Headers | show |
On Thu, 2013-10-31 at 19:43 -0500, Larry Finger wrote: > From: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > > All of the rtlwifi drivers have an error in the routine that tests if > the data is "special". If it is, the subsequant transmission will be > at the lowest rate to enhance reliability. The 16-bit quantity is > big-endian, but was being extracted in native CPU mode. One of the > effects of this bug is to inhibit association under some conditions > as the TX rate is too high. > > A statement that would have made the code correct had been changed to > a comment. Rather than just reinstating that code, the fix here passes > sparse tests. A side effect of fixing this problem would have been to force > all IPv6 frames to run at the lowest rate. The test for that frame type > is removed. > > The original code only checked the lower-order byte of UDP ports for BOOTP > protocol. That is extended to the full 16-bit source and destination ports. > > One of the local headers contained duplicates of some of the ETH_P_XXX > definitions. These are deleted. > > Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> > Cc: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> > Cc: Stable <stable@vger.kernel.org> [2.6.38+] > --- > > V2 - Addresses comments by Ben Hutchings and Bjorn Mork. > > drivers/net/wireless/rtlwifi/base.c | 15 ++++++--------- > drivers/net/wireless/rtlwifi/wifi.h | 6 +----- > 2 files changed, 7 insertions(+), 14 deletions(-) > Index: wireless-testing-save/drivers/net/wireless/rtlwifi/base.c > =================================================================== > --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/base.c > +++ wireless-testing-save/drivers/net/wireless/rtlwifi/base.c > @@ -1077,17 +1077,17 @@ u8 rtl_is_special_data(struct ieee80211_ > > ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + > SNAP_SIZE + PROTOC_TYPE_SIZE); > - ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); > - /* ether_type = ntohs(ether_type); */ > + ether_type = be16_to_cpu(*(__be16 *)((u8 *)skb->data + mac_hdr_len + > + SNAP_SIZE)); > > if (ETH_P_IP == ether_type) { > if (IPPROTO_UDP == ip->protocol) { > struct udphdr *udp = (struct udphdr *)((u8 *) ip + > (ip->ihl << 2)); > - if (((((u8 *) udp)[1] == 68) && > - (((u8 *) udp)[3] == 67)) || > - ((((u8 *) udp)[1] == 67) && > - (((u8 *) udp)[3] == 68))) { > + if (((((u16 *) udp)[0] == 68) && > + (((u16 *) udp)[2] == 67)) || > + ((((u16 *) udp)[0] == 67) && > + (((u16 *) udp)[2] == 68))) { [...] Now you're missing byte-swapping here, and using the wrong offset for the dest port (4 bytes rather than 2). If you really think this is necessary then use something like: if ((udp->source == htons(68) && udp->dest == htons(67)) || ... Ben.
Index: wireless-testing-save/drivers/net/wireless/rtlwifi/base.c =================================================================== --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/base.c +++ wireless-testing-save/drivers/net/wireless/rtlwifi/base.c @@ -1077,17 +1077,17 @@ u8 rtl_is_special_data(struct ieee80211_ ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len + SNAP_SIZE + PROTOC_TYPE_SIZE); - ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE); - /* ether_type = ntohs(ether_type); */ + ether_type = be16_to_cpu(*(__be16 *)((u8 *)skb->data + mac_hdr_len + + SNAP_SIZE)); if (ETH_P_IP == ether_type) { if (IPPROTO_UDP == ip->protocol) { struct udphdr *udp = (struct udphdr *)((u8 *) ip + (ip->ihl << 2)); - if (((((u8 *) udp)[1] == 68) && - (((u8 *) udp)[3] == 67)) || - ((((u8 *) udp)[1] == 67) && - (((u8 *) udp)[3] == 68))) { + if (((((u16 *) udp)[0] == 68) && + (((u16 *) udp)[2] == 67)) || + ((((u16 *) udp)[0] == 67) && + (((u16 *) udp)[2] == 68))) { /* * 68 : UDP BOOTP client * 67 : UDP BOOTP server @@ -1126,9 +1126,6 @@ u8 rtl_is_special_data(struct ieee80211_ } return true; - } else if (ETH_P_IPV6 == ether_type) { - /* IPv6 */ - return true; } return false; Index: wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h =================================================================== --- wireless-testing-save.orig/drivers/net/wireless/rtlwifi/wifi.h +++ wireless-testing-save/drivers/net/wireless/rtlwifi/wifi.h @@ -77,11 +77,7 @@ #define RTL_SLOT_TIME_9 9 #define RTL_SLOT_TIME_20 20 -/*related with tcp/ip. */ -/*if_ehther.h*/ -#define ETH_P_PAE 0x888E /*Port Access Entity (IEEE 802.1X) */ -#define ETH_P_IP 0x0800 /*Internet Protocol packet */ -#define ETH_P_ARP 0x0806 /*Address Resolution packet */ +/*related to tcp/ip. */ #define SNAP_SIZE 6 #define PROTOC_TYPE_SIZE 2