2.6.23-stable review, network changes
Subsystems (8)
cover 2.6.23-stable review, network changes
This is the start of the stable review cycle for the 2.6.23.X release. There are 23 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let us know. If anyone is a maintainer of the proper subsystem, and wants to add a Signed-off-by: line to the patch, please respond with it.
These patches are sent out with a number of different people on the
Cc: line. If you wish to be a reviewer, please email [email protected] to add your name to the list. If you want to be off the reviewer list, also email us.
Responses should be made by Friday 00:00:00 UTC. Anything received after that time might be too late.
This set of patches focuses on only the core kernel. Other sets of patches will follow if you are interested in those instead.
The diffstat of this review series is included below.
thanks,
greg k-h
------
include/linux/netlink.h | 2 include/linux/skbuff.h | 3 include/net/9p/9p.h | 12 ++ ipc/mqueue.c | 6 - net/8021q/vlan.c | 5 + net/ieee80211/ieee80211_crypt_tkip.c | 2 net/ieee80211/softmac/ieee80211softmac_wx.c | 2 net/ipv4/ipcomp.c | 3 net/ipv6/ipcomp6.c | 3 net/mac80211/ieee80211.c | 55 +++++++----- net/mac80211/ieee80211_ioctl.c | 11 ++ net/mac80211/ieee80211_sta.c | 128 +++++++++++----------------- net/netfilter/nf_conntrack_proto_tcp.c | 38 +++----- net/netlink/af_netlink.c | 10 +- net/sched/cls_u32.c | 4 net/sched/sch_api.c | 5 - net/sched/sch_teql.c | 3 net/socket.c | 6 + 18 files changed, 161 insertions(+), 137 deletions(-)
PATCH 1/23 mac80211: filter locally-originated multicast frames
-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
patch b331615722779b078822988843ddffd4eaec9f83 in mainline.
In STA mode, the AP will echo our traffic. This includes multicast traffic.
Receiving these frames confuses some protocols and applications, notably IPv6 Duplicate Address Detection.
--- net/mac80211/ieee80211.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
net/mac80211/ieee80211.c +3 -2
@@ -2836,9 +2836,10 @@ ieee80211_rx_h_data(struct ieee80211_txrmemcpy (dst, hdr->addr1,ETH_ALEN );memcpy (src, hdr->addr3,ETH_ALEN ); -if (sdata->type !=IEEE80211_IF_TYPE_STA ) { +if (sdata->type !=IEEE80211_IF_TYPE_STA || + (is_multicast_ether_addr (dst) && + !compare_ether_addr (src, dev->dev_addr)))return TXRX_DROP ; - }break ;case 0 :/* DA SA BSSID */
PATCH 2/23 mac80211: Improve sanity checks on injected packets
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andy Green <[email protected]>
patch 9b8a74e3482f9fc077a88c13fa0ceca8feb0b772 in mainline.
Michael Wu noticed that the skb length checking is not taken care of enough when a packet is presented on the Monitor interface for injection.
This patch improves the sanity checking and removes fake offsets placed into the skb network and transport header.
--- net/mac80211/ieee80211.c | 48 +++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-)
net/mac80211/ieee80211.c +28 -20
@@ -1680,46 +1680,54 @@ int ieee80211_monitor_start_xmit(structstruct ieee80211_tx_packet_data *pkt_data;struct ieee80211_radiotap_header *prthdr = (struct ieee80211_radiotap_header *)skb->data; -u16 len; +u16 len_rthdr; -/* -* there must be a radiotap header at the -* start in this case -*/ -if (unlikely (prthdr->it_version)) { -/* only version 0 is supported */ -dev_kfree_skb (skb); -return NETDEV_TX_OK ; - } +/* check for not even having the fixed radiotap header part */ +if (unlikely (skb->len <sizeof (struct ieee80211_radiotap_header ))) + goto fail;/* too short to be possibly valid */ + +/* is it a header version we can trust to find length from? */ +if (unlikely (prthdr->it_version)) + goto fail;/* only version 0 is supported */ + +/* then there must be a radiotap header with a length we can use */ + len_rthdr =ieee80211_get_radiotap_len (skb); + +/* does the skb contain enough to deliver on the alleged length? */ +if (unlikely (skb->len < len_rthdr)) + goto fail;/* skb too short for claimed rt header extent */ skb->dev = local->mdev; pkt_data = (struct ieee80211_tx_packet_data *)skb->cb;memset (pkt_data,0 ,sizeof (*pkt_data)); +/* needed because we set skb device to master */ pkt_data->ifindex = dev->ifindex; + pkt_data->mgmt_iface =0 ; pkt_data->do_not_encrypt =1 ; -/* above needed because we set skb device to master */ -/* * fix up the pointers accounting for the radiotap * header still being in there. We are being given * a precooked IEEE80211 header so no need for * normal processing */ - len =le16_to_cpu (get_unaligned (&prthdr->it_len)); -skb_set_mac_header (skb, len); -skb_set_network_header (skb, len +sizeof (struct ieee80211_hdr )); -skb_set_transport_header (skb, len +sizeof (struct ieee80211_hdr )); - +skb_set_mac_header (skb, len_rthdr);/* -* pass the radiotap header up to -* the next stage intact +* these are just fixed to the end of the rt area since we +* don't have any better information and at this point, nobody cares */ -dev_queue_xmit (skb); +skb_set_network_header (skb, len_rthdr); +skb_set_transport_header (skb, len_rthdr); +/* pass the radiotap header up to the next stage intact */ +dev_queue_xmit (skb);return NETDEV_TX_OK ; + +fail: +dev_kfree_skb (skb); +return NETDEV_TX_OK ;/* meaning, we dealt with the skb */ }
PATCH 3/23 Add get_unaligned to ieee80211_get_radiotap_len
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Andy Green <[email protected]>
patch dfe6e81deaa79c85086c0cc8d85b229e444ab97f in mainline.
ieee80211_get_radiotap_len() tries to dereference radiotap length without taking care that it is completely unaligned and get_unaligned() is required.
--- net/mac80211/ieee80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/mac80211/ieee80211.c +1 -1
@@ -350,7 +350,7 @@ static int ieee80211_get_radiotap_len(ststruct ieee80211_radiotap_header *hdr = (struct ieee80211_radiotap_header *) skb->data; -return le16_to_cpu (hdr->it_len); +return le16_to_cpu (get_unaligned (&hdr->it_len)); }#ifdef CONFIG_MAC80211_LOWTX_FRAME_DUMP
PATCH 4/23 Fix advertised packet scheduler timer resolution
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
patch 3c0cfc135829b98f7a4894938652f9ef78e24237 in mainline
The fourth parameter of /proc/net/psched is supposed to show the timer resultion and is used by HTB userspace to calculate the necessary burst rate. Currently we show the clock resolution, which results in a too low burst rate when the two differ.
--- net/sched/sch_api.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/sched/sch_api.c +4 -1
@@ -1225,10 +1225,13 @@ EXPORT_SYMBOL(tcf_destroy_chain);#ifdef CONFIG_PROC_FS static int psched_show (struct seq_file *seq,void *v) { +struct timespec ts; + +hrtimer_get_res (CLOCK_MONOTONIC , &ts);seq_printf (seq,"%08x %08x %08x %08x\n" , (u32 )NSEC_PER_USEC , (u32 )PSCHED_US2NS (1 ),1000000 , - (u32 )NSEC_PER_SEC /(u32 )ktime_to_ns (KTIME_MONOTONIC_RES )); + (u32 )NSEC_PER_SEC /(u32 )ktime_to_ns (timespec_to_ktime (ts)));return 0 ; }
PATCH 5/23 Fix 9P protocol build
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Ingo Molnar <[email protected]>
patch 092e9d93b3728d484a4e73df9852dc4002cf9923 in mainline.
[9P]: build fix with !CONFIG_SYSCTL
found via make randconfig build testing:
net/built-in.o: In function `init_p9':
mod.c:(.init.text+0x3b39): undefined reference to p9_sysctl_register' net/built-in.o: In function exit_p9':
mod.c:(.exit.text+0x36b): undefined reference to `p9_sysctl_unregister'
--- include/net/9p/9p.h | 12 ++++++++++++ 1 file changed, 12 insertions(+)
include/net/9p/9p.h +12 -0
@@ -412,6 +412,18 @@ int p9_idpool_check(int id, struct p9_idint p9_error_init (void );int p9_errstr2errno (char *,int ); + +#ifdef CONFIG_SYSCTL int __init p9_sysctl_register (void ); void __exit p9_sysctl_unregister(void); +#else +static inline int p9_sysctl_register (void ) +{ +return 0 ; +} +static inline void p9_sysctl_unregister (void ) +{ +} +#endif +#endif /* NET_9P_H */
PATCH 6/23 Fix SKB_WITH_OVERHEAD calculations.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
patch deea84b0ae3d26b41502ae0a39fe7fe134e703d0 in mainline.
[NET]: Fix SKB_WITH_OVERHEAD calculation
The calculation in SKB_WITH_OVERHEAD is incorrect in that it can cause an overflow across a page boundary which is what it's meant to prevent. In particular, the header length (X) should not be lumped together with skb_shared_info. The latter needs to be aligned properly while the header has no choice but to sit in front of wherever the payload is.
Therefore the correct calculation is to take away the aligned size of skb_shared_info, and then subtract the header length. The resulting quantity L satisfies the following inequality:
SKB_DATA_ALIGN(L + X) + sizeof(struct skb_shared_info) <= PAGE_SIZE
This is the quantity used by alloc_skb to do the actual allocation.
--- include/linux/skbuff.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
include/linux/skbuff.h +1 -2
@@ -41,8 +41,7 @@#define SKB_DATA_ALIGN (X ) (((X) + (SMP_CACHE_BYTES - 1)) & \ ~(SMP_CACHE_BYTES - 1))#define SKB_WITH_OVERHEAD (X ) \ - (((X) - sizeof(struct skb_shared_info)) & \ - ~(SMP_CACHE_BYTES - 1)) + ((X) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))#define SKB_MAX_ORDER (X ,ORDER ) \ SKB_WITH_OVERHEAD((PAGE_SIZE << (ORDER)) - (X))#define SKB_MAX_HEAD (X ) (SKB_MAX_ORDER((X), 0))
Herbert Xu
maintainerRe: [patch 06/23] Fix SKB_WITH_OVERHEAD calculations.
Quoted 9 lines · Greg KH
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
patch
deea84b0ae3d26b41502ae0a39fe7fe134e703d0in mainline.[NET]: Fix
SKB_WITH_OVERHEADcalculation
Although this is correct as it is, it tirggers a latent bug which is fixed by
commit fb93134dfc2a6e6fbedc7c270a31da03fce88db9
Author: Herbert Xu <[email protected]> Date: Wed Nov 14 15:45:21 2007 -0800
[TCP]: Fix size calculation in sk_stream_alloc_pskb
So please postpone it to the next round such that both patches can be included together.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtDavid Miller
maintainerRe: [patch 06/23] Fix SKB_WITH_OVERHEAD calculations.
From: Herbert Xu <[email protected]>
Date: Thu, 15 Nov 2007 14:29:39 +0800
Quoted 14 lines · Greg KH
Quoted 9 lines
-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
patch
deea84b0ae3d26b41502ae0a39fe7fe134e703d0in mainline.[NET]: Fix
SKB_WITH_OVERHEADcalculationAlthough this is correct as it is, it tirggers a latent bug which is fixed by
Quoted 8 lines
commit
fb93134dfc2a6e6fbedc7c270a31da03fce88db9Author: Herbert Xu <[email protected]> Date: Wed Nov 14 15:45:21 2007 -0800[TCP]: Fix size calculation in
sk_stream_alloc_pskbSo please postpone it to the next round such that both patches can be included together.
I was just about to mention this and what I think we should do instead is keep the SKB_WITH_OVERHEAD calculation fix in there (it fixes a serious bug which users are hitting) and add the fix for the second bug fix this round as well.
Therefore, Greg please keep the patch add the following one as it will address all of the issues.
[TCP]: Fix size calculation in sk_stream_alloc_pskb
[ Upstream commit: fb93134dfc2a6e6fbedc7c270a31da03fce88db9 ]
We round up the header size in sk_stream_alloc_pskb so that TSO packets get zero tail room. Unfortunately this rounding up is not coordinated with the select_size() function used by TCP to calculate the second parameter of sk_stream_alloc_pskb.
As a result, we may allocate more than a page of data in the non-TSO case when exactly one page is desired.
In fact, rounding up the head room is detrimental in the non-TSO case because it makes memory that would otherwise be available to the payload head room. TSO doesn't need this either, all it wants is the guarantee that there is no tail room.
So this patch fixes this by adjusting the skb_reserve call so that exactly the requested amount (which all callers have calculated in a precise way) is made available as tail room.
include/net/sock.h +6 -4
@@ -1235,14 +1235,16 @@ static inline struct sk_buff *sk_stream_alloc_pskb(struct sock *sk, gfp_t gfp) {struct sk_buff *skb; -int hdr_len; - hdr_len =SKB_DATA_ALIGN (sk->sk_prot->max_header); - skb =alloc_skb_fclone (size + hdr_len, gfp); + skb =alloc_skb_fclone (size + sk->sk_prot->max_header, gfp);if (skb) { skb->truesize += mem;if (sk_stream_wmem_schedule (sk, skb->truesize)) { -skb_reserve (skb, hdr_len); +/* +* Make sure that we have exactly size bytes +* available to the caller, no more, no less. +*/ +skb_reserve (skb,skb_tailroom (skb) - size);return skb; }__kfree_skb (skb);
Herbert Xu
maintainerRe: [patch 06/23] Fix SKB_WITH_OVERHEAD calculations.
Quoted 8 lines · David Miller
I was just about to mention this and what I think we should do instead is keep the
SKB_WITH_OVERHEADcalculation fix in there (it fixes a serious bug which users are hitting) and add the fix for the second bug fix this round as well.Therefore, Greg please keep the patch add the following one as it will address all of the issues.
I agree. If the stable team could make an exception for this it would be great.
Thanks,
Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txtRe: [stable] [patch 06/23] Fix SKB_WITH_OVERHEAD calculations.
Quoted 7 lines · Herbert Xu
Quoted 6 lines · David Miller
I was just about to mention this and what I think we should do instead is keep the
SKB_WITH_OVERHEADcalculation fix in there (it fixes a serious bug which users are hitting) and add the fix for the second bug fix this round as well.
Quoted 5 lines
Quoted 2 lines
Therefore, Greg please keep the patch add the following one as it will address all of the issues.
I agree. If the stable team could make an exception for this it would be great.
No problem, I've added this patch to the series right after the above mentioned one and it will come out in the next release.
thanks for the review,
greg k-h
David Miller
maintainerRe: [stable] [patch 06/23] Fix SKB_WITH_OVERHEAD calculations.
From: Greg KH <[email protected]>
Date: Thu, 15 Nov 2007 16:31:02 -0800
Quoted 8 lines · Herbert Xu
Quoted 7 lines · David Miller
Quoted 6 lines
I was just about to mention this and what I think we should do instead is keep the
SKB_WITH_OVERHEADcalculation fix in there (it fixes a serious bug which users are hitting) and add the fix for the second bug fix this round as well.
Quoted 8 lines
Quoted 5 lines
Quoted 2 lines
Therefore, Greg please keep the patch add the following one as it will address all of the issues.
I agree. If the stable team could make an exception for this it would be great.
No problem, I've added this patch to the series right after the above mentioned one and it will come out in the next release.
Thanks a lot Greg.
PATCH 7/23 Fix kernel_accept() return handling.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Tony Battersby <[email protected]>
patch fa8705b00aeca19d91a1437b8a5cf865999b28f6 in mainline.
[NET]: sanitize kernel_accept() error path
If kernel_accept() returns an error, it may pass back a pointer to freed memory (which the caller should ignore). Make it pass back NULL instead for better safety.
--- net/socket.c | 1 + 1 file changed, 1 insertion(+)
net/socket.c +1 -0
@@ -2230,6 +2230,7 @@ int kernel_accept(struct socket *sock, s err = sock->ops->accept (sock, *newsock, flags);if (err <0 ) {sock_release (*newsock); + *newsock =NULL ; goto done; }
PATCH 8/23 softmac: fix wext MLME request reason code endianness
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Johannes Berg <[email protected]>
patch 94e10bfb8a7372df3ef2759c9ec2a37de2f24aca in mainline.
The MLME request reason code is host-endian and our passing it to the low level functions is host-endian as well since they do the swapping. I noticed that the reason code 768 was sent (0x300) rather than 3 when wpa_supplicant terminates. This removes the superfluous cpu_to_le16() call.
--- net/ieee80211/softmac/ieee80211softmac_wx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ieee80211/softmac/ieee80211softmac_wx.c +1 -1
@@ -469,7 +469,7 @@ ieee80211softmac_wx_set_mlme(struct net_ {struct ieee80211softmac_device *mac =ieee80211_priv (dev);struct iw_mlme *mlme = (struct iw_mlme *)extra; -u16 reason =cpu_to_le16 (mlme->reason_code); +u16 reason = mlme->reason_code;struct ieee80211softmac_network *net;int err = -EINVAL ;
PATCH 9/23 Fix error returns in sys_socketpair()
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: David Miller <[email protected]>
patch bf3c23d171e35e6e168074a1514b0acd59cfd81a in mainline.
[NET]: Fix error reporting in sys_socketpair().
If either of the two sock_alloc_fd() calls fail, we forget to update 'err' and thus we'll erroneously return zero in these cases.
Based upon a report and patch from Rich Paul, and commentary from Chuck Ebbert.
--- net/socket.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
net/socket.c +4 -1
@@ -1245,11 +1245,14 @@ asmlinkage long sys_socketpair(int famil goto out_release_both; fd1 =sock_alloc_fd (&newfile1); -if (unlikely (fd1 <0 )) +if (unlikely (fd1 <0 )) { + err = fd1; goto out_release_both; + } fd2 =sock_alloc_fd (&newfile2);if (unlikely (fd2 <0 )) { + err = fd2;put_filp (newfile1);put_unused_fd (fd1); goto out_release_both;
PATCH 10/23 Fix TEQL oops.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Evgeniy Polyakov <[email protected]>
[PKT_SCHED]: Fix OOPS when removing devices from a teql queuing discipline
[ Upstream commit: 4f9f8311a08c0d95c70261264a2b47f2ae99683a ]
tecl_reset() is called from deactivate and qdisc is set to noop already, but subsequent teql_xmit does not know about it and dereference private data as teql qdisc and thus oopses.
not catch it first :)
--- net/sched/sch_teql.c | 3 +++ 1 file changed, 3 insertions(+)
net/sched/sch_teql.c +3 -0
@@ -249,6 +249,9 @@ __teql_resolve(struct sk_buff *skb, strustatic __inline__int teql_resolve (struct sk_buff *skb,struct sk_buff *skb_res,struct net_device *dev) { +if (dev->qdisc == &noop_qdisc) +return -ENODEV ; +if (dev->hard_header ==NULL || skb->dst ==NULL || skb->dst->neighbour ==NULL )
PATCH 11/23 Fix endianness bug in U32 classifier.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Radu Rendec <[email protected]>
changeset 543821c6f5dea5221426eaf1eac98b100249c7ac in mainline.
[PKT_SCHED] CLS_U32: Fix endianness problem with u32 classifier hash masks.
While trying to implement u32 hashes in my shaping machine I ran into a possible bug in the u32 hash/bucket computing algorithm (net/sched/cls_u32.c).
The problem occurs only with hash masks that extend over the octet boundary, on little endian machines (where htonl() actually does something).
Let's say that I would like to use 0x3fc0 as the hash mask. This means 8 contiguous "1" bits starting at b6. With such a mask, the expected (and logical) behavior is to hash any address in, for instance, 192.168.0.0/26 in bucket 0, then any address in 192.168.0.64/26 in bucket 1, then 192.168.0.128/26 in bucket 2 and so on.
This is exactly what would happen on a big endian machine, but on little endian machines, what would actually happen with current implementation is 0x3fc0 being reversed (into 0xc03f0000) by htonl() in the userspace tool and then applied to 192.168.x.x in the u32 classifier. When shifting right by 16 bits (rank of first "1" bit in the reversed mask) and applying the divisor mask (0xff for divisor 256), what would actually remain is 0x3f applied on the "168" octet of the address.
One could say is this can be easily worked around by taking endianness into account in userspace and supplying an appropriate mask (0xfc03) that would be turned into contiguous "1" bits when reversed (0x03fc0000). But the actual problem is the network address (inside the packet) not being converted to host order, but used as a host-order value when computing the bucket.
Let's say the network address is written as n31 n30 ... n0, with n0 being the least significant bit. When used directly (without any conversion) on a little endian machine, it becomes n7 ... n0 n8 ..n15 etc in the machine's registers. Thus bits n7 and n8 would no longer be adjacent and 192.168.64.0/26 and 192.168.128.0/26 would no longer be consecutive.
The fix is to apply ntohl() on the hmask before computing fshift, and in u32_hash_fold() convert the packet data to host order before shifting down by fshift.
With helpful feedback from Jamal Hadi Salim and Jarek Poplawski.
--- net/sched/cls_u32.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/sched/cls_u32.c +2 -2
@@ -91,7 +91,7 @@ static struct tc_u_common *u32_list;static __inline__unsigned u32_hash_fold (u32 key,struct tc_u32_sel *sel,u8 fshift) { -unsigned h = (key & sel->hmask)>>fshift; +unsigned h =ntohl (key & sel->hmask)>>fshift;return h; }
@@ -615,7 +615,7 @@ static int u32_change(struct tcf_proto * n->handle = handle; {u8 i =0 ; -u32 mask = s->hmask; +u32 mask =ntohl (s->hmask);if (mask) {while (!(mask &1 )) { i++;
PATCH 12/23 Fix VLAN address syncing.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
patch d932e04a5e7b146c5f9bf517714b986a432a7594 in mainline.
[PATCH] [VLAN]: Don't synchronize addresses while the vlan device is down
While the VLAN device is down, the unicast addresses are not configured on the underlying device, so we shouldn't attempt to sync them.
Noticed by Dmitry Butskoy <[email protected]>
--- net/8021q/vlan.c | 4 ++++ 1 file changed, 4 insertions(+)
net/8021q/vlan.c +4 -0
@@ -629,6 +629,10 @@ static int vlan_device_event(struct notiif (!vlandev)continue ; + flgs = vlandev->flags; +if (!(flgs &IFF_UP )) +continue ; +vlan_sync_address (dev, vlandev); }break ;
PATCH 13/23 Fix SET_VLAN_INGRESS_PRIORITY_CMD error return.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
patch fffe470a803e7f7b74c016291e542a0162761209 in mainline.
[VLAN]: Fix SET_VLAN_INGRESS_PRIORITY_CMD ioctl
Based on report and patch by Doug Kehn <[email protected]>:
vconfig returns the following error when attempting to execute the set_ingress_map command:
vconfig: socket or ioctl error for set_ingress_map: Operation not permitted
In vlan.c, vlan_ioctl_handler for SET_VLAN_INGRESS_PRIORITY_CMD sets err = -EPERM and calls vlan_dev_set_ingress_priority. vlan_dev_set_ingress_priority is a void function so err remains at -EPERM and results in the vconfig error (even though the ingress map was set).
Fix by setting err = 0 after the vlan_dev_set_ingress_priority call.
--- net/8021q/vlan.c | 1 + 1 file changed, 1 insertion(+)
net/8021q/vlan.c +1 -0
@@ -744,6 +744,7 @@ static int vlan_ioctl_handler(void __usevlan_dev_set_ingress_priority (dev, args.u.skb_priority, args.vlan_qos); + err =0 ;break ;case SET_VLAN_EGRESS_PRIORITY_CMD :
PATCH 14/23 Fix crypto_alloc_comp() error checking.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Herbert Xu <[email protected]>
[IPSEC]: Fix crypto_alloc_comp error checking
[ Upstream commit: 4999f3621f4da622e77931b3d33ada6c7083c705 ]
The function crypto_alloc_comp returns an errno instead of NULL to indicate error. So it needs to be tested with IS_ERR.
This is based on a patch by Vicen� Beltran Querol.
--- net/ipv4/ipcomp.c | 3 ++- net/ipv6/ipcomp6.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-)
net/ipv4/ipcomp.c +2 -1
@@ -17,6 +17,7 @@#include <asm/scatterlist.h> #include <asm/semaphore.h> #include <linux/crypto.h> +#include <linux/err.h> #include <linux/pfkeyv2.h> #include <linux/percpu.h> #include <linux/smp.h>
@@ -355,7 +356,7 @@ static struct crypto_comp **ipcomp_allocfor_each_possible_cpu (cpu) {struct crypto_comp *tfm =crypto_alloc_comp (alg_name,0 ,CRYPTO_ALG_ASYNC ); -if (!tfm) +if (IS_ERR (tfm)) goto error; *per_cpu_ptr (tfms, cpu) = tfm; }
net/ipv6/ipcomp6.c +2 -1
@@ -37,6 +37,7 @@#include <asm/scatterlist.h> #include <asm/semaphore.h> #include <linux/crypto.h> +#include <linux/err.h> #include <linux/pfkeyv2.h> #include <linux/random.h> #include <linux/percpu.h>
@@ -366,7 +367,7 @@ static struct crypto_comp **ipcomp6_allofor_each_possible_cpu (cpu) {struct crypto_comp *tfm =crypto_alloc_comp (alg_name,0 ,CRYPTO_ALG_ASYNC ); -if (!tfm) +if (IS_ERR (tfm)) goto error; *per_cpu_ptr (tfms, cpu) = tfm; }
PATCH 15/23 Fix netlink timeouts.
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Patrick McHardy <[email protected]>
[NETLINK]: Fix unicast timeouts
[ Upstream commit: c3d8d1e30cace31fed6186a4b8c6b1401836d89c ]
Commit ed6dcf4a in the history.git tree broke netlink_unicast timeouts by moving the schedule_timeout() call to a new function that doesn't propagate the remaining timeout back to the caller. This means on each retry we start with the full timeout again.
ipc/mqueue.c seems to actually want to wait indefinitely so this behaviour is retained.
--- include/linux/netlink.h | 2 +- ipc/mqueue.c | 6 ++++-- net/netlink/af_netlink.c | 10 +++++----- 3 files changed, 10 insertions(+), 8 deletions(-)
include/linux/netlink.h +1 -1
@@ -175,7 +175,7 @@ extern int netlink_unregister_notifier(s/* finegrained unicast helpers: */ struct sock *netlink_getsockbyfilp (struct file *filp);int netlink_attachskb (struct sock *sk,struct sk_buff *skb,int nonblock, -long timeo,struct sock *ssk); +long *timeo,struct sock *ssk);void netlink_detachskb (struct sock *sk,struct sk_buff *skb);int netlink_sendskb (struct sock *sk,struct sk_buff *skb,int protocol);
ipc/mqueue.c +4 -2
@@ -1014,6 +1014,8 @@ asmlinkage long sys_mq_notify(mqd_t mqdereturn -EINVAL ; }if (notification.sigev_notify ==SIGEV_THREAD ) { +long timeo; +/* create the notify skb */ nc =alloc_skb (NOTIFY_COOKIE_LEN ,GFP_KERNEL ); ret = -ENOMEM ;
@@ -1042,8 +1044,8 @@ retry: goto out; } - ret =netlink_attachskb (sock, nc,0 , -MAX_SCHEDULE_TIMEOUT ,NULL ); + timeo =MAX_SCHEDULE_TIMEOUT ; + ret =netlink_attachskb (sock, nc,0 , &timeo,NULL );if (ret ==1 ) goto retry;if (ret) {
net/netlink/af_netlink.c +5 -5
@@ -744,7 +744,7 @@ struct sock *netlink_getsockbyfilp(struc* 1: repeat lookup - reference dropped while waiting for socket memory. */ int netlink_attachskb (struct sock *sk,struct sk_buff *skb,int nonblock, -long timeo,struct sock *ssk) +long *timeo,struct sock *ssk) {struct netlink_sock *nlk;
@@ -753,7 +753,7 @@ int netlink_attachskb(struct sock *sk, sif (atomic_read (&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||test_bit (0 , &nlk->state)) {DECLARE_WAITQUEUE (wait, current); -if (!timeo) { +if (!*timeo) {if (!ssk ||nlk_sk (ssk)->pid ==0 )netlink_overrun (sk);sock_put (sk);
@@ -767,7 +767,7 @@ int netlink_attachskb(struct sock *sk, sif ((atomic_read (&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||test_bit (0 , &nlk->state)) && !sock_flag (sk,SOCK_DEAD )) - timeo =schedule_timeout (timeo); + *timeo =schedule_timeout (*timeo);__set_current_state (TASK_RUNNING );remove_wait_queue (&nlk->wait, &wait);
@@ -775,7 +775,7 @@ int netlink_attachskb(struct sock *sk, sif (signal_pending (current)) {kfree_skb (skb); -return sock_intr_errno (timeo); +return sock_intr_errno (*timeo); }return 1 ; }
@@ -839,7 +839,7 @@ retry:kfree_skb (skb);return PTR_ERR (sk); } - err =netlink_attachskb (sk, skb, nonblock, timeo, ssk); + err =netlink_attachskb (sk, skb, nonblock, &timeo, ssk);if (err ==1 ) goto retry;if (err)
PATCH 16/23 NETFILTER: nf_conntrack_tcp: fix connection reopening
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Jozsef Kadlecsik <[email protected]>
Upstream commits: 17311393 + bc34b841 merged together. Merge done by Patrick McHardy <[email protected]>
[NETFILTER]: nf_conntrack_tcp: fix connection reopening
With your description I could reproduce the bug and actually you were completely right: the code above is incorrect. Somehow I was able to misread RFC1122 and mixed the roles :-(:
When a connection is >>closed actively<<, it MUST linger in TIME-WAIT state for a time 2xMSL (Maximum Segment Lifetime). However, it MAY >>accept<< a new SYN from the remote TCP to reopen the connection directly from TIME-WAIT state, if it:
[...]
The fix is as follows: if the receiver initiated an active close, then the sender may reopen the connection - otherwise try to figure out if we hold a dead connection.
--- net/netfilter/nf_conntrack_proto_tcp.c | 38 ++++++++++++++------------------- 1 file changed, 17 insertions(+), 21 deletions(-)
net/netfilter/nf_conntrack_proto_tcp.c +17 -21
@@ -831,6 +831,22 @@ static int tcp_packet(struct nf_conn *co tuple = &conntrack->tuplehash[dir].tuple;switch (new_state) { +case TCP_CONNTRACK_SYN_SENT : +if (old_state <TCP_CONNTRACK_TIME_WAIT ) +break ; +if ((conntrack->proto.tcp.seen[!dir].flags & +IP_CT_TCP_FLAG_CLOSE_INIT ) + || (conntrack->proto.tcp.last_dir == dir + && conntrack->proto.tcp.last_index ==TCP_RST_SET )) { +/* Attempt to reopen a closed/aborted connection. +* Delete this connection and look up again. */ +write_unlock_bh (&tcp_lock); +if (del_timer (&conntrack->timeout)) + conntrack->timeout.function ((unsigned long ) + conntrack); +return -NF_REPEAT ; + } +/* Fall through */ case TCP_CONNTRACK_IGNORE :/* Ignored packets: *
@@ -879,27 +895,6 @@ static int tcp_packet(struct nf_conn *conf_log_packet (pf,0 , skb,NULL ,NULL ,NULL ,"nf_ct_tcp: invalid state " );return -NF_ACCEPT ; -case TCP_CONNTRACK_SYN_SENT : -if (old_state <TCP_CONNTRACK_TIME_WAIT ) -break ; -if ((conntrack->proto.tcp.seen[dir].flags & -IP_CT_TCP_FLAG_CLOSE_INIT ) - ||after (ntohl (th->seq), - conntrack->proto.tcp.seen[dir].td_end)) { -/* Attempt to reopen a closed connection. -* Delete this connection and look up again. */ -write_unlock_bh (&tcp_lock); -if (del_timer (&conntrack->timeout)) - conntrack->timeout.function ((unsigned long ) - conntrack); -return -NF_REPEAT ; - }else { -write_unlock_bh (&tcp_lock); -if (LOG_INVALID (IPPROTO_TCP )) -nf_log_packet (pf,0 , skb,NULL ,NULL , -NULL ,"nf_ct_tcp: invalid SYN" ); -return -NF_ACCEPT ; - }case TCP_CONNTRACK_CLOSE : if (index == TCP_RST_SET && ((test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)
@@ -932,6 +927,7 @@ static int tcp_packet(struct nf_conn *co in_window:/* From now on we have got in-window packets */ conntrack->proto.tcp.last_index = index; + conntrack->proto.tcp.last_dir = dir;pr_debug ("tcp_conntracks: " );NF_CT_DUMP_TUPLE (tuple);
PATCH 17/23 ieee80211: fix TKIP QoS bug
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Johannes Berg <[email protected]>
patch e797aa1b7da6bfcb2e19a10ae5ead9aa7aea732b in mainline.
The commit 65b6a277 titled "ieee80211: Fix header->qos_ctl endian issue" *introduced* an endianness bug. Partially revert it.
--- net/ieee80211/ieee80211_crypt_tkip.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ieee80211/ieee80211_crypt_tkip.c +1 -1
@@ -584,7 +584,7 @@ static void michael_mic_hdr(struct sk_buif (stype &IEEE80211_STYPE_QOS_DATA ) {const struct ieee80211_hdr_3addrqos *qoshdr = (struct ieee80211_hdr_3addrqos *)skb->data; - hdr[12 ] = qoshdr->qos_ctl &cpu_to_le16 (IEEE80211_QCTL_TID ); + hdr[12 ] =le16_to_cpu (qoshdr->qos_ctl) &IEEE80211_QCTL_TID ; }else hdr[12 ] =0 ;/* priority */
PATCH 18/23 mac80211: reorder association debug output
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Johannes Berg <[email protected]>
patch 1dd84aa213d0f98a91a1ec9be2f750f5f48e75a0 in mainline.
There's no reason to warn about an invalid AID field when the association was denied.
--- net/mac80211/ieee80211_sta.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/mac80211/ieee80211_sta.c +6 -5
@@ -1174,15 +1174,11 @@ static void ieee80211_rx_mgmt_assoc_resp capab_info =le16_to_cpu (mgmt->u.assoc_resp.capab_info); status_code =le16_to_cpu (mgmt->u.assoc_resp.status_code); aid =le16_to_cpu (mgmt->u.assoc_resp.aid); -if ((aid & (BIT (15 ) |BIT (14 ))) != (BIT (15 ) |BIT (14 ))) -printk (KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " -"set\n" , dev->name, aid); - aid &= ~(BIT (15 ) |BIT (14 ));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); + capab_info, status_code, aid & ~(BIT (15 ) |BIT (14 )));if (status_code !=WLAN_STATUS_SUCCESS ) { printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -1192,6 +1188,11 @@ static void ieee80211_rx_mgmt_assoc_respreturn ; } +if ((aid & (BIT (15 ) |BIT (14 ))) != (BIT (15 ) |BIT (14 ))) +printk (KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not " +"set\n" , dev->name, aid); + aid &= ~(BIT (15 ) |BIT (14 )); + pos = mgmt->u.assoc_resp.variable;if (ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems) == ParseFailed) {
PATCH 19/23 mac80211: store channel info in sta_bss_list
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
patch 65c107ab3befc37b21d1c970a6159525bc0121b8 in mainline.
Some AP equipment "in the wild" uses the same BSSID on multiple channels (particularly "a" vs. "b/g"). This patch changes the key of sta_bss_list to include both the BSSID and the channel so as to prevent a BSSID on one channel from eclipsing the same BSSID on another channel.
--- net/mac80211/ieee80211_sta.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-)
net/mac80211/ieee80211_sta.c +20 -15
@@ -61,7 +61,7 @@static void ieee80211_send_probe_req (struct net_device *dev,u8 *dst,u8 *ssid,size_t ssid_len);static struct ieee80211_sta_bss * -ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid); +ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel);static void ieee80211_rx_bss_put (struct net_device *dev,struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -387,6 +387,7 @@ static void ieee80211_set_associated(str struct ieee80211_if_sta *ifsta, int assoc) {union iwreq_data wrqu; +struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);if (ifsta->associated == assoc)
@@ -401,7 +402,8 @@ static void ieee80211_set_associated(strif (sdata->type !=IEEE80211_IF_TYPE_STA )return ; - bss =ieee80211_rx_bss_get (dev, ifsta->bssid); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, + local->hw.conf.channel);if (bss) {if (bss->has_erp_value)ieee80211_handle_erp_ie (dev, bss->erp_value);
@@ -543,7 +545,7 @@ static void ieee80211_send_assoc(struct capab |=WLAN_CAPABILITY_SHORT_SLOT_TIME |WLAN_CAPABILITY_SHORT_PREAMBLE ; } - bss =ieee80211_rx_bss_get (dev, ifsta->bssid); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel);if (bss) {if (bss->capability &WLAN_CAPABILITY_PRIVACY ) capab |=WLAN_CAPABILITY_PRIVACY ;
@@ -695,6 +697,7 @@ static void ieee80211_send_disassoc(strustatic int ieee80211_privacy_mismatch (struct net_device *dev,struct ieee80211_if_sta *ifsta) { +struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss;int res =0 ;
@@ -702,7 +705,7 @@ static int ieee80211_privacy_mismatch(st ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE)return 0 ; - bss =ieee80211_rx_bss_get (dev, ifsta->bssid); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel);if (!bss)return 0 ;
@@ -1211,7 +1214,8 @@ static void ieee80211_rx_mgmt_assoc_resp* update our stored copy */ if (elems.erp_info && elems.erp_info_len >=1 ) {struct ieee80211_sta_bss *bss - =ieee80211_rx_bss_get (dev, ifsta->bssid); + =ieee80211_rx_bss_get (dev, ifsta->bssid, + local->hw.conf.channel);if (bss) { bss->erp_value = elems.erp_info[0 ]; bss->has_erp_value =1 ;
@@ -1241,7 +1245,8 @@ static void ieee80211_rx_mgmt_assoc_resp " AP\n", dev->name);return ; } - bss =ieee80211_rx_bss_get (dev, ifsta->bssid); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, + local->hw.conf.channel);if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal;
@@ -1322,7 +1327,7 @@ static void __ieee80211_rx_bss_hash_del(static struct ieee80211_sta_bss * -ieee80211_rx_bss_add (struct net_device *dev,u8 *bssid) +ieee80211_rx_bss_add (struct net_device *dev,u8 *bssid,int channel) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss;
@@ -1333,6 +1338,7 @@ ieee80211_rx_bss_add(struct net_device *atomic_inc (&bss->users);atomic_inc (&bss->users);memcpy (bss->bssid, bssid,ETH_ALEN ); + bss->channel = channel;spin_lock_bh (&local->sta_bss_lock);/* TODO: order by RSSI? */
@@ -1344,7 +1350,7 @@ ieee80211_rx_bss_add(struct net_device *static struct ieee80211_sta_bss * -ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid) +ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss;
@@ -1352,7 +1358,8 @@ ieee80211_rx_bss_get(struct net_device *spin_lock_bh (&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH (bssid)];while (bss) { -if (memcmp (bss->bssid, bssid,ETH_ALEN ) ==0 ) { +if (memcmp (bss->bssid, bssid,ETH_ALEN ) ==0 && + bss->channel == channel) {atomic_inc (&bss->users);break ; }
@@ -1520,9 +1527,9 @@ static void ieee80211_rx_bss_info(structelse channel = rx_status->channel; - bss =ieee80211_rx_bss_get (dev, mgmt->bssid); + bss =ieee80211_rx_bss_get (dev, mgmt->bssid, channel);if (!bss) { - bss =ieee80211_rx_bss_add (dev, mgmt->bssid); + bss =ieee80211_rx_bss_add (dev, mgmt->bssid, channel);if (!bss)return ; }else {
@@ -1622,7 +1629,6 @@ static void ieee80211_rx_bss_info(struct bss->hw_mode = rx_status->phymode; - bss->channel = channel; bss->freq = rx_status->freq; if (channel != rx_status->channel && (bss->hw_mode == MODE_IEEE80211G ||
@@ -2355,7 +2361,7 @@ static int ieee80211_sta_create_ibss(strprintk (KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n" , dev->name,MAC_ARG (bssid)); - bss =ieee80211_rx_bss_add (dev, bssid); + bss =ieee80211_rx_bss_add (dev, bssid, local->hw.conf.channel);if (!bss)return -ENOMEM ;
@@ -2366,7 +2372,6 @@ static int ieee80211_sta_create_ibss(str local->hw.conf.beacon_int =100 ; bss->beacon_int = local->hw.conf.beacon_int; bss->hw_mode = local->hw.conf.phymode; - bss->channel = local->hw.conf.channel; bss->freq = local->hw.conf.freq; bss->last_update = jiffies; bss->capability =WLAN_CAPABILITY_IBSS ;
@@ -2426,7 +2431,7 @@ static int ieee80211_sta_find_ibss(struc MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));#endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found &&memcmp (ifsta->bssid, bssid,ETH_ALEN ) !=0 && - (bss =ieee80211_rx_bss_get (dev, bssid))) { + (bss =ieee80211_rx_bss_get (dev, bssid, local->hw.conf.channel))) {printk (KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT " based on configured SSID\n" , dev->name,MAC_ARG (bssid));
PATCH 20/23 mac80211: store SSID in sta_bss_list
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
patch cffdd30d20d163343b1c6de25bcb0cc978a1ebf9 in mainline.
Some AP equipment "in the wild" services multiple SSIDs using the same BSSID. This patch changes the key of sta_bss_list to include the SSID as well as the BSSID and the channel so as to prevent one SSID from eclipsing another SSID with the same BSSID.
--- net/mac80211/ieee80211_sta.c | 54 ++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 21 deletions(-)
net/mac80211/ieee80211_sta.c +33 -21
@@ -12,7 +12,6 @@*/ /* TODO: -* BSS table: use <BSSID,SSID> as the key to support multi-SSID APs * order BSS list by RSSI(?) ("quality of AP") * scan result table filtering (by capability (privacy, IBSS/BSS, WPA/RSN IE, * SSID)
@@ -61,7 +60,8 @@static void ieee80211_send_probe_req (struct net_device *dev,u8 *dst,u8 *ssid,size_t ssid_len);static struct ieee80211_sta_bss * -ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel); +ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel, +u8 *ssid,u8 ssid_len);static void ieee80211_rx_bss_put (struct net_device *dev,struct ieee80211_sta_bss *bss); static int ieee80211_sta_find_ibss(struct net_device *dev,
@@ -403,7 +403,8 @@ static void ieee80211_set_associated(strreturn ; bss =ieee80211_rx_bss_get (dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len);if (bss) {if (bss->has_erp_value)ieee80211_handle_erp_ie (dev, bss->erp_value);
@@ -545,7 +546,8 @@ static void ieee80211_send_assoc(struct capab |=WLAN_CAPABILITY_SHORT_SLOT_TIME |WLAN_CAPABILITY_SHORT_PREAMBLE ; } - bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len);if (bss) {if (bss->capability &WLAN_CAPABILITY_PRIVACY ) capab |=WLAN_CAPABILITY_PRIVACY ;
@@ -705,7 +707,8 @@ static int ieee80211_privacy_mismatch(st ifsta->key_mgmt != IEEE80211_KEY_MGMT_NONE)return 0 ; - bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel); + bss =ieee80211_rx_bss_get (dev, ifsta->bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len);if (!bss)return 0 ;
@@ -1215,7 +1218,8 @@ static void ieee80211_rx_mgmt_assoc_respif (elems.erp_info && elems.erp_info_len >=1 ) {struct ieee80211_sta_bss *bss =ieee80211_rx_bss_get (dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len);if (bss) { bss->erp_value = elems.erp_info[0 ]; bss->has_erp_value =1 ;
@@ -1246,7 +1250,8 @@ static void ieee80211_rx_mgmt_assoc_respreturn ; } bss =ieee80211_rx_bss_get (dev, ifsta->bssid, - local->hw.conf.channel); + local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len);if (bss) { sta->last_rssi = bss->rssi; sta->last_signal = bss->signal;
@@ -1327,7 +1332,8 @@ static void __ieee80211_rx_bss_hash_del(static struct ieee80211_sta_bss * -ieee80211_rx_bss_add (struct net_device *dev,u8 *bssid,int channel) +ieee80211_rx_bss_add (struct net_device *dev,u8 *bssid,int channel, +u8 *ssid,u8 ssid_len) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss;
@@ -1339,6 +1345,10 @@ ieee80211_rx_bss_add(struct net_device *atomic_inc (&bss->users);memcpy (bss->bssid, bssid,ETH_ALEN ); bss->channel = channel; +if (ssid && ssid_len <=IEEE80211_MAX_SSID_LEN ) { +memcpy (bss->ssid, ssid, ssid_len); + bss->ssid_len = ssid_len; + }spin_lock_bh (&local->sta_bss_lock);/* TODO: order by RSSI? */
@@ -1350,7 +1360,8 @@ ieee80211_rx_bss_add(struct net_device *static struct ieee80211_sta_bss * -ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel) +ieee80211_rx_bss_get (struct net_device *dev,u8 *bssid,int channel, +u8 *ssid,u8 ssid_len) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss;
@@ -1358,8 +1369,10 @@ ieee80211_rx_bss_get(struct net_device *spin_lock_bh (&local->sta_bss_lock); bss = local->sta_bss_hash[STA_HASH (bssid)];while (bss) { -if (memcmp (bss->bssid, bssid,ETH_ALEN ) ==0 && - bss->channel == channel) { +if (!memcmp (bss->bssid, bssid,ETH_ALEN ) && + bss->channel == channel && + bss->ssid_len == ssid_len && + (ssid_len ==0 || !memcmp (bss->ssid, ssid, ssid_len))) {atomic_inc (&bss->users);break ; }
@@ -1527,9 +1540,11 @@ static void ieee80211_rx_bss_info(structelse channel = rx_status->channel; - bss =ieee80211_rx_bss_get (dev, mgmt->bssid, channel); + bss =ieee80211_rx_bss_get (dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len);if (!bss) { - bss =ieee80211_rx_bss_add (dev, mgmt->bssid, channel); + bss =ieee80211_rx_bss_add (dev, mgmt->bssid, channel, + elems.ssid, elems.ssid_len);if (!bss)return ; }else {
@@ -1555,10 +1570,6 @@ static void ieee80211_rx_bss_info(struct bss->beacon_int =le16_to_cpu (mgmt->u.beacon.beacon_int); bss->capability =le16_to_cpu (mgmt->u.beacon.capab_info); -if (elems.ssid && elems.ssid_len <=IEEE80211_MAX_SSID_LEN ) { -memcpy (bss->ssid, elems.ssid, elems.ssid_len); - bss->ssid_len = elems.ssid_len; - } bss->supp_rates_len =0 ;if (elems.supp_rates) {
@@ -2339,7 +2350,7 @@ static int ieee80211_sta_create_ibss(str {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sta_bss *bss; -struct ieee80211_sub_if_data *sdata; +struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);struct ieee80211_hw_mode *mode;u8 bssid[ETH_ALEN ], *pos;int i;
@@ -2361,11 +2372,11 @@ static int ieee80211_sta_create_ibss(strprintk (KERN_DEBUG "%s: Creating new IBSS network, BSSID " MAC_FMT "\n" , dev->name,MAC_ARG (bssid)); - bss =ieee80211_rx_bss_add (dev, bssid, local->hw.conf.channel); + bss =ieee80211_rx_bss_add (dev, bssid, local->hw.conf.channel, + sdata->u.sta.ssid, sdata->u.sta.ssid_len);if (!bss)return -ENOMEM ; - sdata =IEEE80211_DEV_TO_SUB_IF (dev); mode = local->oper_hw_mode;if (local->hw.conf.beacon_int ==0 )
@@ -2431,7 +2442,8 @@ static int ieee80211_sta_find_ibss(struc MAC_FMT "\n", MAC_ARG(bssid), MAC_ARG(ifsta->bssid));#endif /* CONFIG_MAC80211_IBSS_DEBUG */ if (found &&memcmp (ifsta->bssid, bssid,ETH_ALEN ) !=0 && - (bss =ieee80211_rx_bss_get (dev, bssid, local->hw.conf.channel))) { + (bss =ieee80211_rx_bss_get (dev, bssid, local->hw.conf.channel, + ifsta->ssid, ifsta->ssid_len))) {printk (KERN_DEBUG "%s: Selected IBSS BSSID " MAC_FMT " based on configured SSID\n" , dev->name,MAC_ARG (bssid));
PATCH 21/23 mac80211: honor IW_SCAN_THIS_ESSID in siwscan ioctl
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: Bill Moss <[email protected]>
patch 107acb23ba763197d390ae9ffd347f3e2a524d39 in mainline.
This patch fixes the problem of associating with wpa_secured hidden AP. Please try out.
The original author of this patch is Bill Moss <[email protected]>
--- net/mac80211/ieee80211_ioctl.c | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-)
net/mac80211/ieee80211_ioctl.c +24 -16
@@ -687,32 +687,40 @@ static int ieee80211_ioctl_giwap(structstatic int ieee80211_ioctl_siwscan (struct net_device *dev,struct iw_request_info *info, -struct iw_point *data,char *extra) +union iwreq_data *wrqu,char *extra) {struct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev); +struct iw_scan_req *req =NULL ;u8 *ssid =NULL ;size_t ssid_len =0 ;if (!netif_running (dev))return -ENETDOWN ; -switch (sdata->type) { -case IEEE80211_IF_TYPE_STA : -case IEEE80211_IF_TYPE_IBSS : -if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { - ssid = sdata->u.sta.ssid; - ssid_len = sdata->u.sta.ssid_len; - } -break ; -case IEEE80211_IF_TYPE_AP : -if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { - ssid = sdata->u.ap.ssid; - ssid_len = sdata->u.ap.ssid_len; +if (wrqu->data.length ==sizeof (struct iw_scan_req ) && + wrqu->data.flags &IW_SCAN_THIS_ESSID ) { + req = (struct iw_scan_req *)extra; + ssid = req->essid; + ssid_len = req->essid_len; + }else { +switch (sdata->type) { +case IEEE80211_IF_TYPE_STA : +case IEEE80211_IF_TYPE_IBSS : +if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { + ssid = sdata->u.sta.ssid; + ssid_len = sdata->u.sta.ssid_len; + } +break ; +case IEEE80211_IF_TYPE_AP : +if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { + ssid = sdata->u.ap.ssid; + ssid_len = sdata->u.ap.ssid_len; + } +break ; +default : +return -EOPNOTSUPP ; } -break ; -default : -return -EOPNOTSUPP ; }return ieee80211_sta_req_scan (dev, ssid, ssid_len);
PATCH 22/23 mac80211: only honor IW_SCAN_THIS_ESSID in STA, IBSS, and AP modes
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
patch d114f399b4da6fa7f9da3bbf1fb841370c11e788 in mainline.
The previous IW_SCAN_THIS_ESSID patch left a hole allowing scan requests on interfaces in inappropriate modes.
--- net/mac80211/ieee80211_ioctl.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-)
net/mac80211/ieee80211_ioctl.c +19 -18
@@ -698,29 +698,30 @@ static int ieee80211_ioctl_siwscan(strucif (!netif_running (dev))return -ENETDOWN ; +switch (sdata->type) { +case IEEE80211_IF_TYPE_STA : +case IEEE80211_IF_TYPE_IBSS : +if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { + ssid = sdata->u.sta.ssid; + ssid_len = sdata->u.sta.ssid_len; + } +break ; +case IEEE80211_IF_TYPE_AP : +if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { + ssid = sdata->u.ap.ssid; + ssid_len = sdata->u.ap.ssid_len; + } +break ; +default : +return -EOPNOTSUPP ; + } + +/* if SSID was specified explicitly then use that */ if (wrqu->data.length ==sizeof (struct iw_scan_req ) && wrqu->data.flags &IW_SCAN_THIS_ESSID ) { req = (struct iw_scan_req *)extra; ssid = req->essid; ssid_len = req->essid_len; - }else { -switch (sdata->type) { -case IEEE80211_IF_TYPE_STA : -case IEEE80211_IF_TYPE_IBSS : -if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { - ssid = sdata->u.sta.ssid; - ssid_len = sdata->u.sta.ssid_len; - } -break ; -case IEEE80211_IF_TYPE_AP : -if (local->scan_flags &IEEE80211_SCAN_MATCH_SSID ) { - ssid = sdata->u.ap.ssid; - ssid_len = sdata->u.ap.ssid_len; - } -break ; -default : -return -EOPNOTSUPP ; - } }return ieee80211_sta_req_scan (dev, ssid, ssid_len);
PATCH 23/23 mac80211: make ieee802_11_parse_elems return void
In reply to Greg KH-stable review patch. If anyone has any objections, please let us know.
------------------
From: John W. Linville <[email protected]>
patch 67a4cce4a89718d252b61aaf58882c69c0e2f6e3 in mainline.
Some APs send management frames with junk padding after the last IE. We already account for a similar problem with some Apple Airport devices, but at least one device is known to send more than a single extra byte. The device in question is the Draytek Vigor2900:
http://www.draytek.com.au/products/Vigor2900.php
The junk in question looks like an IE that runs off the end of the frame. This cause us to return ParseFailed. Since the frame in question is an association response, this causes us to fail to associate with this AP.
The return code from ieee802_11_parse_elems is superfluous. All callers still check for the presence of the specific IEs that interest them anyway. So, remove the return code so the parse never "fails".
--- net/mac80211/ieee80211_sta.c | 56 ++++++------------------------------------- 1 file changed, 9 insertions(+), 47 deletions(-)
net/mac80211/ieee80211_sta.c +9 -47
@@ -108,15 +108,11 @@ struct ieee802_11_elems {u8 wmm_param_len; }; -typedef enum { ParseOK =0 , ParseUnknown =1 , ParseFailed =-1 }ParseRes ; - - -static ParseRes ieee802_11_parse_elems (u8 *start,size_t len, -struct ieee802_11_elems *elems) +static void ieee802_11_parse_elems (u8 *start,size_t len, +struct ieee802_11_elems *elems) {size_t left = len;u8 *pos = start; -int unknown =0 ;memset (elems,0 ,sizeof (*elems));
@@ -127,15 +123,8 @@ static ParseRes ieee802_11_parse_elems(u elen = *pos++; left -=2 ; -if (elen > left) { -#if 0 -if (net_ratelimit ()) -printk (KERN_DEBUG "IEEE 802.11 element parse " -"failed (id=%d elen=%d left=%d)\n" , - id, elen, left); -#endif -return ParseFailed; - } +if (elen > left) +return ;switch (id) {case WLAN_EID_SSID :
@@ -202,28 +191,15 @@ static ParseRes ieee802_11_parse_elems(u elems->ext_supp_rates_len = elen;break ;default : -#if 0 -printk (KERN_DEBUG "IEEE 802.11 element parse ignored " -"unknown element (id=%d elen=%d)\n" , - id, elen); -#endif - unknown++;break ; } left -= elen; pos += elen; } - -/* Do not trigger error if left == 1 as Apple Airport base stations -* send AssocResps that are one spurious byte too long. */ - -return unknown ? ParseUnknown : ParseOK; } - -static int ecw2cw (int ecw) {int cw =1 ;
@@ -907,12 +883,7 @@ static void ieee80211_auth_challenge(strprintk (KERN_DEBUG "%s: replying to auth challenge\n" , dev->name); pos = mgmt->u.auth.variable; -if (ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { -printk (KERN_DEBUG "%s: failed to parse Auth(challenge)\n" , - dev->name); -return ; - } +ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems);if (!elems.challenge) {printk (KERN_DEBUG "%s: no challenge IE in shared key auth " "frame\n" , dev->name);
@@ -1200,12 +1171,7 @@ static void ieee80211_rx_mgmt_assoc_resp aid &= ~(BIT (15 ) |BIT (14 )); pos = mgmt->u.assoc_resp.variable; -if (ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems) - == ParseFailed) { -printk (KERN_DEBUG "%s: failed to parse AssocResp\n" , - dev->name); -return ; - } +ieee802_11_parse_elems (pos, len - (pos - (u8 *) mgmt), &elems);if (!elems.supp_rates) { printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n",
@@ -1434,7 +1400,7 @@ static void ieee80211_rx_bss_info(structstruct ieee80211_local *local =wdev_priv (dev->ieee80211_ptr);struct ieee802_11_elems elems;size_t baselen; -int channel, invalid =0 , clen; +int channel, clen;struct ieee80211_sta_bss *bss;struct sta_info *sta;struct ieee80211_sub_if_data *sdata =IEEE80211_DEV_TO_SUB_IF (dev);
@@ -1478,9 +1444,7 @@ static void ieee80211_rx_bss_info(struct#endif /* CONFIG_MAC80211_IBSS_DEBUG */ } -if (ieee802_11_parse_elems (mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) - invalid =1 ; +ieee802_11_parse_elems (mgmt->u.beacon.variable, len - baselen, &elems); if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 &&
@@ -1699,9 +1663,7 @@ static void ieee80211_rx_mgmt_beacon(strif (baselen > len)return ; -if (ieee802_11_parse_elems (mgmt->u.beacon.variable, len - baselen, - &elems) == ParseFailed) -return ; +ieee802_11_parse_elems (mgmt->u.beacon.variable, len - baselen, &elems);if (elems.erp_info && elems.erp_info_len >=1 )ieee80211_handle_erp_ie (dev, elems.erp_info[0 ]);