diff options
Diffstat (limited to 'net')
| -rw-r--r-- | net/bluetooth/rfcomm/core.c | 1 | ||||
| -rw-r--r-- | net/bridge/br_multicast.c | 2 | ||||
| -rw-r--r-- | net/core/fib_rules.c | 3 | ||||
| -rw-r--r-- | net/core/sock.c | 47 | ||||
| -rw-r--r-- | net/ipv4/fib_frontend.c | 10 | ||||
| -rw-r--r-- | net/ipv4/route.c | 7 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 4 | ||||
| -rw-r--r-- | net/ipv4/udp.c | 1 | ||||
| -rw-r--r-- | net/ipv4/udplite.c | 1 | ||||
| -rw-r--r-- | net/ipv6/addrconf.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ip6_output.c | 12 | ||||
| -rw-r--r-- | net/ipv6/route.c | 7 | ||||
| -rw-r--r-- | net/ipv6/udp.c | 1 | ||||
| -rw-r--r-- | net/ipv6/udplite.c | 1 | ||||
| -rw-r--r-- | net/ipv6/xfrm6_output.c | 16 | ||||
| -rw-r--r-- | net/irda/af_irda.c | 18 | ||||
| -rw-r--r-- | net/mac80211/ibss.c | 4 | ||||
| -rw-r--r-- | net/mac80211/rx.c | 5 | ||||
| -rw-r--r-- | net/mac80211/work.c | 5 | ||||
| -rw-r--r-- | net/sched/sch_sfq.c | 20 | ||||
| -rw-r--r-- | net/sctp/socket.c | 2 |
21 files changed, 114 insertions, 57 deletions
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index fa642aa652bd..432a9a633e8d 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c | |||
| @@ -311,6 +311,7 @@ static void rfcomm_dlc_clear_state(struct rfcomm_dlc *d) | |||
| 311 | d->state = BT_OPEN; | 311 | d->state = BT_OPEN; |
| 312 | d->flags = 0; | 312 | d->flags = 0; |
| 313 | d->mscex = 0; | 313 | d->mscex = 0; |
| 314 | d->sec_level = BT_SECURITY_LOW; | ||
| 314 | d->mtu = RFCOMM_DEFAULT_MTU; | 315 | d->mtu = RFCOMM_DEFAULT_MTU; |
| 315 | d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV; | 316 | d->v24_sig = RFCOMM_V24_RTC | RFCOMM_V24_RTR | RFCOMM_V24_DV; |
| 316 | 317 | ||
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index eb5b256ffc88..f19e347f56f6 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -437,7 +437,7 @@ static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br, | |||
| 437 | ip6h = ipv6_hdr(skb); | 437 | ip6h = ipv6_hdr(skb); |
| 438 | 438 | ||
| 439 | *(__force __be32 *)ip6h = htonl(0x60000000); | 439 | *(__force __be32 *)ip6h = htonl(0x60000000); |
| 440 | ip6h->payload_len = 8 + sizeof(*mldq); | 440 | ip6h->payload_len = htons(8 + sizeof(*mldq)); |
| 441 | ip6h->nexthdr = IPPROTO_HOPOPTS; | 441 | ip6h->nexthdr = IPPROTO_HOPOPTS; |
| 442 | ip6h->hop_limit = 1; | 442 | ip6h->hop_limit = 1; |
| 443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); | 443 | ipv6_addr_set(&ip6h->saddr, 0, 0, 0, 0); |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 82a4369ae150..a20e5d3bbfa0 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
| @@ -181,8 +181,7 @@ static int fib_rule_match(struct fib_rule *rule, struct fib_rules_ops *ops, | |||
| 181 | { | 181 | { |
| 182 | int ret = 0; | 182 | int ret = 0; |
| 183 | 183 | ||
| 184 | if (rule->iifindex && (rule->iifindex != fl->iif) && | 184 | if (rule->iifindex && (rule->iifindex != fl->iif)) |
| 185 | !(fl->flags & FLOWI_FLAG_MATCH_ANY_IIF)) | ||
| 186 | goto out; | 185 | goto out; |
| 187 | 186 | ||
| 188 | if (rule->oifindex && (rule->oifindex != fl->oif)) | 187 | if (rule->oifindex && (rule->oifindex != fl->oif)) |
diff --git a/net/core/sock.c b/net/core/sock.c index fb6080111461..e5af8d5d5b50 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -1009,6 +1009,36 @@ static void sock_copy(struct sock *nsk, const struct sock *osk) | |||
| 1009 | #endif | 1009 | #endif |
| 1010 | } | 1010 | } |
| 1011 | 1011 | ||
| 1012 | /* | ||
| 1013 | * caches using SLAB_DESTROY_BY_RCU should let .next pointer from nulls nodes | ||
| 1014 | * un-modified. Special care is taken when initializing object to zero. | ||
| 1015 | */ | ||
| 1016 | static inline void sk_prot_clear_nulls(struct sock *sk, int size) | ||
| 1017 | { | ||
| 1018 | if (offsetof(struct sock, sk_node.next) != 0) | ||
| 1019 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
| 1020 | memset(&sk->sk_node.pprev, 0, | ||
| 1021 | size - offsetof(struct sock, sk_node.pprev)); | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | void sk_prot_clear_portaddr_nulls(struct sock *sk, int size) | ||
| 1025 | { | ||
| 1026 | unsigned long nulls1, nulls2; | ||
| 1027 | |||
| 1028 | nulls1 = offsetof(struct sock, __sk_common.skc_node.next); | ||
| 1029 | nulls2 = offsetof(struct sock, __sk_common.skc_portaddr_node.next); | ||
| 1030 | if (nulls1 > nulls2) | ||
| 1031 | swap(nulls1, nulls2); | ||
| 1032 | |||
| 1033 | if (nulls1 != 0) | ||
| 1034 | memset((char *)sk, 0, nulls1); | ||
| 1035 | memset((char *)sk + nulls1 + sizeof(void *), 0, | ||
| 1036 | nulls2 - nulls1 - sizeof(void *)); | ||
| 1037 | memset((char *)sk + nulls2 + sizeof(void *), 0, | ||
| 1038 | size - nulls2 - sizeof(void *)); | ||
| 1039 | } | ||
| 1040 | EXPORT_SYMBOL(sk_prot_clear_portaddr_nulls); | ||
| 1041 | |||
| 1012 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | 1042 | static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, |
| 1013 | int family) | 1043 | int family) |
| 1014 | { | 1044 | { |
| @@ -1021,19 +1051,12 @@ static struct sock *sk_prot_alloc(struct proto *prot, gfp_t priority, | |||
| 1021 | if (!sk) | 1051 | if (!sk) |
| 1022 | return sk; | 1052 | return sk; |
| 1023 | if (priority & __GFP_ZERO) { | 1053 | if (priority & __GFP_ZERO) { |
| 1024 | /* | 1054 | if (prot->clear_sk) |
| 1025 | * caches using SLAB_DESTROY_BY_RCU should let | 1055 | prot->clear_sk(sk, prot->obj_size); |
| 1026 | * sk_node.next un-modified. Special care is taken | 1056 | else |
| 1027 | * when initializing object to zero. | 1057 | sk_prot_clear_nulls(sk, prot->obj_size); |
| 1028 | */ | ||
| 1029 | if (offsetof(struct sock, sk_node.next) != 0) | ||
| 1030 | memset(sk, 0, offsetof(struct sock, sk_node.next)); | ||
| 1031 | memset(&sk->sk_node.pprev, 0, | ||
| 1032 | prot->obj_size - offsetof(struct sock, | ||
| 1033 | sk_node.pprev)); | ||
| 1034 | } | 1058 | } |
| 1035 | } | 1059 | } else |
| 1036 | else | ||
| 1037 | sk = kmalloc(prot->obj_size, priority); | 1060 | sk = kmalloc(prot->obj_size, priority); |
| 1038 | 1061 | ||
| 1039 | if (sk != NULL) { | 1062 | if (sk != NULL) { |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index eb6f69a8f27a..c19c1f739fba 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -163,13 +163,19 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref) | |||
| 163 | .daddr = addr | 163 | .daddr = addr |
| 164 | } | 164 | } |
| 165 | }, | 165 | }, |
| 166 | .flags = FLOWI_FLAG_MATCH_ANY_IIF | ||
| 167 | }; | 166 | }; |
| 168 | struct fib_result res = { 0 }; | 167 | struct fib_result res = { 0 }; |
| 169 | struct net_device *dev = NULL; | 168 | struct net_device *dev = NULL; |
| 169 | struct fib_table *local_table; | ||
| 170 | |||
| 171 | #ifdef CONFIG_IP_MULTIPLE_TABLES | ||
| 172 | res.r = NULL; | ||
| 173 | #endif | ||
| 170 | 174 | ||
| 171 | rcu_read_lock(); | 175 | rcu_read_lock(); |
| 172 | if (fib_lookup(net, &fl, &res)) { | 176 | local_table = fib_get_table(net, RT_TABLE_LOCAL); |
| 177 | if (!local_table || | ||
| 178 | fib_table_lookup(local_table, &fl, &res, FIB_LOOKUP_NOREF)) { | ||
| 173 | rcu_read_unlock(); | 179 | rcu_read_unlock(); |
| 174 | return NULL; | 180 | return NULL; |
| 175 | } | 181 | } |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 987bf9adb318..df948b0f1ac9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2585,9 +2585,10 @@ static int ip_route_output_slow(struct net *net, struct rtable **rp, | |||
| 2585 | goto out; | 2585 | goto out; |
| 2586 | 2586 | ||
| 2587 | /* RACE: Check return value of inet_select_addr instead. */ | 2587 | /* RACE: Check return value of inet_select_addr instead. */ |
| 2588 | if (rcu_dereference(dev_out->ip_ptr) == NULL) | 2588 | if (!(dev_out->flags & IFF_UP) || !__in_dev_get_rcu(dev_out)) { |
| 2589 | goto out; /* Wrong error code */ | 2589 | err = -ENETUNREACH; |
| 2590 | 2590 | goto out; | |
| 2591 | } | ||
| 2591 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || | 2592 | if (ipv4_is_local_multicast(oldflp->fl4_dst) || |
| 2592 | ipv4_is_lbcast(oldflp->fl4_dst)) { | 2593 | ipv4_is_lbcast(oldflp->fl4_dst)) { |
| 2593 | if (!fl.fl4_src) | 2594 | if (!fl.fl4_src) |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index e13da6de1fc7..d978bb2f748b 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -2030,7 +2030,7 @@ static void *listening_get_next(struct seq_file *seq, void *cur) | |||
| 2030 | get_req: | 2030 | get_req: |
| 2031 | req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; | 2031 | req = icsk->icsk_accept_queue.listen_opt->syn_table[st->sbucket]; |
| 2032 | } | 2032 | } |
| 2033 | sk = sk_next(st->syn_wait_sk); | 2033 | sk = sk_nulls_next(st->syn_wait_sk); |
| 2034 | st->state = TCP_SEQ_STATE_LISTENING; | 2034 | st->state = TCP_SEQ_STATE_LISTENING; |
| 2035 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 2035 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
| 2036 | } else { | 2036 | } else { |
| @@ -2039,7 +2039,7 @@ get_req: | |||
| 2039 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) | 2039 | if (reqsk_queue_len(&icsk->icsk_accept_queue)) |
| 2040 | goto start_req; | 2040 | goto start_req; |
| 2041 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); | 2041 | read_unlock_bh(&icsk->icsk_accept_queue.syn_wait_lock); |
| 2042 | sk = sk_next(sk); | 2042 | sk = sk_nulls_next(sk); |
| 2043 | } | 2043 | } |
| 2044 | get_sk: | 2044 | get_sk: |
| 2045 | sk_nulls_for_each_from(sk, node) { | 2045 | sk_nulls_for_each_from(sk, node) { |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 5e0a3a582a59..2d3ded4d0786 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
| @@ -1899,6 +1899,7 @@ struct proto udp_prot = { | |||
| 1899 | .compat_setsockopt = compat_udp_setsockopt, | 1899 | .compat_setsockopt = compat_udp_setsockopt, |
| 1900 | .compat_getsockopt = compat_udp_getsockopt, | 1900 | .compat_getsockopt = compat_udp_getsockopt, |
| 1901 | #endif | 1901 | #endif |
| 1902 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
| 1902 | }; | 1903 | }; |
| 1903 | EXPORT_SYMBOL(udp_prot); | 1904 | EXPORT_SYMBOL(udp_prot); |
| 1904 | 1905 | ||
diff --git a/net/ipv4/udplite.c b/net/ipv4/udplite.c index ab76aa928fa9..aee9963f7f5a 100644 --- a/net/ipv4/udplite.c +++ b/net/ipv4/udplite.c | |||
| @@ -57,6 +57,7 @@ struct proto udplite_prot = { | |||
| 57 | .compat_setsockopt = compat_udp_setsockopt, | 57 | .compat_setsockopt = compat_udp_setsockopt, |
| 58 | .compat_getsockopt = compat_udp_getsockopt, | 58 | .compat_getsockopt = compat_udp_getsockopt, |
| 59 | #endif | 59 | #endif |
| 60 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
| 60 | }; | 61 | }; |
| 61 | EXPORT_SYMBOL(udplite_prot); | 62 | EXPORT_SYMBOL(udplite_prot); |
| 62 | 63 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 93b7a933a775..848b35591042 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
| @@ -2669,7 +2669,9 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
| 2669 | 2669 | ||
| 2670 | ASSERT_RTNL(); | 2670 | ASSERT_RTNL(); |
| 2671 | 2671 | ||
| 2672 | rt6_ifdown(net, dev); | 2672 | /* Flush routes if device is being removed or it is not loopback */ |
| 2673 | if (how || !(dev->flags & IFF_LOOPBACK)) | ||
| 2674 | rt6_ifdown(net, dev); | ||
| 2673 | neigh_ifdown(&nd_tbl, dev); | 2675 | neigh_ifdown(&nd_tbl, dev); |
| 2674 | 2676 | ||
| 2675 | idev = __in6_dev_get(dev); | 2677 | idev = __in6_dev_get(dev); |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 99157b4cd56e..94b5bf132b2e 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -56,7 +56,7 @@ | |||
| 56 | #include <net/checksum.h> | 56 | #include <net/checksum.h> |
| 57 | #include <linux/mroute6.h> | 57 | #include <linux/mroute6.h> |
| 58 | 58 | ||
| 59 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); | 59 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)); |
| 60 | 60 | ||
| 61 | int __ip6_local_out(struct sk_buff *skb) | 61 | int __ip6_local_out(struct sk_buff *skb) |
| 62 | { | 62 | { |
| @@ -145,14 +145,6 @@ static int ip6_finish_output2(struct sk_buff *skb) | |||
| 145 | return -EINVAL; | 145 | return -EINVAL; |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | static inline int ip6_skb_dst_mtu(struct sk_buff *skb) | ||
| 149 | { | ||
| 150 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | ||
| 151 | |||
| 152 | return (np && np->pmtudisc == IPV6_PMTUDISC_PROBE) ? | ||
| 153 | skb_dst(skb)->dev->mtu : dst_mtu(skb_dst(skb)); | ||
| 154 | } | ||
| 155 | |||
| 156 | static int ip6_finish_output(struct sk_buff *skb) | 148 | static int ip6_finish_output(struct sk_buff *skb) |
| 157 | { | 149 | { |
| 158 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | 150 | if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || |
| @@ -601,7 +593,7 @@ int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr) | |||
| 601 | return offset; | 593 | return offset; |
| 602 | } | 594 | } |
| 603 | 595 | ||
| 604 | static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 596 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
| 605 | { | 597 | { |
| 606 | struct sk_buff *frag; | 598 | struct sk_buff *frag; |
| 607 | struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); | 599 | struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 96455ffb76fb..7659d6f16e6b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -1565,11 +1565,16 @@ static void rt6_do_pmtu_disc(struct in6_addr *daddr, struct in6_addr *saddr, | |||
| 1565 | { | 1565 | { |
| 1566 | struct rt6_info *rt, *nrt; | 1566 | struct rt6_info *rt, *nrt; |
| 1567 | int allfrag = 0; | 1567 | int allfrag = 0; |
| 1568 | 1568 | again: | |
| 1569 | rt = rt6_lookup(net, daddr, saddr, ifindex, 0); | 1569 | rt = rt6_lookup(net, daddr, saddr, ifindex, 0); |
| 1570 | if (rt == NULL) | 1570 | if (rt == NULL) |
| 1571 | return; | 1571 | return; |
| 1572 | 1572 | ||
| 1573 | if (rt6_check_expired(rt)) { | ||
| 1574 | ip6_del_rt(rt); | ||
| 1575 | goto again; | ||
| 1576 | } | ||
| 1577 | |||
| 1573 | if (pmtu >= dst_mtu(&rt->dst)) | 1578 | if (pmtu >= dst_mtu(&rt->dst)) |
| 1574 | goto out; | 1579 | goto out; |
| 1575 | 1580 | ||
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index 91def93bec85..cd6cb7c3e563 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -1477,6 +1477,7 @@ struct proto udpv6_prot = { | |||
| 1477 | .compat_setsockopt = compat_udpv6_setsockopt, | 1477 | .compat_setsockopt = compat_udpv6_setsockopt, |
| 1478 | .compat_getsockopt = compat_udpv6_getsockopt, | 1478 | .compat_getsockopt = compat_udpv6_getsockopt, |
| 1479 | #endif | 1479 | #endif |
| 1480 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
| 1480 | }; | 1481 | }; |
| 1481 | 1482 | ||
| 1482 | static struct inet_protosw udpv6_protosw = { | 1483 | static struct inet_protosw udpv6_protosw = { |
diff --git a/net/ipv6/udplite.c b/net/ipv6/udplite.c index 5f48fadc27f7..986c4de5292e 100644 --- a/net/ipv6/udplite.c +++ b/net/ipv6/udplite.c | |||
| @@ -55,6 +55,7 @@ struct proto udplitev6_prot = { | |||
| 55 | .compat_setsockopt = compat_udpv6_setsockopt, | 55 | .compat_setsockopt = compat_udpv6_setsockopt, |
| 56 | .compat_getsockopt = compat_udpv6_getsockopt, | 56 | .compat_getsockopt = compat_udpv6_getsockopt, |
| 57 | #endif | 57 | #endif |
| 58 | .clear_sk = sk_prot_clear_portaddr_nulls, | ||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | static struct inet_protosw udplite6_protosw = { | 61 | static struct inet_protosw udplite6_protosw = { |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 6434bd5ce088..8e688b3de9ab 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -17,6 +17,7 @@ | |||
| 17 | #include <linux/netfilter_ipv6.h> | 17 | #include <linux/netfilter_ipv6.h> |
| 18 | #include <net/dst.h> | 18 | #include <net/dst.h> |
| 19 | #include <net/ipv6.h> | 19 | #include <net/ipv6.h> |
| 20 | #include <net/ip6_route.h> | ||
| 20 | #include <net/xfrm.h> | 21 | #include <net/xfrm.h> |
| 21 | 22 | ||
| 22 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, | 23 | int xfrm6_find_1stfragopt(struct xfrm_state *x, struct sk_buff *skb, |
| @@ -88,8 +89,21 @@ static int xfrm6_output_finish(struct sk_buff *skb) | |||
| 88 | return xfrm_output(skb); | 89 | return xfrm_output(skb); |
| 89 | } | 90 | } |
| 90 | 91 | ||
| 92 | static int __xfrm6_output(struct sk_buff *skb) | ||
| 93 | { | ||
| 94 | struct dst_entry *dst = skb_dst(skb); | ||
| 95 | struct xfrm_state *x = dst->xfrm; | ||
| 96 | |||
| 97 | if ((x && x->props.mode == XFRM_MODE_TUNNEL) && | ||
| 98 | ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || | ||
| 99 | dst_allfrag(skb_dst(skb)))) { | ||
| 100 | return ip6_fragment(skb, xfrm6_output_finish); | ||
| 101 | } | ||
| 102 | return xfrm6_output_finish(skb); | ||
| 103 | } | ||
| 104 | |||
| 91 | int xfrm6_output(struct sk_buff *skb) | 105 | int xfrm6_output(struct sk_buff *skb) |
| 92 | { | 106 | { |
| 93 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, | 107 | return NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, |
| 94 | skb_dst(skb)->dev, xfrm6_output_finish); | 108 | skb_dst(skb)->dev, __xfrm6_output); |
| 95 | } | 109 | } |
diff --git a/net/irda/af_irda.c b/net/irda/af_irda.c index a6de3059746d..c9890e25cd4c 100644 --- a/net/irda/af_irda.c +++ b/net/irda/af_irda.c | |||
| @@ -2280,6 +2280,16 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, | |||
| 2280 | 2280 | ||
| 2281 | switch (optname) { | 2281 | switch (optname) { |
| 2282 | case IRLMP_ENUMDEVICES: | 2282 | case IRLMP_ENUMDEVICES: |
| 2283 | |||
| 2284 | /* Offset to first device entry */ | ||
| 2285 | offset = sizeof(struct irda_device_list) - | ||
| 2286 | sizeof(struct irda_device_info); | ||
| 2287 | |||
| 2288 | if (len < offset) { | ||
| 2289 | err = -EINVAL; | ||
| 2290 | goto out; | ||
| 2291 | } | ||
| 2292 | |||
| 2283 | /* Ask lmp for the current discovery log */ | 2293 | /* Ask lmp for the current discovery log */ |
| 2284 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, | 2294 | discoveries = irlmp_get_discoveries(&list.len, self->mask.word, |
| 2285 | self->nslots); | 2295 | self->nslots); |
| @@ -2290,15 +2300,9 @@ static int irda_getsockopt(struct socket *sock, int level, int optname, | |||
| 2290 | } | 2300 | } |
| 2291 | 2301 | ||
| 2292 | /* Write total list length back to client */ | 2302 | /* Write total list length back to client */ |
| 2293 | if (copy_to_user(optval, &list, | 2303 | if (copy_to_user(optval, &list, offset)) |
| 2294 | sizeof(struct irda_device_list) - | ||
| 2295 | sizeof(struct irda_device_info))) | ||
| 2296 | err = -EFAULT; | 2304 | err = -EFAULT; |
| 2297 | 2305 | ||
| 2298 | /* Offset to first device entry */ | ||
| 2299 | offset = sizeof(struct irda_device_list) - | ||
| 2300 | sizeof(struct irda_device_info); | ||
| 2301 | |||
| 2302 | /* Copy the list itself - watch for overflow */ | 2306 | /* Copy the list itself - watch for overflow */ |
| 2303 | if (list.len > 2048) { | 2307 | if (list.len > 2048) { |
| 2304 | err = -EINVAL; | 2308 | err = -EINVAL; |
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c index 239c4836a946..077a93dd1671 100644 --- a/net/mac80211/ibss.c +++ b/net/mac80211/ibss.c | |||
| @@ -780,6 +780,9 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 780 | 780 | ||
| 781 | mutex_lock(&sdata->u.ibss.mtx); | 781 | mutex_lock(&sdata->u.ibss.mtx); |
| 782 | 782 | ||
| 783 | if (!sdata->u.ibss.ssid_len) | ||
| 784 | goto mgmt_out; /* not ready to merge yet */ | ||
| 785 | |||
| 783 | switch (fc & IEEE80211_FCTL_STYPE) { | 786 | switch (fc & IEEE80211_FCTL_STYPE) { |
| 784 | case IEEE80211_STYPE_PROBE_REQ: | 787 | case IEEE80211_STYPE_PROBE_REQ: |
| 785 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); | 788 | ieee80211_rx_mgmt_probe_req(sdata, mgmt, skb->len); |
| @@ -797,6 +800,7 @@ void ieee80211_ibss_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata, | |||
| 797 | break; | 800 | break; |
| 798 | } | 801 | } |
| 799 | 802 | ||
| 803 | mgmt_out: | ||
| 800 | mutex_unlock(&sdata->u.ibss.mtx); | 804 | mutex_unlock(&sdata->u.ibss.mtx); |
| 801 | } | 805 | } |
| 802 | 806 | ||
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 54fb4a0e76f0..b01e467b76c6 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1788,9 +1788,11 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1788 | 1788 | ||
| 1789 | fwd_skb = skb_copy(skb, GFP_ATOMIC); | 1789 | fwd_skb = skb_copy(skb, GFP_ATOMIC); |
| 1790 | 1790 | ||
| 1791 | if (!fwd_skb && net_ratelimit()) | 1791 | if (!fwd_skb && net_ratelimit()) { |
| 1792 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", | 1792 | printk(KERN_DEBUG "%s: failed to clone mesh frame\n", |
| 1793 | sdata->name); | 1793 | sdata->name); |
| 1794 | goto out; | ||
| 1795 | } | ||
| 1794 | 1796 | ||
| 1795 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; | 1797 | fwd_hdr = (struct ieee80211_hdr *) fwd_skb->data; |
| 1796 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); | 1798 | memcpy(fwd_hdr->addr2, sdata->vif.addr, ETH_ALEN); |
| @@ -1828,6 +1830,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 1828 | } | 1830 | } |
| 1829 | } | 1831 | } |
| 1830 | 1832 | ||
| 1833 | out: | ||
| 1831 | if (is_multicast_ether_addr(hdr->addr1) || | 1834 | if (is_multicast_ether_addr(hdr->addr1) || |
| 1832 | sdata->dev->flags & IFF_PROMISC) | 1835 | sdata->dev->flags & IFF_PROMISC) |
| 1833 | return RX_CONTINUE; | 1836 | return RX_CONTINUE; |
diff --git a/net/mac80211/work.c b/net/mac80211/work.c index ae344d1ba056..146097cb43a7 100644 --- a/net/mac80211/work.c +++ b/net/mac80211/work.c | |||
| @@ -1051,11 +1051,13 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
| 1051 | { | 1051 | { |
| 1052 | struct ieee80211_local *local = sdata->local; | 1052 | struct ieee80211_local *local = sdata->local; |
| 1053 | struct ieee80211_work *wk; | 1053 | struct ieee80211_work *wk; |
| 1054 | bool cleanup = false; | ||
| 1054 | 1055 | ||
| 1055 | mutex_lock(&local->mtx); | 1056 | mutex_lock(&local->mtx); |
| 1056 | list_for_each_entry(wk, &local->work_list, list) { | 1057 | list_for_each_entry(wk, &local->work_list, list) { |
| 1057 | if (wk->sdata != sdata) | 1058 | if (wk->sdata != sdata) |
| 1058 | continue; | 1059 | continue; |
| 1060 | cleanup = true; | ||
| 1059 | wk->type = IEEE80211_WORK_ABORT; | 1061 | wk->type = IEEE80211_WORK_ABORT; |
| 1060 | wk->started = true; | 1062 | wk->started = true; |
| 1061 | wk->timeout = jiffies; | 1063 | wk->timeout = jiffies; |
| @@ -1063,7 +1065,8 @@ void ieee80211_work_purge(struct ieee80211_sub_if_data *sdata) | |||
| 1063 | mutex_unlock(&local->mtx); | 1065 | mutex_unlock(&local->mtx); |
| 1064 | 1066 | ||
| 1065 | /* run cleanups etc. */ | 1067 | /* run cleanups etc. */ |
| 1066 | ieee80211_work_work(&local->work_work); | 1068 | if (cleanup) |
| 1069 | ieee80211_work_work(&local->work_work); | ||
| 1067 | 1070 | ||
| 1068 | mutex_lock(&local->mtx); | 1071 | mutex_lock(&local->mtx); |
| 1069 | list_for_each_entry(wk, &local->work_list, list) { | 1072 | list_for_each_entry(wk, &local->work_list, list) { |
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c index 3cf478d012dd..7150705f1d0b 100644 --- a/net/sched/sch_sfq.c +++ b/net/sched/sch_sfq.c | |||
| @@ -270,7 +270,6 @@ static unsigned int sfq_drop(struct Qdisc *sch) | |||
| 270 | /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ | 270 | /* It is difficult to believe, but ALL THE SLOTS HAVE LENGTH 1. */ |
| 271 | d = q->next[q->tail]; | 271 | d = q->next[q->tail]; |
| 272 | q->next[q->tail] = q->next[d]; | 272 | q->next[q->tail] = q->next[d]; |
| 273 | q->allot[q->next[d]] += q->quantum; | ||
| 274 | skb = q->qs[d].prev; | 273 | skb = q->qs[d].prev; |
| 275 | len = qdisc_pkt_len(skb); | 274 | len = qdisc_pkt_len(skb); |
| 276 | __skb_unlink(skb, &q->qs[d]); | 275 | __skb_unlink(skb, &q->qs[d]); |
| @@ -321,14 +320,13 @@ sfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
| 321 | sfq_inc(q, x); | 320 | sfq_inc(q, x); |
| 322 | if (q->qs[x].qlen == 1) { /* The flow is new */ | 321 | if (q->qs[x].qlen == 1) { /* The flow is new */ |
| 323 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ | 322 | if (q->tail == SFQ_DEPTH) { /* It is the first flow */ |
| 324 | q->tail = x; | ||
| 325 | q->next[x] = x; | 323 | q->next[x] = x; |
| 326 | q->allot[x] = q->quantum; | ||
| 327 | } else { | 324 | } else { |
| 328 | q->next[x] = q->next[q->tail]; | 325 | q->next[x] = q->next[q->tail]; |
| 329 | q->next[q->tail] = x; | 326 | q->next[q->tail] = x; |
| 330 | q->tail = x; | ||
| 331 | } | 327 | } |
| 328 | q->tail = x; | ||
| 329 | q->allot[x] = q->quantum; | ||
| 332 | } | 330 | } |
| 333 | if (++sch->q.qlen <= q->limit) { | 331 | if (++sch->q.qlen <= q->limit) { |
| 334 | sch->bstats.bytes += qdisc_pkt_len(skb); | 332 | sch->bstats.bytes += qdisc_pkt_len(skb); |
| @@ -359,13 +357,13 @@ sfq_dequeue(struct Qdisc *sch) | |||
| 359 | { | 357 | { |
| 360 | struct sfq_sched_data *q = qdisc_priv(sch); | 358 | struct sfq_sched_data *q = qdisc_priv(sch); |
| 361 | struct sk_buff *skb; | 359 | struct sk_buff *skb; |
| 362 | sfq_index a, old_a; | 360 | sfq_index a, next_a; |
| 363 | 361 | ||
| 364 | /* No active slots */ | 362 | /* No active slots */ |
| 365 | if (q->tail == SFQ_DEPTH) | 363 | if (q->tail == SFQ_DEPTH) |
| 366 | return NULL; | 364 | return NULL; |
| 367 | 365 | ||
| 368 | a = old_a = q->next[q->tail]; | 366 | a = q->next[q->tail]; |
| 369 | 367 | ||
| 370 | /* Grab packet */ | 368 | /* Grab packet */ |
| 371 | skb = __skb_dequeue(&q->qs[a]); | 369 | skb = __skb_dequeue(&q->qs[a]); |
| @@ -376,17 +374,15 @@ sfq_dequeue(struct Qdisc *sch) | |||
| 376 | /* Is the slot empty? */ | 374 | /* Is the slot empty? */ |
| 377 | if (q->qs[a].qlen == 0) { | 375 | if (q->qs[a].qlen == 0) { |
| 378 | q->ht[q->hash[a]] = SFQ_DEPTH; | 376 | q->ht[q->hash[a]] = SFQ_DEPTH; |
| 379 | a = q->next[a]; | 377 | next_a = q->next[a]; |
| 380 | if (a == old_a) { | 378 | if (a == next_a) { |
| 381 | q->tail = SFQ_DEPTH; | 379 | q->tail = SFQ_DEPTH; |
| 382 | return skb; | 380 | return skb; |
| 383 | } | 381 | } |
| 384 | q->next[q->tail] = a; | 382 | q->next[q->tail] = next_a; |
| 385 | q->allot[a] += q->quantum; | ||
| 386 | } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { | 383 | } else if ((q->allot[a] -= qdisc_pkt_len(skb)) <= 0) { |
| 387 | q->tail = a; | ||
| 388 | a = q->next[a]; | ||
| 389 | q->allot[a] += q->quantum; | 384 | q->allot[a] += q->quantum; |
| 385 | q->tail = a; | ||
| 390 | } | 386 | } |
| 391 | return skb; | 387 | return skb; |
| 392 | } | 388 | } |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 0b9ee34ad35c..fff0926b1111 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -5053,7 +5053,7 @@ static int sctp_getsockopt_partial_delivery_point(struct sock *sk, int len, | |||
| 5053 | if (copy_to_user(optval, &val, len)) | 5053 | if (copy_to_user(optval, &val, len)) |
| 5054 | return -EFAULT; | 5054 | return -EFAULT; |
| 5055 | 5055 | ||
| 5056 | return -ENOTSUPP; | 5056 | return 0; |
| 5057 | } | 5057 | } |
| 5058 | 5058 | ||
| 5059 | /* | 5059 | /* |
