diff options
| author | Grant Likely <grant.likely@linaro.org> | 2014-03-31 03:10:55 -0400 |
|---|---|---|
| committer | Grant Likely <grant.likely@linaro.org> | 2014-03-31 03:10:55 -0400 |
| commit | d88cf7d7b4240b8df170ba105e414e476fb51cce (patch) | |
| tree | 7efe976da6e0ec854eb0eeda82c1e9a275b8c69f /net | |
| parent | 676e1b2fcd9dbb47a59baac13d089621d22c68b8 (diff) | |
| parent | 6f976267da0e2c873c4b4aaacaf08266d1d1797d (diff) | |
Merge remote-tracking branch 'robh/for-next' into devicetree/next
Diffstat (limited to 'net')
53 files changed, 500 insertions, 384 deletions
diff --git a/net/can/raw.c b/net/can/raw.c index 8be757cca2ec..081e81fd017f 100644 --- a/net/can/raw.c +++ b/net/can/raw.c | |||
| @@ -121,13 +121,9 @@ static void raw_rcv(struct sk_buff *oskb, void *data) | |||
| 121 | if (!ro->recv_own_msgs && oskb->sk == sk) | 121 | if (!ro->recv_own_msgs && oskb->sk == sk) |
| 122 | return; | 122 | return; |
| 123 | 123 | ||
| 124 | /* do not pass frames with DLC > 8 to a legacy socket */ | 124 | /* do not pass non-CAN2.0 frames to a legacy socket */ |
| 125 | if (!ro->fd_frames) { | 125 | if (!ro->fd_frames && oskb->len != CAN_MTU) |
| 126 | struct canfd_frame *cfd = (struct canfd_frame *)oskb->data; | 126 | return; |
| 127 | |||
| 128 | if (unlikely(cfd->len > CAN_MAX_DLEN)) | ||
| 129 | return; | ||
| 130 | } | ||
| 131 | 127 | ||
| 132 | /* clone the given skb to be able to enqueue it into the rcv queue */ | 128 | /* clone the given skb to be able to enqueue it into the rcv queue */ |
| 133 | skb = skb_clone(oskb, GFP_ATOMIC); | 129 | skb = skb_clone(oskb, GFP_ATOMIC); |
| @@ -738,9 +734,7 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 738 | struct msghdr *msg, size_t size, int flags) | 734 | struct msghdr *msg, size_t size, int flags) |
| 739 | { | 735 | { |
| 740 | struct sock *sk = sock->sk; | 736 | struct sock *sk = sock->sk; |
| 741 | struct raw_sock *ro = raw_sk(sk); | ||
| 742 | struct sk_buff *skb; | 737 | struct sk_buff *skb; |
| 743 | int rxmtu; | ||
| 744 | int err = 0; | 738 | int err = 0; |
| 745 | int noblock; | 739 | int noblock; |
| 746 | 740 | ||
| @@ -751,20 +745,10 @@ static int raw_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 751 | if (!skb) | 745 | if (!skb) |
| 752 | return err; | 746 | return err; |
| 753 | 747 | ||
| 754 | /* | 748 | if (size < skb->len) |
| 755 | * when serving a legacy socket the DLC <= 8 is already checked inside | ||
| 756 | * raw_rcv(). Now check if we need to pass a canfd_frame to a legacy | ||
| 757 | * socket and cut the possible CANFD_MTU/CAN_MTU length to CAN_MTU | ||
| 758 | */ | ||
| 759 | if (!ro->fd_frames) | ||
| 760 | rxmtu = CAN_MTU; | ||
| 761 | else | ||
| 762 | rxmtu = skb->len; | ||
| 763 | |||
| 764 | if (size < rxmtu) | ||
| 765 | msg->msg_flags |= MSG_TRUNC; | 749 | msg->msg_flags |= MSG_TRUNC; |
| 766 | else | 750 | else |
| 767 | size = rxmtu; | 751 | size = skb->len; |
| 768 | 752 | ||
| 769 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); | 753 | err = memcpy_toiovec(msg->msg_iov, skb->data, size); |
| 770 | if (err < 0) { | 754 | if (err < 0) { |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index b9e9e0d38672..e16129019c66 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
| @@ -766,9 +766,6 @@ static void neigh_periodic_work(struct work_struct *work) | |||
| 766 | nht = rcu_dereference_protected(tbl->nht, | 766 | nht = rcu_dereference_protected(tbl->nht, |
| 767 | lockdep_is_held(&tbl->lock)); | 767 | lockdep_is_held(&tbl->lock)); |
| 768 | 768 | ||
| 769 | if (atomic_read(&tbl->entries) < tbl->gc_thresh1) | ||
| 770 | goto out; | ||
| 771 | |||
| 772 | /* | 769 | /* |
| 773 | * periodically recompute ReachableTime from random function | 770 | * periodically recompute ReachableTime from random function |
| 774 | */ | 771 | */ |
| @@ -781,6 +778,9 @@ static void neigh_periodic_work(struct work_struct *work) | |||
| 781 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); | 778 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); |
| 782 | } | 779 | } |
| 783 | 780 | ||
| 781 | if (atomic_read(&tbl->entries) < tbl->gc_thresh1) | ||
| 782 | goto out; | ||
| 783 | |||
| 784 | for (i = 0 ; i < (1 << nht->hash_shift); i++) { | 784 | for (i = 0 ; i < (1 << nht->hash_shift); i++) { |
| 785 | np = &nht->hash_buckets[i]; | 785 | np = &nht->hash_buckets[i]; |
| 786 | 786 | ||
| @@ -3046,7 +3046,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
| 3046 | if (!t) | 3046 | if (!t) |
| 3047 | goto err; | 3047 | goto err; |
| 3048 | 3048 | ||
| 3049 | for (i = 0; i < ARRAY_SIZE(t->neigh_vars); i++) { | 3049 | for (i = 0; i < NEIGH_VAR_GC_INTERVAL; i++) { |
| 3050 | t->neigh_vars[i].data += (long) p; | 3050 | t->neigh_vars[i].data += (long) p; |
| 3051 | t->neigh_vars[i].extra1 = dev; | 3051 | t->neigh_vars[i].extra1 = dev; |
| 3052 | t->neigh_vars[i].extra2 = p; | 3052 | t->neigh_vars[i].extra2 = p; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 5976ef0846bd..5d6236d9fdce 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -707,9 +707,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old) | |||
| 707 | new->mark = old->mark; | 707 | new->mark = old->mark; |
| 708 | new->skb_iif = old->skb_iif; | 708 | new->skb_iif = old->skb_iif; |
| 709 | __nf_copy(new, old); | 709 | __nf_copy(new, old); |
| 710 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) | ||
| 711 | new->nf_trace = old->nf_trace; | ||
| 712 | #endif | ||
| 713 | #ifdef CONFIG_NET_SCHED | 710 | #ifdef CONFIG_NET_SCHED |
| 714 | new->tc_index = old->tc_index; | 711 | new->tc_index = old->tc_index; |
| 715 | #ifdef CONFIG_NET_CLS_ACT | 712 | #ifdef CONFIG_NET_CLS_ACT |
diff --git a/net/hsr/hsr_framereg.c b/net/hsr/hsr_framereg.c index 327060c6c874..7ae0d7f6dbd0 100644 --- a/net/hsr/hsr_framereg.c +++ b/net/hsr/hsr_framereg.c | |||
| @@ -297,7 +297,7 @@ static bool seq_nr_after(u16 a, u16 b) | |||
| 297 | 297 | ||
| 298 | void hsr_register_frame_in(struct node_entry *node, enum hsr_dev_idx dev_idx) | 298 | void hsr_register_frame_in(struct node_entry *node, enum hsr_dev_idx dev_idx) |
| 299 | { | 299 | { |
| 300 | if ((dev_idx < 0) || (dev_idx >= HSR_MAX_DEV)) { | 300 | if ((dev_idx < 0) || (dev_idx >= HSR_MAX_SLAVE)) { |
| 301 | WARN_ONCE(1, "%s: Invalid dev_idx (%d)\n", __func__, dev_idx); | 301 | WARN_ONCE(1, "%s: Invalid dev_idx (%d)\n", __func__, dev_idx); |
| 302 | return; | 302 | return; |
| 303 | } | 303 | } |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index ecd2c3f245ce..19ab78aca547 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -1296,8 +1296,11 @@ static struct sk_buff *inet_gso_segment(struct sk_buff *skb, | |||
| 1296 | 1296 | ||
| 1297 | segs = ERR_PTR(-EPROTONOSUPPORT); | 1297 | segs = ERR_PTR(-EPROTONOSUPPORT); |
| 1298 | 1298 | ||
| 1299 | /* Note : following gso_segment() might change skb->encapsulation */ | 1299 | if (skb->encapsulation && |
| 1300 | udpfrag = !skb->encapsulation && proto == IPPROTO_UDP; | 1300 | skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP)) |
| 1301 | udpfrag = proto == IPPROTO_UDP && encap; | ||
| 1302 | else | ||
| 1303 | udpfrag = proto == IPPROTO_UDP && !skb->encapsulation; | ||
| 1301 | 1304 | ||
| 1302 | ops = rcu_dereference(inet_offloads[proto]); | 1305 | ops = rcu_dereference(inet_offloads[proto]); |
| 1303 | if (likely(ops && ops->callbacks.gso_segment)) | 1306 | if (likely(ops && ops->callbacks.gso_segment)) |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 8971780aec7c..73c6b63bba74 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -422,9 +422,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
| 422 | to->tc_index = from->tc_index; | 422 | to->tc_index = from->tc_index; |
| 423 | #endif | 423 | #endif |
| 424 | nf_copy(to, from); | 424 | nf_copy(to, from); |
| 425 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) | ||
| 426 | to->nf_trace = from->nf_trace; | ||
| 427 | #endif | ||
| 428 | #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) | 425 | #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) |
| 429 | to->ipvs_property = from->ipvs_property; | 426 | to->ipvs_property = from->ipvs_property; |
| 430 | #endif | 427 | #endif |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index 50228be5c17b..78a89e61925d 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
| @@ -93,13 +93,14 @@ static void tunnel_dst_reset(struct ip_tunnel *t) | |||
| 93 | tunnel_dst_set(t, NULL); | 93 | tunnel_dst_set(t, NULL); |
| 94 | } | 94 | } |
| 95 | 95 | ||
| 96 | static void tunnel_dst_reset_all(struct ip_tunnel *t) | 96 | void ip_tunnel_dst_reset_all(struct ip_tunnel *t) |
| 97 | { | 97 | { |
| 98 | int i; | 98 | int i; |
| 99 | 99 | ||
| 100 | for_each_possible_cpu(i) | 100 | for_each_possible_cpu(i) |
| 101 | __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); | 101 | __tunnel_dst_set(per_cpu_ptr(t->dst_cache, i), NULL); |
| 102 | } | 102 | } |
| 103 | EXPORT_SYMBOL(ip_tunnel_dst_reset_all); | ||
| 103 | 104 | ||
| 104 | static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) | 105 | static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) |
| 105 | { | 106 | { |
| @@ -119,52 +120,6 @@ static struct rtable *tunnel_rtable_get(struct ip_tunnel *t, u32 cookie) | |||
| 119 | return (struct rtable *)dst; | 120 | return (struct rtable *)dst; |
| 120 | } | 121 | } |
| 121 | 122 | ||
| 122 | /* Often modified stats are per cpu, other are shared (netdev->stats) */ | ||
| 123 | struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, | ||
| 124 | struct rtnl_link_stats64 *tot) | ||
| 125 | { | ||
| 126 | int i; | ||
| 127 | |||
| 128 | for_each_possible_cpu(i) { | ||
| 129 | const struct pcpu_sw_netstats *tstats = | ||
| 130 | per_cpu_ptr(dev->tstats, i); | ||
| 131 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | ||
| 132 | unsigned int start; | ||
| 133 | |||
| 134 | do { | ||
| 135 | start = u64_stats_fetch_begin_bh(&tstats->syncp); | ||
| 136 | rx_packets = tstats->rx_packets; | ||
| 137 | tx_packets = tstats->tx_packets; | ||
| 138 | rx_bytes = tstats->rx_bytes; | ||
| 139 | tx_bytes = tstats->tx_bytes; | ||
| 140 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
| 141 | |||
| 142 | tot->rx_packets += rx_packets; | ||
| 143 | tot->tx_packets += tx_packets; | ||
| 144 | tot->rx_bytes += rx_bytes; | ||
| 145 | tot->tx_bytes += tx_bytes; | ||
| 146 | } | ||
| 147 | |||
| 148 | tot->multicast = dev->stats.multicast; | ||
| 149 | |||
| 150 | tot->rx_crc_errors = dev->stats.rx_crc_errors; | ||
| 151 | tot->rx_fifo_errors = dev->stats.rx_fifo_errors; | ||
| 152 | tot->rx_length_errors = dev->stats.rx_length_errors; | ||
| 153 | tot->rx_frame_errors = dev->stats.rx_frame_errors; | ||
| 154 | tot->rx_errors = dev->stats.rx_errors; | ||
| 155 | |||
| 156 | tot->tx_fifo_errors = dev->stats.tx_fifo_errors; | ||
| 157 | tot->tx_carrier_errors = dev->stats.tx_carrier_errors; | ||
| 158 | tot->tx_dropped = dev->stats.tx_dropped; | ||
| 159 | tot->tx_aborted_errors = dev->stats.tx_aborted_errors; | ||
| 160 | tot->tx_errors = dev->stats.tx_errors; | ||
| 161 | |||
| 162 | tot->collisions = dev->stats.collisions; | ||
| 163 | |||
| 164 | return tot; | ||
| 165 | } | ||
| 166 | EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); | ||
| 167 | |||
| 168 | static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, | 123 | static bool ip_tunnel_key_match(const struct ip_tunnel_parm *p, |
| 169 | __be16 flags, __be32 key) | 124 | __be16 flags, __be32 key) |
| 170 | { | 125 | { |
| @@ -759,7 +714,7 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn, | |||
| 759 | if (set_mtu) | 714 | if (set_mtu) |
| 760 | dev->mtu = mtu; | 715 | dev->mtu = mtu; |
| 761 | } | 716 | } |
| 762 | tunnel_dst_reset_all(t); | 717 | ip_tunnel_dst_reset_all(t); |
| 763 | netdev_state_change(dev); | 718 | netdev_state_change(dev); |
| 764 | } | 719 | } |
| 765 | 720 | ||
| @@ -1088,7 +1043,7 @@ void ip_tunnel_uninit(struct net_device *dev) | |||
| 1088 | if (itn->fb_tunnel_dev != dev) | 1043 | if (itn->fb_tunnel_dev != dev) |
| 1089 | ip_tunnel_del(netdev_priv(dev)); | 1044 | ip_tunnel_del(netdev_priv(dev)); |
| 1090 | 1045 | ||
| 1091 | tunnel_dst_reset_all(tunnel); | 1046 | ip_tunnel_dst_reset_all(tunnel); |
| 1092 | } | 1047 | } |
| 1093 | EXPORT_SYMBOL_GPL(ip_tunnel_uninit); | 1048 | EXPORT_SYMBOL_GPL(ip_tunnel_uninit); |
| 1094 | 1049 | ||
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c index 6156f4ef5e91..6f847dd56dbc 100644 --- a/net/ipv4/ip_tunnel_core.c +++ b/net/ipv4/ip_tunnel_core.c | |||
| @@ -108,7 +108,6 @@ int iptunnel_pull_header(struct sk_buff *skb, int hdr_len, __be16 inner_proto) | |||
| 108 | nf_reset(skb); | 108 | nf_reset(skb); |
| 109 | secpath_reset(skb); | 109 | secpath_reset(skb); |
| 110 | skb_clear_hash_if_not_l4(skb); | 110 | skb_clear_hash_if_not_l4(skb); |
| 111 | skb_dst_drop(skb); | ||
| 112 | skb->vlan_tci = 0; | 111 | skb->vlan_tci = 0; |
| 113 | skb_set_queue_mapping(skb, 0); | 112 | skb_set_queue_mapping(skb, 0); |
| 114 | skb->pkt_type = PACKET_HOST; | 113 | skb->pkt_type = PACKET_HOST; |
| @@ -148,3 +147,49 @@ error: | |||
| 148 | return ERR_PTR(err); | 147 | return ERR_PTR(err); |
| 149 | } | 148 | } |
| 150 | EXPORT_SYMBOL_GPL(iptunnel_handle_offloads); | 149 | EXPORT_SYMBOL_GPL(iptunnel_handle_offloads); |
| 150 | |||
| 151 | /* Often modified stats are per cpu, other are shared (netdev->stats) */ | ||
| 152 | struct rtnl_link_stats64 *ip_tunnel_get_stats64(struct net_device *dev, | ||
| 153 | struct rtnl_link_stats64 *tot) | ||
| 154 | { | ||
| 155 | int i; | ||
| 156 | |||
| 157 | for_each_possible_cpu(i) { | ||
| 158 | const struct pcpu_sw_netstats *tstats = | ||
| 159 | per_cpu_ptr(dev->tstats, i); | ||
| 160 | u64 rx_packets, rx_bytes, tx_packets, tx_bytes; | ||
| 161 | unsigned int start; | ||
| 162 | |||
| 163 | do { | ||
| 164 | start = u64_stats_fetch_begin_bh(&tstats->syncp); | ||
| 165 | rx_packets = tstats->rx_packets; | ||
| 166 | tx_packets = tstats->tx_packets; | ||
| 167 | rx_bytes = tstats->rx_bytes; | ||
| 168 | tx_bytes = tstats->tx_bytes; | ||
| 169 | } while (u64_stats_fetch_retry_bh(&tstats->syncp, start)); | ||
| 170 | |||
| 171 | tot->rx_packets += rx_packets; | ||
| 172 | tot->tx_packets += tx_packets; | ||
| 173 | tot->rx_bytes += rx_bytes; | ||
| 174 | tot->tx_bytes += tx_bytes; | ||
| 175 | } | ||
| 176 | |||
| 177 | tot->multicast = dev->stats.multicast; | ||
| 178 | |||
| 179 | tot->rx_crc_errors = dev->stats.rx_crc_errors; | ||
| 180 | tot->rx_fifo_errors = dev->stats.rx_fifo_errors; | ||
| 181 | tot->rx_length_errors = dev->stats.rx_length_errors; | ||
| 182 | tot->rx_frame_errors = dev->stats.rx_frame_errors; | ||
| 183 | tot->rx_errors = dev->stats.rx_errors; | ||
| 184 | |||
| 185 | tot->tx_fifo_errors = dev->stats.tx_fifo_errors; | ||
| 186 | tot->tx_carrier_errors = dev->stats.tx_carrier_errors; | ||
| 187 | tot->tx_dropped = dev->stats.tx_dropped; | ||
| 188 | tot->tx_aborted_errors = dev->stats.tx_aborted_errors; | ||
| 189 | tot->tx_errors = dev->stats.tx_errors; | ||
| 190 | |||
| 191 | tot->collisions = dev->stats.collisions; | ||
| 192 | |||
| 193 | return tot; | ||
| 194 | } | ||
| 195 | EXPORT_SYMBOL_GPL(ip_tunnel_get_stats64); | ||
diff --git a/net/ipv4/netfilter/nf_nat_snmp_basic.c b/net/ipv4/netfilter/nf_nat_snmp_basic.c index d551e31b416e..7c676671329d 100644 --- a/net/ipv4/netfilter/nf_nat_snmp_basic.c +++ b/net/ipv4/netfilter/nf_nat_snmp_basic.c | |||
| @@ -1198,8 +1198,8 @@ static int snmp_translate(struct nf_conn *ct, | |||
| 1198 | map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); | 1198 | map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); |
| 1199 | } else { | 1199 | } else { |
| 1200 | /* DNAT replies */ | 1200 | /* DNAT replies */ |
| 1201 | map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip); | 1201 | map.from = NOCT1(&ct->tuplehash[!dir].tuple.src.u3.ip); |
| 1202 | map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); | 1202 | map.to = NOCT1(&ct->tuplehash[dir].tuple.dst.u3.ip); |
| 1203 | } | 1203 | } |
| 1204 | 1204 | ||
| 1205 | if (map.from == map.to) | 1205 | if (map.from == map.to) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9f3a2db9109e..97c8f5620c43 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -1044,7 +1044,8 @@ void tcp_free_fastopen_req(struct tcp_sock *tp) | |||
| 1044 | } | 1044 | } |
| 1045 | } | 1045 | } |
| 1046 | 1046 | ||
| 1047 | static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size) | 1047 | static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, |
| 1048 | int *copied, size_t size) | ||
| 1048 | { | 1049 | { |
| 1049 | struct tcp_sock *tp = tcp_sk(sk); | 1050 | struct tcp_sock *tp = tcp_sk(sk); |
| 1050 | int err, flags; | 1051 | int err, flags; |
| @@ -1059,11 +1060,12 @@ static int tcp_sendmsg_fastopen(struct sock *sk, struct msghdr *msg, int *size) | |||
| 1059 | if (unlikely(tp->fastopen_req == NULL)) | 1060 | if (unlikely(tp->fastopen_req == NULL)) |
| 1060 | return -ENOBUFS; | 1061 | return -ENOBUFS; |
| 1061 | tp->fastopen_req->data = msg; | 1062 | tp->fastopen_req->data = msg; |
| 1063 | tp->fastopen_req->size = size; | ||
| 1062 | 1064 | ||
| 1063 | flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0; | 1065 | flags = (msg->msg_flags & MSG_DONTWAIT) ? O_NONBLOCK : 0; |
| 1064 | err = __inet_stream_connect(sk->sk_socket, msg->msg_name, | 1066 | err = __inet_stream_connect(sk->sk_socket, msg->msg_name, |
| 1065 | msg->msg_namelen, flags); | 1067 | msg->msg_namelen, flags); |
| 1066 | *size = tp->fastopen_req->copied; | 1068 | *copied = tp->fastopen_req->copied; |
| 1067 | tcp_free_fastopen_req(tp); | 1069 | tcp_free_fastopen_req(tp); |
| 1068 | return err; | 1070 | return err; |
| 1069 | } | 1071 | } |
| @@ -1083,7 +1085,7 @@ int tcp_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 1083 | 1085 | ||
| 1084 | flags = msg->msg_flags; | 1086 | flags = msg->msg_flags; |
| 1085 | if (flags & MSG_FASTOPEN) { | 1087 | if (flags & MSG_FASTOPEN) { |
| 1086 | err = tcp_sendmsg_fastopen(sk, msg, &copied_syn); | 1088 | err = tcp_sendmsg_fastopen(sk, msg, &copied_syn, size); |
| 1087 | if (err == -EINPROGRESS && copied_syn > 0) | 1089 | if (err == -EINPROGRESS && copied_syn > 0) |
| 1088 | goto out; | 1090 | goto out; |
| 1089 | else if (err) | 1091 | else if (err) |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index ad37bf18ae4b..2388275adb9b 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -290,8 +290,7 @@ bool tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight) | |||
| 290 | left = tp->snd_cwnd - in_flight; | 290 | left = tp->snd_cwnd - in_flight; |
| 291 | if (sk_can_gso(sk) && | 291 | if (sk_can_gso(sk) && |
| 292 | left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && | 292 | left * sysctl_tcp_tso_win_divisor < tp->snd_cwnd && |
| 293 | left * tp->mss_cache < sk->sk_gso_max_size && | 293 | left < tp->xmit_size_goal_segs) |
| 294 | left < sk->sk_gso_max_segs) | ||
| 295 | return true; | 294 | return true; |
| 296 | return left <= tcp_max_tso_deferred_mss(tp); | 295 | return left <= tcp_max_tso_deferred_mss(tp); |
| 297 | } | 296 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 227cba79fa6b..eeaac399420d 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -1945,8 +1945,9 @@ void tcp_enter_loss(struct sock *sk, int how) | |||
| 1945 | if (skb == tcp_send_head(sk)) | 1945 | if (skb == tcp_send_head(sk)) |
| 1946 | break; | 1946 | break; |
| 1947 | 1947 | ||
| 1948 | if (TCP_SKB_CB(skb)->sacked & TCPCB_RETRANS) | 1948 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) |
| 1949 | tp->undo_marker = 0; | 1949 | tp->undo_marker = 0; |
| 1950 | |||
| 1950 | TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; | 1951 | TCP_SKB_CB(skb)->sacked &= (~TCPCB_TAGBITS)|TCPCB_SACKED_ACKED; |
| 1951 | if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) { | 1952 | if (!(TCP_SKB_CB(skb)->sacked&TCPCB_SACKED_ACKED) || how) { |
| 1952 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; | 1953 | TCP_SKB_CB(skb)->sacked &= ~TCPCB_SACKED_ACKED; |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 3be16727f058..f0eb4e337ec8 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
| @@ -864,8 +864,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it, | |||
| 864 | 864 | ||
| 865 | if (unlikely(skb->fclone == SKB_FCLONE_ORIG && | 865 | if (unlikely(skb->fclone == SKB_FCLONE_ORIG && |
| 866 | fclone->fclone == SKB_FCLONE_CLONE)) | 866 | fclone->fclone == SKB_FCLONE_CLONE)) |
| 867 | NET_INC_STATS_BH(sock_net(sk), | 867 | NET_INC_STATS(sock_net(sk), |
| 868 | LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES); | 868 | LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES); |
| 869 | 869 | ||
| 870 | if (unlikely(skb_cloned(skb))) | 870 | if (unlikely(skb_cloned(skb))) |
| 871 | skb = pskb_copy(skb, gfp_mask); | 871 | skb = pskb_copy(skb, gfp_mask); |
| @@ -2337,6 +2337,7 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2337 | struct tcp_sock *tp = tcp_sk(sk); | 2337 | struct tcp_sock *tp = tcp_sk(sk); |
| 2338 | struct inet_connection_sock *icsk = inet_csk(sk); | 2338 | struct inet_connection_sock *icsk = inet_csk(sk); |
| 2339 | unsigned int cur_mss; | 2339 | unsigned int cur_mss; |
| 2340 | int err; | ||
| 2340 | 2341 | ||
| 2341 | /* Inconslusive MTU probe */ | 2342 | /* Inconslusive MTU probe */ |
| 2342 | if (icsk->icsk_mtup.probe_size) { | 2343 | if (icsk->icsk_mtup.probe_size) { |
| @@ -2400,11 +2401,15 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
| 2400 | skb_headroom(skb) >= 0xFFFF)) { | 2401 | skb_headroom(skb) >= 0xFFFF)) { |
| 2401 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2402 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
| 2402 | GFP_ATOMIC); | 2403 | GFP_ATOMIC); |
| 2403 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2404 | err = nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
| 2404 | -ENOBUFS; | 2405 | -ENOBUFS; |
| 2405 | } else { | 2406 | } else { |
| 2406 | return tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2407 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
| 2407 | } | 2408 | } |
| 2409 | |||
| 2410 | if (likely(!err)) | ||
| 2411 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; | ||
| 2412 | return err; | ||
| 2408 | } | 2413 | } |
| 2409 | 2414 | ||
| 2410 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | 2415 | int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) |
| @@ -2908,7 +2913,12 @@ static int tcp_send_syn_data(struct sock *sk, struct sk_buff *syn) | |||
| 2908 | space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) - | 2913 | space = __tcp_mtu_to_mss(sk, inet_csk(sk)->icsk_pmtu_cookie) - |
| 2909 | MAX_TCP_OPTION_SPACE; | 2914 | MAX_TCP_OPTION_SPACE; |
| 2910 | 2915 | ||
| 2911 | syn_data = skb_copy_expand(syn, skb_headroom(syn), space, | 2916 | space = min_t(size_t, space, fo->size); |
| 2917 | |||
| 2918 | /* limit to order-0 allocations */ | ||
| 2919 | space = min_t(size_t, space, SKB_MAX_HEAD(MAX_TCP_HEADER)); | ||
| 2920 | |||
| 2921 | syn_data = skb_copy_expand(syn, MAX_TCP_HEADER, space, | ||
| 2912 | sk->sk_allocation); | 2922 | sk->sk_allocation); |
| 2913 | if (syn_data == NULL) | 2923 | if (syn_data == NULL) |
| 2914 | goto fallback; | 2924 | goto fallback; |
diff --git a/net/ipv6/Kconfig b/net/ipv6/Kconfig index d92e5586783e..438a73aa777c 100644 --- a/net/ipv6/Kconfig +++ b/net/ipv6/Kconfig | |||
| @@ -138,6 +138,7 @@ config INET6_XFRM_MODE_ROUTEOPTIMIZATION | |||
| 138 | config IPV6_VTI | 138 | config IPV6_VTI |
| 139 | tristate "Virtual (secure) IPv6: tunneling" | 139 | tristate "Virtual (secure) IPv6: tunneling" |
| 140 | select IPV6_TUNNEL | 140 | select IPV6_TUNNEL |
| 141 | select NET_IP_TUNNEL | ||
| 141 | depends on INET6_XFRM_MODE_TUNNEL | 142 | depends on INET6_XFRM_MODE_TUNNEL |
| 142 | ---help--- | 143 | ---help--- |
| 143 | Tunneling means encapsulating data of one protocol type within | 144 | Tunneling means encapsulating data of one protocol type within |
diff --git a/net/ipv6/exthdrs_core.c b/net/ipv6/exthdrs_core.c index 140748debc4a..8af3eb57f438 100644 --- a/net/ipv6/exthdrs_core.c +++ b/net/ipv6/exthdrs_core.c | |||
| @@ -212,7 +212,7 @@ int ipv6_find_hdr(const struct sk_buff *skb, unsigned int *offset, | |||
| 212 | found = (nexthdr == target); | 212 | found = (nexthdr == target); |
| 213 | 213 | ||
| 214 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { | 214 | if ((!ipv6_ext_hdr(nexthdr)) || nexthdr == NEXTHDR_NONE) { |
| 215 | if (target < 0) | 215 | if (target < 0 || found) |
| 216 | break; | 216 | break; |
| 217 | return -ENOENT; | 217 | return -ENOENT; |
| 218 | } | 218 | } |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 1e8683b135bb..59f95affceb0 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
| @@ -89,7 +89,7 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 89 | unsigned int unfrag_ip6hlen; | 89 | unsigned int unfrag_ip6hlen; |
| 90 | u8 *prevhdr; | 90 | u8 *prevhdr; |
| 91 | int offset = 0; | 91 | int offset = 0; |
| 92 | bool tunnel; | 92 | bool encap, udpfrag; |
| 93 | int nhoff; | 93 | int nhoff; |
| 94 | 94 | ||
| 95 | if (unlikely(skb_shinfo(skb)->gso_type & | 95 | if (unlikely(skb_shinfo(skb)->gso_type & |
| @@ -110,8 +110,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 110 | if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) | 110 | if (unlikely(!pskb_may_pull(skb, sizeof(*ipv6h)))) |
| 111 | goto out; | 111 | goto out; |
| 112 | 112 | ||
| 113 | tunnel = SKB_GSO_CB(skb)->encap_level > 0; | 113 | encap = SKB_GSO_CB(skb)->encap_level > 0; |
| 114 | if (tunnel) | 114 | if (encap) |
| 115 | features = skb->dev->hw_enc_features & netif_skb_features(skb); | 115 | features = skb->dev->hw_enc_features & netif_skb_features(skb); |
| 116 | SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h); | 116 | SKB_GSO_CB(skb)->encap_level += sizeof(*ipv6h); |
| 117 | 117 | ||
| @@ -121,6 +121,12 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 121 | 121 | ||
| 122 | proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr); | 122 | proto = ipv6_gso_pull_exthdrs(skb, ipv6h->nexthdr); |
| 123 | 123 | ||
| 124 | if (skb->encapsulation && | ||
| 125 | skb_shinfo(skb)->gso_type & (SKB_GSO_SIT|SKB_GSO_IPIP)) | ||
| 126 | udpfrag = proto == IPPROTO_UDP && encap; | ||
| 127 | else | ||
| 128 | udpfrag = proto == IPPROTO_UDP && !skb->encapsulation; | ||
| 129 | |||
| 124 | ops = rcu_dereference(inet6_offloads[proto]); | 130 | ops = rcu_dereference(inet6_offloads[proto]); |
| 125 | if (likely(ops && ops->callbacks.gso_segment)) { | 131 | if (likely(ops && ops->callbacks.gso_segment)) { |
| 126 | skb_reset_transport_header(skb); | 132 | skb_reset_transport_header(skb); |
| @@ -133,13 +139,9 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 133 | for (skb = segs; skb; skb = skb->next) { | 139 | for (skb = segs; skb; skb = skb->next) { |
| 134 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); | 140 | ipv6h = (struct ipv6hdr *)(skb_mac_header(skb) + nhoff); |
| 135 | ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h)); | 141 | ipv6h->payload_len = htons(skb->len - nhoff - sizeof(*ipv6h)); |
| 136 | if (tunnel) { | ||
| 137 | skb_reset_inner_headers(skb); | ||
| 138 | skb->encapsulation = 1; | ||
| 139 | } | ||
| 140 | skb->network_header = (u8 *)ipv6h - skb->head; | 142 | skb->network_header = (u8 *)ipv6h - skb->head; |
| 141 | 143 | ||
| 142 | if (!tunnel && proto == IPPROTO_UDP) { | 144 | if (udpfrag) { |
| 143 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | 145 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
| 144 | fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); | 146 | fptr = (struct frag_hdr *)((u8 *)ipv6h + unfrag_ip6hlen); |
| 145 | fptr->frag_off = htons(offset); | 147 | fptr->frag_off = htons(offset); |
| @@ -148,6 +150,8 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 148 | offset += (ntohs(ipv6h->payload_len) - | 150 | offset += (ntohs(ipv6h->payload_len) - |
| 149 | sizeof(struct frag_hdr)); | 151 | sizeof(struct frag_hdr)); |
| 150 | } | 152 | } |
| 153 | if (encap) | ||
| 154 | skb_reset_inner_headers(skb); | ||
| 151 | } | 155 | } |
| 152 | 156 | ||
| 153 | out: | 157 | out: |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 070a2fae2375..16f91a2e7888 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -530,9 +530,6 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
| 530 | to->tc_index = from->tc_index; | 530 | to->tc_index = from->tc_index; |
| 531 | #endif | 531 | #endif |
| 532 | nf_copy(to, from); | 532 | nf_copy(to, from); |
| 533 | #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) | ||
| 534 | to->nf_trace = from->nf_trace; | ||
| 535 | #endif | ||
| 536 | skb_copy_secmark(to, from); | 533 | skb_copy_secmark(to, from); |
| 537 | } | 534 | } |
| 538 | 535 | ||
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index fb9beb78f00b..587bbdcb22b4 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
| @@ -135,6 +135,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 135 | fl6.flowi6_proto = IPPROTO_ICMPV6; | 135 | fl6.flowi6_proto = IPPROTO_ICMPV6; |
| 136 | fl6.saddr = np->saddr; | 136 | fl6.saddr = np->saddr; |
| 137 | fl6.daddr = *daddr; | 137 | fl6.daddr = *daddr; |
| 138 | fl6.flowi6_mark = sk->sk_mark; | ||
| 138 | fl6.fl6_icmp_type = user_icmph.icmp6_type; | 139 | fl6.fl6_icmp_type = user_icmph.icmp6_type; |
| 139 | fl6.fl6_icmp_code = user_icmph.icmp6_code; | 140 | fl6.fl6_icmp_code = user_icmph.icmp6_code; |
| 140 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); | 141 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index 3dfbcf1dcb1c..b4d74c86586c 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -475,6 +475,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev) | |||
| 475 | ipip6_tunnel_unlink(sitn, tunnel); | 475 | ipip6_tunnel_unlink(sitn, tunnel); |
| 476 | ipip6_tunnel_del_prl(tunnel, NULL); | 476 | ipip6_tunnel_del_prl(tunnel, NULL); |
| 477 | } | 477 | } |
| 478 | ip_tunnel_dst_reset_all(tunnel); | ||
| 478 | dev_put(dev); | 479 | dev_put(dev); |
| 479 | } | 480 | } |
| 480 | 481 | ||
| @@ -1082,6 +1083,7 @@ static void ipip6_tunnel_update(struct ip_tunnel *t, struct ip_tunnel_parm *p) | |||
| 1082 | t->parms.link = p->link; | 1083 | t->parms.link = p->link; |
| 1083 | ipip6_tunnel_bind_dev(t->dev); | 1084 | ipip6_tunnel_bind_dev(t->dev); |
| 1084 | } | 1085 | } |
| 1086 | ip_tunnel_dst_reset_all(t); | ||
| 1085 | netdev_state_change(t->dev); | 1087 | netdev_state_change(t->dev); |
| 1086 | } | 1088 | } |
| 1087 | 1089 | ||
| @@ -1112,6 +1114,7 @@ static int ipip6_tunnel_update_6rd(struct ip_tunnel *t, | |||
| 1112 | t->ip6rd.relay_prefix = relay_prefix; | 1114 | t->ip6rd.relay_prefix = relay_prefix; |
| 1113 | t->ip6rd.prefixlen = ip6rd->prefixlen; | 1115 | t->ip6rd.prefixlen = ip6rd->prefixlen; |
| 1114 | t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; | 1116 | t->ip6rd.relay_prefixlen = ip6rd->relay_prefixlen; |
| 1117 | ip_tunnel_dst_reset_all(t); | ||
| 1115 | netdev_state_change(t->dev); | 1118 | netdev_state_change(t->dev); |
| 1116 | return 0; | 1119 | return 0; |
| 1117 | } | 1120 | } |
| @@ -1271,6 +1274,7 @@ ipip6_tunnel_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1271 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); | 1274 | err = ipip6_tunnel_add_prl(t, &prl, cmd == SIOCCHGPRL); |
| 1272 | break; | 1275 | break; |
| 1273 | } | 1276 | } |
| 1277 | ip_tunnel_dst_reset_all(t); | ||
| 1274 | netdev_state_change(dev); | 1278 | netdev_state_change(dev); |
| 1275 | break; | 1279 | break; |
| 1276 | 1280 | ||
| @@ -1326,6 +1330,9 @@ static const struct net_device_ops ipip6_netdev_ops = { | |||
| 1326 | 1330 | ||
| 1327 | static void ipip6_dev_free(struct net_device *dev) | 1331 | static void ipip6_dev_free(struct net_device *dev) |
| 1328 | { | 1332 | { |
| 1333 | struct ip_tunnel *tunnel = netdev_priv(dev); | ||
| 1334 | |||
| 1335 | free_percpu(tunnel->dst_cache); | ||
| 1329 | free_percpu(dev->tstats); | 1336 | free_percpu(dev->tstats); |
| 1330 | free_netdev(dev); | 1337 | free_netdev(dev); |
| 1331 | } | 1338 | } |
| @@ -1375,6 +1382,12 @@ static int ipip6_tunnel_init(struct net_device *dev) | |||
| 1375 | u64_stats_init(&ipip6_tunnel_stats->syncp); | 1382 | u64_stats_init(&ipip6_tunnel_stats->syncp); |
| 1376 | } | 1383 | } |
| 1377 | 1384 | ||
| 1385 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | ||
| 1386 | if (!tunnel->dst_cache) { | ||
| 1387 | free_percpu(dev->tstats); | ||
| 1388 | return -ENOMEM; | ||
| 1389 | } | ||
| 1390 | |||
| 1378 | return 0; | 1391 | return 0; |
| 1379 | } | 1392 | } |
| 1380 | 1393 | ||
| @@ -1405,6 +1418,12 @@ static int __net_init ipip6_fb_tunnel_init(struct net_device *dev) | |||
| 1405 | u64_stats_init(&ipip6_fb_stats->syncp); | 1418 | u64_stats_init(&ipip6_fb_stats->syncp); |
| 1406 | } | 1419 | } |
| 1407 | 1420 | ||
| 1421 | tunnel->dst_cache = alloc_percpu(struct ip_tunnel_dst); | ||
| 1422 | if (!tunnel->dst_cache) { | ||
| 1423 | free_percpu(dev->tstats); | ||
| 1424 | return -ENOMEM; | ||
| 1425 | } | ||
| 1426 | |||
| 1408 | dev_hold(dev); | 1427 | dev_hold(dev); |
| 1409 | rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); | 1428 | rcu_assign_pointer(sitn->tunnels_wc[0], tunnel); |
| 1410 | return 0; | 1429 | return 0; |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index e7359f9eaa8d..b261ee8b83fc 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
| @@ -113,7 +113,7 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
| 113 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); | 113 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); |
| 114 | fptr->nexthdr = nexthdr; | 114 | fptr->nexthdr = nexthdr; |
| 115 | fptr->reserved = 0; | 115 | fptr->reserved = 0; |
| 116 | ipv6_select_ident(fptr, (struct rt6_info *)skb_dst(skb)); | 116 | fptr->identification = skb_shinfo(skb)->ip6_frag_id; |
| 117 | 117 | ||
| 118 | /* Fragment the skb. ipv6 header and the remaining fields of the | 118 | /* Fragment the skb. ipv6 header and the remaining fields of the |
| 119 | * fragment header are updated in ipv6_gso_segment() | 119 | * fragment header are updated in ipv6_gso_segment() |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3701930c6649..5e44e3179e02 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1692,14 +1692,8 @@ void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, | |||
| 1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); | 1692 | void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue); |
| 1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, | 1693 | void ieee80211_add_pending_skb(struct ieee80211_local *local, |
| 1694 | struct sk_buff *skb); | 1694 | struct sk_buff *skb); |
| 1695 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 1695 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
| 1696 | struct sk_buff_head *skbs, | 1696 | struct sk_buff_head *skbs); |
| 1697 | void (*fn)(void *data), void *data); | ||
| 1698 | static inline void ieee80211_add_pending_skbs(struct ieee80211_local *local, | ||
| 1699 | struct sk_buff_head *skbs) | ||
| 1700 | { | ||
| 1701 | ieee80211_add_pending_skbs_fn(local, skbs, NULL, NULL); | ||
| 1702 | } | ||
| 1703 | void ieee80211_flush_queues(struct ieee80211_local *local, | 1697 | void ieee80211_flush_queues(struct ieee80211_local *local, |
| 1704 | struct ieee80211_sub_if_data *sdata); | 1698 | struct ieee80211_sub_if_data *sdata); |
| 1705 | 1699 | ||
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index fc1d82465b3c..245dce969b31 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -222,6 +222,7 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
| 222 | switch (vht_oper->chan_width) { | 222 | switch (vht_oper->chan_width) { |
| 223 | case IEEE80211_VHT_CHANWIDTH_USE_HT: | 223 | case IEEE80211_VHT_CHANWIDTH_USE_HT: |
| 224 | vht_chandef.width = chandef->width; | 224 | vht_chandef.width = chandef->width; |
| 225 | vht_chandef.center_freq1 = chandef->center_freq1; | ||
| 225 | break; | 226 | break; |
| 226 | case IEEE80211_VHT_CHANWIDTH_80MHZ: | 227 | case IEEE80211_VHT_CHANWIDTH_80MHZ: |
| 227 | vht_chandef.width = NL80211_CHAN_WIDTH_80; | 228 | vht_chandef.width = NL80211_CHAN_WIDTH_80; |
| @@ -271,6 +272,28 @@ ieee80211_determine_chantype(struct ieee80211_sub_if_data *sdata, | |||
| 271 | ret = 0; | 272 | ret = 0; |
| 272 | 273 | ||
| 273 | out: | 274 | out: |
| 275 | /* | ||
| 276 | * When tracking the current AP, don't do any further checks if the | ||
| 277 | * new chandef is identical to the one we're currently using for the | ||
| 278 | * connection. This keeps us from playing ping-pong with regulatory, | ||
| 279 | * without it the following can happen (for example): | ||
| 280 | * - connect to an AP with 80 MHz, world regdom allows 80 MHz | ||
| 281 | * - AP advertises regdom US | ||
| 282 | * - CRDA loads regdom US with 80 MHz prohibited (old database) | ||
| 283 | * - the code below detects an unsupported channel, downgrades, and | ||
| 284 | * we disconnect from the AP in the caller | ||
| 285 | * - disconnect causes CRDA to reload world regdomain and the game | ||
| 286 | * starts anew. | ||
| 287 | * (see https://bugzilla.kernel.org/show_bug.cgi?id=70881) | ||
| 288 | * | ||
| 289 | * It seems possible that there are still scenarios with CSA or real | ||
| 290 | * bandwidth changes where a this could happen, but those cases are | ||
| 291 | * less common and wouldn't completely prevent using the AP. | ||
| 292 | */ | ||
| 293 | if (tracking && | ||
| 294 | cfg80211_chandef_identical(chandef, &sdata->vif.bss_conf.chandef)) | ||
| 295 | return ret; | ||
| 296 | |||
| 274 | /* don't print the message below for VHT mismatch if VHT is disabled */ | 297 | /* don't print the message below for VHT mismatch if VHT is disabled */ |
| 275 | if (ret & IEEE80211_STA_DISABLE_VHT) | 298 | if (ret & IEEE80211_STA_DISABLE_VHT) |
| 276 | vht_chandef = *chandef; | 299 | vht_chandef = *chandef; |
| @@ -3753,6 +3776,7 @@ static int ieee80211_prep_connection(struct ieee80211_sub_if_data *sdata, | |||
| 3753 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); | 3776 | chanctx_conf = rcu_dereference(sdata->vif.chanctx_conf); |
| 3754 | if (WARN_ON(!chanctx_conf)) { | 3777 | if (WARN_ON(!chanctx_conf)) { |
| 3755 | rcu_read_unlock(); | 3778 | rcu_read_unlock(); |
| 3779 | sta_info_free(local, new_sta); | ||
| 3756 | return -EINVAL; | 3780 | return -EINVAL; |
| 3757 | } | 3781 | } |
| 3758 | rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); | 3782 | rate_flags = ieee80211_chandef_rate_flags(&chanctx_conf->def); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index c24ca0d0f469..3e57f96c9666 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1128,6 +1128,13 @@ static void sta_ps_end(struct sta_info *sta) | |||
| 1128 | sta->sta.addr, sta->sta.aid); | 1128 | sta->sta.addr, sta->sta.aid); |
| 1129 | 1129 | ||
| 1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | 1130 | if (test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { |
| 1131 | /* | ||
| 1132 | * Clear the flag only if the other one is still set | ||
| 1133 | * so that the TX path won't start TX'ing new frames | ||
| 1134 | * directly ... In the case that the driver flag isn't | ||
| 1135 | * set ieee80211_sta_ps_deliver_wakeup() will clear it. | ||
| 1136 | */ | ||
| 1137 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
| 1131 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", | 1138 | ps_dbg(sta->sdata, "STA %pM aid %d driver-ps-blocked\n", |
| 1132 | sta->sta.addr, sta->sta.aid); | 1139 | sta->sta.addr, sta->sta.aid); |
| 1133 | return; | 1140 | return; |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index decd30c1e290..a023b432143b 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -91,7 +91,7 @@ static int sta_info_hash_del(struct ieee80211_local *local, | |||
| 91 | return -ENOENT; | 91 | return -ENOENT; |
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | static void cleanup_single_sta(struct sta_info *sta) | 94 | static void __cleanup_single_sta(struct sta_info *sta) |
| 95 | { | 95 | { |
| 96 | int ac, i; | 96 | int ac, i; |
| 97 | struct tid_ampdu_tx *tid_tx; | 97 | struct tid_ampdu_tx *tid_tx; |
| @@ -99,7 +99,8 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 99 | struct ieee80211_local *local = sdata->local; | 99 | struct ieee80211_local *local = sdata->local; |
| 100 | struct ps_data *ps; | 100 | struct ps_data *ps; |
| 101 | 101 | ||
| 102 | if (test_sta_flag(sta, WLAN_STA_PS_STA)) { | 102 | if (test_sta_flag(sta, WLAN_STA_PS_STA) || |
| 103 | test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | ||
| 103 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || | 104 | if (sta->sdata->vif.type == NL80211_IFTYPE_AP || |
| 104 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | 105 | sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN) |
| 105 | ps = &sdata->bss->ps; | 106 | ps = &sdata->bss->ps; |
| @@ -109,6 +110,7 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 109 | return; | 110 | return; |
| 110 | 111 | ||
| 111 | clear_sta_flag(sta, WLAN_STA_PS_STA); | 112 | clear_sta_flag(sta, WLAN_STA_PS_STA); |
| 113 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 112 | 114 | ||
| 113 | atomic_dec(&ps->num_sta_ps); | 115 | atomic_dec(&ps->num_sta_ps); |
| 114 | sta_info_recalc_tim(sta); | 116 | sta_info_recalc_tim(sta); |
| @@ -139,7 +141,14 @@ static void cleanup_single_sta(struct sta_info *sta) | |||
| 139 | ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); | 141 | ieee80211_purge_tx_queue(&local->hw, &tid_tx->pending); |
| 140 | kfree(tid_tx); | 142 | kfree(tid_tx); |
| 141 | } | 143 | } |
| 144 | } | ||
| 142 | 145 | ||
| 146 | static void cleanup_single_sta(struct sta_info *sta) | ||
| 147 | { | ||
| 148 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
| 149 | struct ieee80211_local *local = sdata->local; | ||
| 150 | |||
| 151 | __cleanup_single_sta(sta); | ||
| 143 | sta_info_free(local, sta); | 152 | sta_info_free(local, sta); |
| 144 | } | 153 | } |
| 145 | 154 | ||
| @@ -330,6 +339,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata, | |||
| 330 | rcu_read_unlock(); | 339 | rcu_read_unlock(); |
| 331 | 340 | ||
| 332 | spin_lock_init(&sta->lock); | 341 | spin_lock_init(&sta->lock); |
| 342 | spin_lock_init(&sta->ps_lock); | ||
| 333 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); | 343 | INIT_WORK(&sta->drv_unblock_wk, sta_unblock); |
| 334 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); | 344 | INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work); |
| 335 | mutex_init(&sta->ampdu_mlme.mtx); | 345 | mutex_init(&sta->ampdu_mlme.mtx); |
| @@ -487,21 +497,26 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
| 487 | goto out_err; | 497 | goto out_err; |
| 488 | } | 498 | } |
| 489 | 499 | ||
| 490 | /* notify driver */ | ||
| 491 | err = sta_info_insert_drv_state(local, sdata, sta); | ||
| 492 | if (err) | ||
| 493 | goto out_err; | ||
| 494 | |||
| 495 | local->num_sta++; | 500 | local->num_sta++; |
| 496 | local->sta_generation++; | 501 | local->sta_generation++; |
| 497 | smp_mb(); | 502 | smp_mb(); |
| 498 | 503 | ||
| 504 | /* simplify things and don't accept BA sessions yet */ | ||
| 505 | set_sta_flag(sta, WLAN_STA_BLOCK_BA); | ||
| 506 | |||
| 499 | /* make the station visible */ | 507 | /* make the station visible */ |
| 500 | sta_info_hash_add(local, sta); | 508 | sta_info_hash_add(local, sta); |
| 501 | 509 | ||
| 502 | list_add_rcu(&sta->list, &local->sta_list); | 510 | list_add_rcu(&sta->list, &local->sta_list); |
| 503 | 511 | ||
| 512 | /* notify driver */ | ||
| 513 | err = sta_info_insert_drv_state(local, sdata, sta); | ||
| 514 | if (err) | ||
| 515 | goto out_remove; | ||
| 516 | |||
| 504 | set_sta_flag(sta, WLAN_STA_INSERTED); | 517 | set_sta_flag(sta, WLAN_STA_INSERTED); |
| 518 | /* accept BA sessions now */ | ||
| 519 | clear_sta_flag(sta, WLAN_STA_BLOCK_BA); | ||
| 505 | 520 | ||
| 506 | ieee80211_recalc_min_chandef(sdata); | 521 | ieee80211_recalc_min_chandef(sdata); |
| 507 | ieee80211_sta_debugfs_add(sta); | 522 | ieee80211_sta_debugfs_add(sta); |
| @@ -522,6 +537,12 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU) | |||
| 522 | mesh_accept_plinks_update(sdata); | 537 | mesh_accept_plinks_update(sdata); |
| 523 | 538 | ||
| 524 | return 0; | 539 | return 0; |
| 540 | out_remove: | ||
| 541 | sta_info_hash_del(local, sta); | ||
| 542 | list_del_rcu(&sta->list); | ||
| 543 | local->num_sta--; | ||
| 544 | synchronize_net(); | ||
| 545 | __cleanup_single_sta(sta); | ||
| 525 | out_err: | 546 | out_err: |
| 526 | mutex_unlock(&local->sta_mtx); | 547 | mutex_unlock(&local->sta_mtx); |
| 527 | rcu_read_lock(); | 548 | rcu_read_lock(); |
| @@ -1071,10 +1092,14 @@ struct ieee80211_sta *ieee80211_find_sta(struct ieee80211_vif *vif, | |||
| 1071 | } | 1092 | } |
| 1072 | EXPORT_SYMBOL(ieee80211_find_sta); | 1093 | EXPORT_SYMBOL(ieee80211_find_sta); |
| 1073 | 1094 | ||
| 1074 | static void clear_sta_ps_flags(void *_sta) | 1095 | /* powersave support code */ |
| 1096 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
| 1075 | { | 1097 | { |
| 1076 | struct sta_info *sta = _sta; | ||
| 1077 | struct ieee80211_sub_if_data *sdata = sta->sdata; | 1098 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 1099 | struct ieee80211_local *local = sdata->local; | ||
| 1100 | struct sk_buff_head pending; | ||
| 1101 | int filtered = 0, buffered = 0, ac; | ||
| 1102 | unsigned long flags; | ||
| 1078 | struct ps_data *ps; | 1103 | struct ps_data *ps; |
| 1079 | 1104 | ||
| 1080 | if (sdata->vif.type == NL80211_IFTYPE_AP || | 1105 | if (sdata->vif.type == NL80211_IFTYPE_AP || |
| @@ -1085,20 +1110,6 @@ static void clear_sta_ps_flags(void *_sta) | |||
| 1085 | else | 1110 | else |
| 1086 | return; | 1111 | return; |
| 1087 | 1112 | ||
| 1088 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 1089 | if (test_and_clear_sta_flag(sta, WLAN_STA_PS_STA)) | ||
| 1090 | atomic_dec(&ps->num_sta_ps); | ||
| 1091 | } | ||
| 1092 | |||
| 1093 | /* powersave support code */ | ||
| 1094 | void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | ||
| 1095 | { | ||
| 1096 | struct ieee80211_sub_if_data *sdata = sta->sdata; | ||
| 1097 | struct ieee80211_local *local = sdata->local; | ||
| 1098 | struct sk_buff_head pending; | ||
| 1099 | int filtered = 0, buffered = 0, ac; | ||
| 1100 | unsigned long flags; | ||
| 1101 | |||
| 1102 | clear_sta_flag(sta, WLAN_STA_SP); | 1113 | clear_sta_flag(sta, WLAN_STA_SP); |
| 1103 | 1114 | ||
| 1104 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); | 1115 | BUILD_BUG_ON(BITS_TO_LONGS(IEEE80211_NUM_TIDS) > 1); |
| @@ -1109,6 +1120,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 1109 | 1120 | ||
| 1110 | skb_queue_head_init(&pending); | 1121 | skb_queue_head_init(&pending); |
| 1111 | 1122 | ||
| 1123 | /* sync with ieee80211_tx_h_unicast_ps_buf */ | ||
| 1124 | spin_lock(&sta->ps_lock); | ||
| 1112 | /* Send all buffered frames to the station */ | 1125 | /* Send all buffered frames to the station */ |
| 1113 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | 1126 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { |
| 1114 | int count = skb_queue_len(&pending), tmp; | 1127 | int count = skb_queue_len(&pending), tmp; |
| @@ -1127,7 +1140,12 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta) | |||
| 1127 | buffered += tmp - count; | 1140 | buffered += tmp - count; |
| 1128 | } | 1141 | } |
| 1129 | 1142 | ||
| 1130 | ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta); | 1143 | ieee80211_add_pending_skbs(local, &pending); |
| 1144 | clear_sta_flag(sta, WLAN_STA_PS_DRIVER); | ||
| 1145 | clear_sta_flag(sta, WLAN_STA_PS_STA); | ||
| 1146 | spin_unlock(&sta->ps_lock); | ||
| 1147 | |||
| 1148 | atomic_dec(&ps->num_sta_ps); | ||
| 1131 | 1149 | ||
| 1132 | /* This station just woke up and isn't aware of our SMPS state */ | 1150 | /* This station just woke up and isn't aware of our SMPS state */ |
| 1133 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, | 1151 | if (!ieee80211_smps_is_restrictive(sta->known_smps_mode, |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index d77ff7090630..d3a6d8208f2f 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat { | |||
| 267 | * @drv_unblock_wk: used for driver PS unblocking | 267 | * @drv_unblock_wk: used for driver PS unblocking |
| 268 | * @listen_interval: listen interval of this station, when we're acting as AP | 268 | * @listen_interval: listen interval of this station, when we're acting as AP |
| 269 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly | 269 | * @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly |
| 270 | * @ps_lock: used for powersave (when mac80211 is the AP) related locking | ||
| 270 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station | 271 | * @ps_tx_buf: buffers (per AC) of frames to transmit to this station |
| 271 | * when it leaves power saving state or polls | 272 | * when it leaves power saving state or polls |
| 272 | * @tx_filtered: buffers (per AC) of frames we already tried to | 273 | * @tx_filtered: buffers (per AC) of frames we already tried to |
| @@ -356,10 +357,8 @@ struct sta_info { | |||
| 356 | /* use the accessors defined below */ | 357 | /* use the accessors defined below */ |
| 357 | unsigned long _flags; | 358 | unsigned long _flags; |
| 358 | 359 | ||
| 359 | /* | 360 | /* STA powersave lock and frame queues */ |
| 360 | * STA powersave frame queues, no more than the internal | 361 | spinlock_t ps_lock; |
| 361 | * locking required. | ||
| 362 | */ | ||
| 363 | struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; | 362 | struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS]; |
| 364 | struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; | 363 | struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS]; |
| 365 | unsigned long driver_buffered_tids; | 364 | unsigned long driver_buffered_tids; |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 97a02d3f7d87..4080c615636f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -478,6 +478,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 478 | sta->sta.addr, sta->sta.aid, ac); | 478 | sta->sta.addr, sta->sta.aid, ac); |
| 479 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) | 479 | if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER) |
| 480 | purge_old_ps_buffers(tx->local); | 480 | purge_old_ps_buffers(tx->local); |
| 481 | |||
| 482 | /* sync with ieee80211_sta_ps_deliver_wakeup */ | ||
| 483 | spin_lock(&sta->ps_lock); | ||
| 484 | /* | ||
| 485 | * STA woke up the meantime and all the frames on ps_tx_buf have | ||
| 486 | * been queued to pending queue. No reordering can happen, go | ||
| 487 | * ahead and Tx the packet. | ||
| 488 | */ | ||
| 489 | if (!test_sta_flag(sta, WLAN_STA_PS_STA) && | ||
| 490 | !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) { | ||
| 491 | spin_unlock(&sta->ps_lock); | ||
| 492 | return TX_CONTINUE; | ||
| 493 | } | ||
| 494 | |||
| 481 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { | 495 | if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) { |
| 482 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); | 496 | struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]); |
| 483 | ps_dbg(tx->sdata, | 497 | ps_dbg(tx->sdata, |
| @@ -492,6 +506,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx) | |||
| 492 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; | 506 | info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; |
| 493 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; | 507 | info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS; |
| 494 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); | 508 | skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb); |
| 509 | spin_unlock(&sta->ps_lock); | ||
| 495 | 510 | ||
| 496 | if (!timer_pending(&local->sta_cleanup)) | 511 | if (!timer_pending(&local->sta_cleanup)) |
| 497 | mod_timer(&local->sta_cleanup, | 512 | mod_timer(&local->sta_cleanup, |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 676dc0967f37..b8700d417a9c 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -435,9 +435,8 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local, | |||
| 435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); | 435 | spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); |
| 436 | } | 436 | } |
| 437 | 437 | ||
| 438 | void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | 438 | void ieee80211_add_pending_skbs(struct ieee80211_local *local, |
| 439 | struct sk_buff_head *skbs, | 439 | struct sk_buff_head *skbs) |
| 440 | void (*fn)(void *data), void *data) | ||
| 441 | { | 440 | { |
| 442 | struct ieee80211_hw *hw = &local->hw; | 441 | struct ieee80211_hw *hw = &local->hw; |
| 443 | struct sk_buff *skb; | 442 | struct sk_buff *skb; |
| @@ -461,9 +460,6 @@ void ieee80211_add_pending_skbs_fn(struct ieee80211_local *local, | |||
| 461 | __skb_queue_tail(&local->pending[queue], skb); | 460 | __skb_queue_tail(&local->pending[queue], skb); |
| 462 | } | 461 | } |
| 463 | 462 | ||
| 464 | if (fn) | ||
| 465 | fn(data); | ||
| 466 | |||
| 467 | for (i = 0; i < hw->queues; i++) | 463 | for (i = 0; i < hw->queues; i++) |
| 468 | __ieee80211_wake_queue(hw, i, | 464 | __ieee80211_wake_queue(hw, i, |
| 469 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); | 465 | IEEE80211_QUEUE_STOP_REASON_SKB_ADD); |
| @@ -1741,6 +1737,26 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1741 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); | 1737 | IEEE80211_QUEUE_STOP_REASON_SUSPEND); |
| 1742 | 1738 | ||
| 1743 | /* | 1739 | /* |
| 1740 | * Reconfigure sched scan if it was interrupted by FW restart or | ||
| 1741 | * suspend. | ||
| 1742 | */ | ||
| 1743 | mutex_lock(&local->mtx); | ||
| 1744 | sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, | ||
| 1745 | lockdep_is_held(&local->mtx)); | ||
| 1746 | if (sched_scan_sdata && local->sched_scan_req) | ||
| 1747 | /* | ||
| 1748 | * Sched scan stopped, but we don't want to report it. Instead, | ||
| 1749 | * we're trying to reschedule. | ||
| 1750 | */ | ||
| 1751 | if (__ieee80211_request_sched_scan_start(sched_scan_sdata, | ||
| 1752 | local->sched_scan_req)) | ||
| 1753 | sched_scan_stopped = true; | ||
| 1754 | mutex_unlock(&local->mtx); | ||
| 1755 | |||
| 1756 | if (sched_scan_stopped) | ||
| 1757 | cfg80211_sched_scan_stopped(local->hw.wiphy); | ||
| 1758 | |||
| 1759 | /* | ||
| 1744 | * If this is for hw restart things are still running. | 1760 | * If this is for hw restart things are still running. |
| 1745 | * We may want to change that later, however. | 1761 | * We may want to change that later, however. |
| 1746 | */ | 1762 | */ |
| @@ -1768,26 +1784,6 @@ int ieee80211_reconfig(struct ieee80211_local *local) | |||
| 1768 | WARN_ON(1); | 1784 | WARN_ON(1); |
| 1769 | #endif | 1785 | #endif |
| 1770 | 1786 | ||
| 1771 | /* | ||
| 1772 | * Reconfigure sched scan if it was interrupted by FW restart or | ||
| 1773 | * suspend. | ||
| 1774 | */ | ||
| 1775 | mutex_lock(&local->mtx); | ||
| 1776 | sched_scan_sdata = rcu_dereference_protected(local->sched_scan_sdata, | ||
| 1777 | lockdep_is_held(&local->mtx)); | ||
| 1778 | if (sched_scan_sdata && local->sched_scan_req) | ||
| 1779 | /* | ||
| 1780 | * Sched scan stopped, but we don't want to report it. Instead, | ||
| 1781 | * we're trying to reschedule. | ||
| 1782 | */ | ||
| 1783 | if (__ieee80211_request_sched_scan_start(sched_scan_sdata, | ||
| 1784 | local->sched_scan_req)) | ||
| 1785 | sched_scan_stopped = true; | ||
| 1786 | mutex_unlock(&local->mtx); | ||
| 1787 | |||
| 1788 | if (sched_scan_stopped) | ||
| 1789 | cfg80211_sched_scan_stopped(local->hw.wiphy); | ||
| 1790 | |||
| 1791 | return 0; | 1787 | return 0; |
| 1792 | } | 1788 | } |
| 1793 | 1789 | ||
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c index 21211c60ca98..d51422c778de 100644 --- a/net/mac80211/wme.c +++ b/net/mac80211/wme.c | |||
| @@ -154,6 +154,11 @@ u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, | |||
| 154 | return IEEE80211_AC_BE; | 154 | return IEEE80211_AC_BE; |
| 155 | } | 155 | } |
| 156 | 156 | ||
| 157 | if (skb->protocol == sdata->control_port_protocol) { | ||
| 158 | skb->priority = 7; | ||
| 159 | return ieee80211_downgrade_queue(sdata, skb); | ||
| 160 | } | ||
| 161 | |||
| 157 | /* use the data classifier to determine what 802.1d tag the | 162 | /* use the data classifier to determine what 802.1d tag the |
| 158 | * data frame has */ | 163 | * data frame has */ |
| 159 | rcu_read_lock(); | 164 | rcu_read_lock(); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index bb322d0beb48..b9f0e0374322 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -1310,27 +1310,22 @@ ctnetlink_change_status(struct nf_conn *ct, const struct nlattr * const cda[]) | |||
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | static int | 1312 | static int |
| 1313 | ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[]) | 1313 | ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[]) |
| 1314 | { | 1314 | { |
| 1315 | #ifdef CONFIG_NF_NAT_NEEDED | 1315 | #ifdef CONFIG_NF_NAT_NEEDED |
| 1316 | int ret; | 1316 | int ret; |
| 1317 | 1317 | ||
| 1318 | if (cda[CTA_NAT_DST]) { | 1318 | ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST, |
| 1319 | ret = ctnetlink_parse_nat_setup(ct, | 1319 | cda[CTA_NAT_DST]); |
| 1320 | NF_NAT_MANIP_DST, | 1320 | if (ret < 0) |
| 1321 | cda[CTA_NAT_DST]); | 1321 | return ret; |
| 1322 | if (ret < 0) | 1322 | |
| 1323 | return ret; | 1323 | ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_SRC, |
| 1324 | } | 1324 | cda[CTA_NAT_SRC]); |
| 1325 | if (cda[CTA_NAT_SRC]) { | 1325 | return ret; |
| 1326 | ret = ctnetlink_parse_nat_setup(ct, | ||
| 1327 | NF_NAT_MANIP_SRC, | ||
| 1328 | cda[CTA_NAT_SRC]); | ||
| 1329 | if (ret < 0) | ||
| 1330 | return ret; | ||
| 1331 | } | ||
| 1332 | return 0; | ||
| 1333 | #else | 1326 | #else |
| 1327 | if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC]) | ||
| 1328 | return 0; | ||
| 1334 | return -EOPNOTSUPP; | 1329 | return -EOPNOTSUPP; |
| 1335 | #endif | 1330 | #endif |
| 1336 | } | 1331 | } |
| @@ -1659,11 +1654,9 @@ ctnetlink_create_conntrack(struct net *net, u16 zone, | |||
| 1659 | goto err2; | 1654 | goto err2; |
| 1660 | } | 1655 | } |
| 1661 | 1656 | ||
| 1662 | if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { | 1657 | err = ctnetlink_setup_nat(ct, cda); |
| 1663 | err = ctnetlink_change_nat(ct, cda); | 1658 | if (err < 0) |
| 1664 | if (err < 0) | 1659 | goto err2; |
| 1665 | goto err2; | ||
| 1666 | } | ||
| 1667 | 1660 | ||
| 1668 | nf_ct_acct_ext_add(ct, GFP_ATOMIC); | 1661 | nf_ct_acct_ext_add(ct, GFP_ATOMIC); |
| 1669 | nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); | 1662 | nf_ct_tstamp_ext_add(ct, GFP_ATOMIC); |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index d3f5cd6dd962..52ca952b802c 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
| @@ -432,15 +432,15 @@ nf_nat_setup_info(struct nf_conn *ct, | |||
| 432 | } | 432 | } |
| 433 | EXPORT_SYMBOL(nf_nat_setup_info); | 433 | EXPORT_SYMBOL(nf_nat_setup_info); |
| 434 | 434 | ||
| 435 | unsigned int | 435 | static unsigned int |
| 436 | nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) | 436 | __nf_nat_alloc_null_binding(struct nf_conn *ct, enum nf_nat_manip_type manip) |
| 437 | { | 437 | { |
| 438 | /* Force range to this IP; let proto decide mapping for | 438 | /* Force range to this IP; let proto decide mapping for |
| 439 | * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). | 439 | * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). |
| 440 | * Use reply in case it's already been mangled (eg local packet). | 440 | * Use reply in case it's already been mangled (eg local packet). |
| 441 | */ | 441 | */ |
| 442 | union nf_inet_addr ip = | 442 | union nf_inet_addr ip = |
| 443 | (HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ? | 443 | (manip == NF_NAT_MANIP_SRC ? |
| 444 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3 : | 444 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3 : |
| 445 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3); | 445 | ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3); |
| 446 | struct nf_nat_range range = { | 446 | struct nf_nat_range range = { |
| @@ -448,7 +448,13 @@ nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) | |||
| 448 | .min_addr = ip, | 448 | .min_addr = ip, |
| 449 | .max_addr = ip, | 449 | .max_addr = ip, |
| 450 | }; | 450 | }; |
| 451 | return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); | 451 | return nf_nat_setup_info(ct, &range, manip); |
| 452 | } | ||
| 453 | |||
| 454 | unsigned int | ||
| 455 | nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) | ||
| 456 | { | ||
| 457 | return __nf_nat_alloc_null_binding(ct, HOOK2MANIP(hooknum)); | ||
| 452 | } | 458 | } |
| 453 | EXPORT_SYMBOL_GPL(nf_nat_alloc_null_binding); | 459 | EXPORT_SYMBOL_GPL(nf_nat_alloc_null_binding); |
| 454 | 460 | ||
| @@ -702,9 +708,9 @@ static const struct nla_policy nat_nla_policy[CTA_NAT_MAX+1] = { | |||
| 702 | 708 | ||
| 703 | static int | 709 | static int |
| 704 | nfnetlink_parse_nat(const struct nlattr *nat, | 710 | nfnetlink_parse_nat(const struct nlattr *nat, |
| 705 | const struct nf_conn *ct, struct nf_nat_range *range) | 711 | const struct nf_conn *ct, struct nf_nat_range *range, |
| 712 | const struct nf_nat_l3proto *l3proto) | ||
| 706 | { | 713 | { |
| 707 | const struct nf_nat_l3proto *l3proto; | ||
| 708 | struct nlattr *tb[CTA_NAT_MAX+1]; | 714 | struct nlattr *tb[CTA_NAT_MAX+1]; |
| 709 | int err; | 715 | int err; |
| 710 | 716 | ||
| @@ -714,38 +720,46 @@ nfnetlink_parse_nat(const struct nlattr *nat, | |||
| 714 | if (err < 0) | 720 | if (err < 0) |
| 715 | return err; | 721 | return err; |
| 716 | 722 | ||
| 717 | rcu_read_lock(); | ||
| 718 | l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct)); | ||
| 719 | if (l3proto == NULL) { | ||
| 720 | err = -EAGAIN; | ||
| 721 | goto out; | ||
| 722 | } | ||
| 723 | err = l3proto->nlattr_to_range(tb, range); | 723 | err = l3proto->nlattr_to_range(tb, range); |
| 724 | if (err < 0) | 724 | if (err < 0) |
| 725 | goto out; | 725 | return err; |
| 726 | 726 | ||
| 727 | if (!tb[CTA_NAT_PROTO]) | 727 | if (!tb[CTA_NAT_PROTO]) |
| 728 | goto out; | 728 | return 0; |
| 729 | 729 | ||
| 730 | err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range); | 730 | return nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range); |
| 731 | out: | ||
| 732 | rcu_read_unlock(); | ||
| 733 | return err; | ||
| 734 | } | 731 | } |
| 735 | 732 | ||
| 733 | /* This function is called under rcu_read_lock() */ | ||
| 736 | static int | 734 | static int |
| 737 | nfnetlink_parse_nat_setup(struct nf_conn *ct, | 735 | nfnetlink_parse_nat_setup(struct nf_conn *ct, |
| 738 | enum nf_nat_manip_type manip, | 736 | enum nf_nat_manip_type manip, |
| 739 | const struct nlattr *attr) | 737 | const struct nlattr *attr) |
| 740 | { | 738 | { |
| 741 | struct nf_nat_range range; | 739 | struct nf_nat_range range; |
| 740 | const struct nf_nat_l3proto *l3proto; | ||
| 742 | int err; | 741 | int err; |
| 743 | 742 | ||
| 744 | err = nfnetlink_parse_nat(attr, ct, &range); | 743 | /* Should not happen, restricted to creating new conntracks |
| 744 | * via ctnetlink. | ||
| 745 | */ | ||
| 746 | if (WARN_ON_ONCE(nf_nat_initialized(ct, manip))) | ||
| 747 | return -EEXIST; | ||
| 748 | |||
| 749 | /* Make sure that L3 NAT is there by when we call nf_nat_setup_info to | ||
| 750 | * attach the null binding, otherwise this may oops. | ||
| 751 | */ | ||
| 752 | l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct)); | ||
| 753 | if (l3proto == NULL) | ||
| 754 | return -EAGAIN; | ||
| 755 | |||
| 756 | /* No NAT information has been passed, allocate the null-binding */ | ||
| 757 | if (attr == NULL) | ||
| 758 | return __nf_nat_alloc_null_binding(ct, manip); | ||
| 759 | |||
| 760 | err = nfnetlink_parse_nat(attr, ct, &range, l3proto); | ||
| 745 | if (err < 0) | 761 | if (err < 0) |
| 746 | return err; | 762 | return err; |
| 747 | if (nf_nat_initialized(ct, manip)) | ||
| 748 | return -EEXIST; | ||
| 749 | 763 | ||
| 750 | return nf_nat_setup_info(ct, &range, manip); | 764 | return nf_nat_setup_info(ct, &range, manip); |
| 751 | } | 765 | } |
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c index e8254ad2e5a9..425cf39af890 100644 --- a/net/netfilter/nft_meta.c +++ b/net/netfilter/nft_meta.c | |||
| @@ -116,7 +116,7 @@ static void nft_meta_get_eval(const struct nft_expr *expr, | |||
| 116 | skb->sk->sk_socket->file->f_cred->fsgid); | 116 | skb->sk->sk_socket->file->f_cred->fsgid); |
| 117 | read_unlock_bh(&skb->sk->sk_callback_lock); | 117 | read_unlock_bh(&skb->sk->sk_callback_lock); |
| 118 | break; | 118 | break; |
| 119 | #ifdef CONFIG_NET_CLS_ROUTE | 119 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 120 | case NFT_META_RTCLASSID: { | 120 | case NFT_META_RTCLASSID: { |
| 121 | const struct dst_entry *dst = skb_dst(skb); | 121 | const struct dst_entry *dst = skb_dst(skb); |
| 122 | 122 | ||
| @@ -199,7 +199,7 @@ static int nft_meta_init_validate_get(uint32_t key) | |||
| 199 | case NFT_META_OIFTYPE: | 199 | case NFT_META_OIFTYPE: |
| 200 | case NFT_META_SKUID: | 200 | case NFT_META_SKUID: |
| 201 | case NFT_META_SKGID: | 201 | case NFT_META_SKGID: |
| 202 | #ifdef CONFIG_NET_CLS_ROUTE | 202 | #ifdef CONFIG_IP_ROUTE_CLASSID |
| 203 | case NFT_META_RTCLASSID: | 203 | case NFT_META_RTCLASSID: |
| 204 | #endif | 204 | #endif |
| 205 | #ifdef CONFIG_NETWORK_SECMARK | 205 | #ifdef CONFIG_NETWORK_SECMARK |
diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c index a2aeb318678f..85daa84bfdfe 100644 --- a/net/netfilter/nft_payload.c +++ b/net/netfilter/nft_payload.c | |||
| @@ -135,7 +135,8 @@ nft_payload_select_ops(const struct nft_ctx *ctx, | |||
| 135 | if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data)) | 135 | if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data)) |
| 136 | return ERR_PTR(-EINVAL); | 136 | return ERR_PTR(-EINVAL); |
| 137 | 137 | ||
| 138 | if (len <= 4 && IS_ALIGNED(offset, len) && base != NFT_PAYLOAD_LL_HEADER) | 138 | if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) && |
| 139 | base != NFT_PAYLOAD_LL_HEADER) | ||
| 139 | return &nft_payload_fast_ops; | 140 | return &nft_payload_fast_ops; |
| 140 | else | 141 | else |
| 141 | return &nft_payload_ops; | 142 | return &nft_payload_ops; |
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c index 8a310f239c93..b718a52a4654 100644 --- a/net/netfilter/nft_reject_inet.c +++ b/net/netfilter/nft_reject_inet.c | |||
| @@ -21,9 +21,9 @@ static void nft_reject_inet_eval(const struct nft_expr *expr, | |||
| 21 | { | 21 | { |
| 22 | switch (pkt->ops->pf) { | 22 | switch (pkt->ops->pf) { |
| 23 | case NFPROTO_IPV4: | 23 | case NFPROTO_IPV4: |
| 24 | nft_reject_ipv4_eval(expr, data, pkt); | 24 | return nft_reject_ipv4_eval(expr, data, pkt); |
| 25 | case NFPROTO_IPV6: | 25 | case NFPROTO_IPV6: |
| 26 | nft_reject_ipv6_eval(expr, data, pkt); | 26 | return nft_reject_ipv6_eval(expr, data, pkt); |
| 27 | } | 27 | } |
| 28 | } | 28 | } |
| 29 | 29 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index fdf51353cf78..04748ab649c2 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -1489,8 +1489,8 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, | |||
| 1489 | if (addr->sa_family != AF_NETLINK) | 1489 | if (addr->sa_family != AF_NETLINK) |
| 1490 | return -EINVAL; | 1490 | return -EINVAL; |
| 1491 | 1491 | ||
| 1492 | /* Only superuser is allowed to send multicasts */ | 1492 | if ((nladdr->nl_groups || nladdr->nl_pid) && |
| 1493 | if (nladdr->nl_groups && !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) | 1493 | !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) |
| 1494 | return -EPERM; | 1494 | return -EPERM; |
| 1495 | 1495 | ||
| 1496 | if (!nlk->portid) | 1496 | if (!nlk->portid) |
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c index 46bda010bf11..56db888b1cd5 100644 --- a/net/nfc/nci/core.c +++ b/net/nfc/nci/core.c | |||
| @@ -301,7 +301,7 @@ static int nci_open_device(struct nci_dev *ndev) | |||
| 301 | rc = __nci_request(ndev, nci_reset_req, 0, | 301 | rc = __nci_request(ndev, nci_reset_req, 0, |
| 302 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); | 302 | msecs_to_jiffies(NCI_RESET_TIMEOUT)); |
| 303 | 303 | ||
| 304 | if (ndev->ops->setup(ndev)) | 304 | if (ndev->ops->setup) |
| 305 | ndev->ops->setup(ndev); | 305 | ndev->ops->setup(ndev); |
| 306 | 306 | ||
| 307 | if (!rc) { | 307 | if (!rc) { |
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 1cb413fead89..4f505a006896 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
| @@ -334,18 +334,6 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 334 | qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, | 334 | qdisc_put_rtab(qdisc_get_rtab(&qopt->peakrate, |
| 335 | tb[TCA_TBF_PTAB])); | 335 | tb[TCA_TBF_PTAB])); |
| 336 | 336 | ||
| 337 | if (q->qdisc != &noop_qdisc) { | ||
| 338 | err = fifo_set_limit(q->qdisc, qopt->limit); | ||
| 339 | if (err) | ||
| 340 | goto done; | ||
| 341 | } else if (qopt->limit > 0) { | ||
| 342 | child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit); | ||
| 343 | if (IS_ERR(child)) { | ||
| 344 | err = PTR_ERR(child); | ||
| 345 | goto done; | ||
| 346 | } | ||
| 347 | } | ||
| 348 | |||
| 349 | buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U); | 337 | buffer = min_t(u64, PSCHED_TICKS2NS(qopt->buffer), ~0U); |
| 350 | mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); | 338 | mtu = min_t(u64, PSCHED_TICKS2NS(qopt->mtu), ~0U); |
| 351 | 339 | ||
| @@ -390,6 +378,18 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
| 390 | goto done; | 378 | goto done; |
| 391 | } | 379 | } |
| 392 | 380 | ||
| 381 | if (q->qdisc != &noop_qdisc) { | ||
| 382 | err = fifo_set_limit(q->qdisc, qopt->limit); | ||
| 383 | if (err) | ||
| 384 | goto done; | ||
| 385 | } else if (qopt->limit > 0) { | ||
| 386 | child = fifo_create_dflt(sch, &bfifo_qdisc_ops, qopt->limit); | ||
| 387 | if (IS_ERR(child)) { | ||
| 388 | err = PTR_ERR(child); | ||
| 389 | goto done; | ||
| 390 | } | ||
| 391 | } | ||
| 392 | |||
| 393 | sch_tree_lock(sch); | 393 | sch_tree_lock(sch); |
| 394 | if (child) { | 394 | if (child) { |
| 395 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); | 395 | qdisc_tree_decrease_qlen(q->qdisc, q->qdisc->q.qlen); |
diff --git a/net/sctp/associola.c b/net/sctp/associola.c index f558433537b8..ee13d28d39d1 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c | |||
| @@ -1239,78 +1239,107 @@ void sctp_assoc_update(struct sctp_association *asoc, | |||
| 1239 | } | 1239 | } |
| 1240 | 1240 | ||
| 1241 | /* Update the retran path for sending a retransmitted packet. | 1241 | /* Update the retran path for sending a retransmitted packet. |
| 1242 | * Round-robin through the active transports, else round-robin | 1242 | * See also RFC4960, 6.4. Multi-Homed SCTP Endpoints: |
| 1243 | * through the inactive transports as this is the next best thing | 1243 | * |
| 1244 | * we can try. | 1244 | * When there is outbound data to send and the primary path |
| 1245 | * becomes inactive (e.g., due to failures), or where the | ||
| 1246 | * SCTP user explicitly requests to send data to an | ||
| 1247 | * inactive destination transport address, before reporting | ||
| 1248 | * an error to its ULP, the SCTP endpoint should try to send | ||
| 1249 | * the data to an alternate active destination transport | ||
| 1250 | * address if one exists. | ||
| 1251 | * | ||
| 1252 | * When retransmitting data that timed out, if the endpoint | ||
| 1253 | * is multihomed, it should consider each source-destination | ||
| 1254 | * address pair in its retransmission selection policy. | ||
| 1255 | * When retransmitting timed-out data, the endpoint should | ||
| 1256 | * attempt to pick the most divergent source-destination | ||
| 1257 | * pair from the original source-destination pair to which | ||
| 1258 | * the packet was transmitted. | ||
| 1259 | * | ||
| 1260 | * Note: Rules for picking the most divergent source-destination | ||
| 1261 | * pair are an implementation decision and are not specified | ||
| 1262 | * within this document. | ||
| 1263 | * | ||
| 1264 | * Our basic strategy is to round-robin transports in priorities | ||
| 1265 | * according to sctp_state_prio_map[] e.g., if no such | ||
| 1266 | * transport with state SCTP_ACTIVE exists, round-robin through | ||
| 1267 | * SCTP_UNKNOWN, etc. You get the picture. | ||
| 1245 | */ | 1268 | */ |
| 1246 | void sctp_assoc_update_retran_path(struct sctp_association *asoc) | 1269 | static const u8 sctp_trans_state_to_prio_map[] = { |
| 1270 | [SCTP_ACTIVE] = 3, /* best case */ | ||
| 1271 | [SCTP_UNKNOWN] = 2, | ||
| 1272 | [SCTP_PF] = 1, | ||
| 1273 | [SCTP_INACTIVE] = 0, /* worst case */ | ||
| 1274 | }; | ||
| 1275 | |||
| 1276 | static u8 sctp_trans_score(const struct sctp_transport *trans) | ||
| 1247 | { | 1277 | { |
| 1248 | struct sctp_transport *t, *next; | 1278 | return sctp_trans_state_to_prio_map[trans->state]; |
| 1249 | struct list_head *head = &asoc->peer.transport_addr_list; | 1279 | } |
| 1250 | struct list_head *pos; | ||
| 1251 | 1280 | ||
| 1252 | if (asoc->peer.transport_count == 1) | 1281 | static struct sctp_transport *sctp_trans_elect_best(struct sctp_transport *curr, |
| 1253 | return; | 1282 | struct sctp_transport *best) |
| 1283 | { | ||
| 1284 | if (best == NULL) | ||
| 1285 | return curr; | ||
| 1254 | 1286 | ||
| 1255 | /* Find the next transport in a round-robin fashion. */ | 1287 | return sctp_trans_score(curr) > sctp_trans_score(best) ? curr : best; |
| 1256 | t = asoc->peer.retran_path; | 1288 | } |
| 1257 | pos = &t->transports; | ||
| 1258 | next = NULL; | ||
| 1259 | 1289 | ||
| 1260 | while (1) { | 1290 | void sctp_assoc_update_retran_path(struct sctp_association *asoc) |
| 1261 | /* Skip the head. */ | 1291 | { |
| 1262 | if (pos->next == head) | 1292 | struct sctp_transport *trans = asoc->peer.retran_path; |
| 1263 | pos = head->next; | 1293 | struct sctp_transport *trans_next = NULL; |
| 1264 | else | ||
| 1265 | pos = pos->next; | ||
| 1266 | 1294 | ||
| 1267 | t = list_entry(pos, struct sctp_transport, transports); | 1295 | /* We're done as we only have the one and only path. */ |
| 1296 | if (asoc->peer.transport_count == 1) | ||
| 1297 | return; | ||
| 1298 | /* If active_path and retran_path are the same and active, | ||
| 1299 | * then this is the only active path. Use it. | ||
| 1300 | */ | ||
| 1301 | if (asoc->peer.active_path == asoc->peer.retran_path && | ||
| 1302 | asoc->peer.active_path->state == SCTP_ACTIVE) | ||
| 1303 | return; | ||
| 1268 | 1304 | ||
| 1269 | /* We have exhausted the list, but didn't find any | 1305 | /* Iterate from retran_path's successor back to retran_path. */ |
| 1270 | * other active transports. If so, use the next | 1306 | for (trans = list_next_entry(trans, transports); 1; |
| 1271 | * transport. | 1307 | trans = list_next_entry(trans, transports)) { |
| 1272 | */ | 1308 | /* Manually skip the head element. */ |
| 1273 | if (t == asoc->peer.retran_path) { | 1309 | if (&trans->transports == &asoc->peer.transport_addr_list) |
| 1274 | t = next; | 1310 | continue; |
| 1311 | if (trans->state == SCTP_UNCONFIRMED) | ||
| 1312 | continue; | ||
| 1313 | trans_next = sctp_trans_elect_best(trans, trans_next); | ||
| 1314 | /* Active is good enough for immediate return. */ | ||
| 1315 | if (trans_next->state == SCTP_ACTIVE) | ||
| 1275 | break; | 1316 | break; |
| 1276 | } | 1317 | /* We've reached the end, time to update path. */ |
| 1277 | 1318 | if (trans == asoc->peer.retran_path) | |
| 1278 | /* Try to find an active transport. */ | ||
| 1279 | |||
| 1280 | if ((t->state == SCTP_ACTIVE) || | ||
| 1281 | (t->state == SCTP_UNKNOWN)) { | ||
| 1282 | break; | 1319 | break; |
| 1283 | } else { | ||
| 1284 | /* Keep track of the next transport in case | ||
| 1285 | * we don't find any active transport. | ||
| 1286 | */ | ||
| 1287 | if (t->state != SCTP_UNCONFIRMED && !next) | ||
| 1288 | next = t; | ||
| 1289 | } | ||
| 1290 | } | 1320 | } |
| 1291 | 1321 | ||
| 1292 | if (t) | 1322 | if (trans_next != NULL) |
| 1293 | asoc->peer.retran_path = t; | 1323 | asoc->peer.retran_path = trans_next; |
| 1294 | else | ||
| 1295 | t = asoc->peer.retran_path; | ||
| 1296 | 1324 | ||
| 1297 | pr_debug("%s: association:%p addr:%pISpc\n", __func__, asoc, | 1325 | pr_debug("%s: association:%p updated new path to addr:%pISpc\n", |
| 1298 | &t->ipaddr.sa); | 1326 | __func__, asoc, &asoc->peer.retran_path->ipaddr.sa); |
| 1299 | } | 1327 | } |
| 1300 | 1328 | ||
| 1301 | /* Choose the transport for sending retransmit packet. */ | 1329 | struct sctp_transport * |
| 1302 | struct sctp_transport *sctp_assoc_choose_alter_transport( | 1330 | sctp_assoc_choose_alter_transport(struct sctp_association *asoc, |
| 1303 | struct sctp_association *asoc, struct sctp_transport *last_sent_to) | 1331 | struct sctp_transport *last_sent_to) |
| 1304 | { | 1332 | { |
| 1305 | /* If this is the first time packet is sent, use the active path, | 1333 | /* If this is the first time packet is sent, use the active path, |
| 1306 | * else use the retran path. If the last packet was sent over the | 1334 | * else use the retran path. If the last packet was sent over the |
| 1307 | * retran path, update the retran path and use it. | 1335 | * retran path, update the retran path and use it. |
| 1308 | */ | 1336 | */ |
| 1309 | if (!last_sent_to) | 1337 | if (last_sent_to == NULL) { |
| 1310 | return asoc->peer.active_path; | 1338 | return asoc->peer.active_path; |
| 1311 | else { | 1339 | } else { |
| 1312 | if (last_sent_to == asoc->peer.retran_path) | 1340 | if (last_sent_to == asoc->peer.retran_path) |
| 1313 | sctp_assoc_update_retran_path(asoc); | 1341 | sctp_assoc_update_retran_path(asoc); |
| 1342 | |||
| 1314 | return asoc->peer.retran_path; | 1343 | return asoc->peer.retran_path; |
| 1315 | } | 1344 | } |
| 1316 | } | 1345 | } |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index bd859154000e..5d6883ff00c3 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -495,11 +495,12 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, | |||
| 495 | } | 495 | } |
| 496 | 496 | ||
| 497 | /* If the transport error count is greater than the pf_retrans | 497 | /* If the transport error count is greater than the pf_retrans |
| 498 | * threshold, and less than pathmaxrtx, then mark this transport | 498 | * threshold, and less than pathmaxrtx, and if the current state |
| 499 | * as Partially Failed, ee SCTP Quick Failover Draft, secon 5.1, | 499 | * is not SCTP_UNCONFIRMED, then mark this transport as Partially |
| 500 | * point 1 | 500 | * Failed, see SCTP Quick Failover Draft, section 5.1 |
| 501 | */ | 501 | */ |
| 502 | if ((transport->state != SCTP_PF) && | 502 | if ((transport->state != SCTP_PF) && |
| 503 | (transport->state != SCTP_UNCONFIRMED) && | ||
| 503 | (asoc->pf_retrans < transport->pathmaxrxt) && | 504 | (asoc->pf_retrans < transport->pathmaxrxt) && |
| 504 | (transport->error_count > asoc->pf_retrans)) { | 505 | (transport->error_count > asoc->pf_retrans)) { |
| 505 | 506 | ||
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index 591b44d3b7de..ae65b6b5973a 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -758,6 +758,13 @@ sctp_disposition_t sctp_sf_do_5_1D_ce(struct net *net, | |||
| 758 | struct sctp_chunk auth; | 758 | struct sctp_chunk auth; |
| 759 | sctp_ierror_t ret; | 759 | sctp_ierror_t ret; |
| 760 | 760 | ||
| 761 | /* Make sure that we and the peer are AUTH capable */ | ||
| 762 | if (!net->sctp.auth_enable || !new_asoc->peer.auth_capable) { | ||
| 763 | kfree_skb(chunk->auth_chunk); | ||
| 764 | sctp_association_free(new_asoc); | ||
| 765 | return sctp_sf_pdiscard(net, ep, asoc, type, arg, commands); | ||
| 766 | } | ||
| 767 | |||
| 761 | /* set-up our fake chunk so that we can process it */ | 768 | /* set-up our fake chunk so that we can process it */ |
| 762 | auth.skb = chunk->auth_chunk; | 769 | auth.skb = chunk->auth_chunk; |
| 763 | auth.asoc = chunk->asoc; | 770 | auth.asoc = chunk->asoc; |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index a38c89969c68..574b86193b15 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
| @@ -610,8 +610,13 @@ static struct notifier_block notifier = { | |||
| 610 | 610 | ||
| 611 | int tipc_bearer_setup(void) | 611 | int tipc_bearer_setup(void) |
| 612 | { | 612 | { |
| 613 | int err; | ||
| 614 | |||
| 615 | err = register_netdevice_notifier(¬ifier); | ||
| 616 | if (err) | ||
| 617 | return err; | ||
| 613 | dev_add_pack(&tipc_packet_type); | 618 | dev_add_pack(&tipc_packet_type); |
| 614 | return register_netdevice_notifier(¬ifier); | 619 | return 0; |
| 615 | } | 620 | } |
| 616 | 621 | ||
| 617 | void tipc_bearer_cleanup(void) | 622 | void tipc_bearer_cleanup(void) |
diff --git a/net/tipc/config.c b/net/tipc/config.c index c301a9a592d8..e74eef2e7490 100644 --- a/net/tipc/config.c +++ b/net/tipc/config.c | |||
| @@ -181,7 +181,7 @@ static struct sk_buff *cfg_set_own_addr(void) | |||
| 181 | if (tipc_own_addr) | 181 | if (tipc_own_addr) |
| 182 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED | 182 | return tipc_cfg_reply_error_string(TIPC_CFG_NOT_SUPPORTED |
| 183 | " (cannot change node address once assigned)"); | 183 | " (cannot change node address once assigned)"); |
| 184 | tipc_core_start_net(addr); | 184 | tipc_net_start(addr); |
| 185 | return tipc_cfg_reply_none(); | 185 | return tipc_cfg_reply_none(); |
| 186 | } | 186 | } |
| 187 | 187 | ||
diff --git a/net/tipc/core.c b/net/tipc/core.c index f9e88d8b04ca..80c20647b3d2 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
| @@ -77,37 +77,13 @@ struct sk_buff *tipc_buf_acquire(u32 size) | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | /** | 79 | /** |
| 80 | * tipc_core_stop_net - shut down TIPC networking sub-systems | ||
| 81 | */ | ||
| 82 | static void tipc_core_stop_net(void) | ||
| 83 | { | ||
| 84 | tipc_net_stop(); | ||
| 85 | tipc_bearer_cleanup(); | ||
| 86 | } | ||
| 87 | |||
| 88 | /** | ||
| 89 | * start_net - start TIPC networking sub-systems | ||
| 90 | */ | ||
| 91 | int tipc_core_start_net(unsigned long addr) | ||
| 92 | { | ||
| 93 | int res; | ||
| 94 | |||
| 95 | tipc_net_start(addr); | ||
| 96 | res = tipc_bearer_setup(); | ||
| 97 | if (res < 0) | ||
| 98 | goto err; | ||
| 99 | return res; | ||
| 100 | |||
| 101 | err: | ||
| 102 | tipc_core_stop_net(); | ||
| 103 | return res; | ||
| 104 | } | ||
| 105 | |||
| 106 | /** | ||
| 107 | * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode | 80 | * tipc_core_stop - switch TIPC from SINGLE NODE to NOT RUNNING mode |
| 108 | */ | 81 | */ |
| 109 | static void tipc_core_stop(void) | 82 | static void tipc_core_stop(void) |
| 110 | { | 83 | { |
| 84 | tipc_handler_stop(); | ||
| 85 | tipc_net_stop(); | ||
| 86 | tipc_bearer_cleanup(); | ||
| 111 | tipc_netlink_stop(); | 87 | tipc_netlink_stop(); |
| 112 | tipc_cfg_stop(); | 88 | tipc_cfg_stop(); |
| 113 | tipc_subscr_stop(); | 89 | tipc_subscr_stop(); |
| @@ -122,30 +98,65 @@ static void tipc_core_stop(void) | |||
| 122 | */ | 98 | */ |
| 123 | static int tipc_core_start(void) | 99 | static int tipc_core_start(void) |
| 124 | { | 100 | { |
| 125 | int res; | 101 | int err; |
| 126 | 102 | ||
| 127 | get_random_bytes(&tipc_random, sizeof(tipc_random)); | 103 | get_random_bytes(&tipc_random, sizeof(tipc_random)); |
| 128 | 104 | ||
| 129 | res = tipc_handler_start(); | 105 | err = tipc_handler_start(); |
| 130 | if (!res) | 106 | if (err) |
| 131 | res = tipc_ref_table_init(tipc_max_ports, tipc_random); | 107 | goto out_handler; |
| 132 | if (!res) | 108 | |
| 133 | res = tipc_nametbl_init(); | 109 | err = tipc_ref_table_init(tipc_max_ports, tipc_random); |
| 134 | if (!res) | 110 | if (err) |
| 135 | res = tipc_netlink_start(); | 111 | goto out_reftbl; |
| 136 | if (!res) | 112 | |
| 137 | res = tipc_socket_init(); | 113 | err = tipc_nametbl_init(); |
| 138 | if (!res) | 114 | if (err) |
| 139 | res = tipc_register_sysctl(); | 115 | goto out_nametbl; |
| 140 | if (!res) | 116 | |
| 141 | res = tipc_subscr_start(); | 117 | err = tipc_netlink_start(); |
| 142 | if (!res) | 118 | if (err) |
| 143 | res = tipc_cfg_init(); | 119 | goto out_netlink; |
| 144 | if (res) { | 120 | |
| 145 | tipc_handler_stop(); | 121 | err = tipc_socket_init(); |
| 146 | tipc_core_stop(); | 122 | if (err) |
| 147 | } | 123 | goto out_socket; |
| 148 | return res; | 124 | |
| 125 | err = tipc_register_sysctl(); | ||
| 126 | if (err) | ||
| 127 | goto out_sysctl; | ||
| 128 | |||
| 129 | err = tipc_subscr_start(); | ||
| 130 | if (err) | ||
| 131 | goto out_subscr; | ||
| 132 | |||
| 133 | err = tipc_cfg_init(); | ||
| 134 | if (err) | ||
| 135 | goto out_cfg; | ||
| 136 | |||
| 137 | err = tipc_bearer_setup(); | ||
| 138 | if (err) | ||
| 139 | goto out_bearer; | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | out_bearer: | ||
| 143 | tipc_cfg_stop(); | ||
| 144 | out_cfg: | ||
| 145 | tipc_subscr_stop(); | ||
| 146 | out_subscr: | ||
| 147 | tipc_unregister_sysctl(); | ||
| 148 | out_sysctl: | ||
| 149 | tipc_socket_stop(); | ||
| 150 | out_socket: | ||
| 151 | tipc_netlink_stop(); | ||
| 152 | out_netlink: | ||
| 153 | tipc_nametbl_stop(); | ||
| 154 | out_nametbl: | ||
| 155 | tipc_ref_table_stop(); | ||
| 156 | out_reftbl: | ||
| 157 | tipc_handler_stop(); | ||
| 158 | out_handler: | ||
| 159 | return err; | ||
| 149 | } | 160 | } |
| 150 | 161 | ||
| 151 | static int __init tipc_init(void) | 162 | static int __init tipc_init(void) |
| @@ -174,8 +185,6 @@ static int __init tipc_init(void) | |||
| 174 | 185 | ||
| 175 | static void __exit tipc_exit(void) | 186 | static void __exit tipc_exit(void) |
| 176 | { | 187 | { |
| 177 | tipc_handler_stop(); | ||
| 178 | tipc_core_stop_net(); | ||
| 179 | tipc_core_stop(); | 188 | tipc_core_stop(); |
| 180 | pr_info("Deactivated\n"); | 189 | pr_info("Deactivated\n"); |
| 181 | } | 190 | } |
diff --git a/net/tipc/core.h b/net/tipc/core.h index 5569d96b4da3..4dfe137587bb 100644 --- a/net/tipc/core.h +++ b/net/tipc/core.h | |||
| @@ -90,7 +90,6 @@ extern int tipc_random __read_mostly; | |||
| 90 | /* | 90 | /* |
| 91 | * Routines available to privileged subsystems | 91 | * Routines available to privileged subsystems |
| 92 | */ | 92 | */ |
| 93 | int tipc_core_start_net(unsigned long); | ||
| 94 | int tipc_handler_start(void); | 93 | int tipc_handler_start(void); |
| 95 | void tipc_handler_stop(void); | 94 | void tipc_handler_stop(void); |
| 96 | int tipc_netlink_start(void); | 95 | int tipc_netlink_start(void); |
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index 92a1533af4e0..48302be175ce 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -945,9 +945,6 @@ void tipc_nametbl_stop(void) | |||
| 945 | { | 945 | { |
| 946 | u32 i; | 946 | u32 i; |
| 947 | 947 | ||
| 948 | if (!table.types) | ||
| 949 | return; | ||
| 950 | |||
| 951 | /* Verify name table is empty, then release it */ | 948 | /* Verify name table is empty, then release it */ |
| 952 | write_lock_bh(&tipc_nametbl_lock); | 949 | write_lock_bh(&tipc_nametbl_lock); |
| 953 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { | 950 | for (i = 0; i < TIPC_NAMETBL_SIZE; i++) { |
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 9f72a6376362..3aaf73de9e2d 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
| @@ -83,8 +83,6 @@ static struct genl_ops tipc_genl_ops[] = { | |||
| 83 | }, | 83 | }, |
| 84 | }; | 84 | }; |
| 85 | 85 | ||
| 86 | static int tipc_genl_family_registered; | ||
| 87 | |||
| 88 | int tipc_netlink_start(void) | 86 | int tipc_netlink_start(void) |
| 89 | { | 87 | { |
| 90 | int res; | 88 | int res; |
| @@ -94,16 +92,10 @@ int tipc_netlink_start(void) | |||
| 94 | pr_err("Failed to register netlink interface\n"); | 92 | pr_err("Failed to register netlink interface\n"); |
| 95 | return res; | 93 | return res; |
| 96 | } | 94 | } |
| 97 | |||
| 98 | tipc_genl_family_registered = 1; | ||
| 99 | return 0; | 95 | return 0; |
| 100 | } | 96 | } |
| 101 | 97 | ||
| 102 | void tipc_netlink_stop(void) | 98 | void tipc_netlink_stop(void) |
| 103 | { | 99 | { |
| 104 | if (!tipc_genl_family_registered) | ||
| 105 | return; | ||
| 106 | |||
| 107 | genl_unregister_family(&tipc_genl_family); | 100 | genl_unregister_family(&tipc_genl_family); |
| 108 | tipc_genl_family_registered = 0; | ||
| 109 | } | 101 | } |
diff --git a/net/tipc/ref.c b/net/tipc/ref.c index 2a2a938dc22c..de3d593e2fee 100644 --- a/net/tipc/ref.c +++ b/net/tipc/ref.c | |||
| @@ -126,9 +126,6 @@ int tipc_ref_table_init(u32 requested_size, u32 start) | |||
| 126 | */ | 126 | */ |
| 127 | void tipc_ref_table_stop(void) | 127 | void tipc_ref_table_stop(void) |
| 128 | { | 128 | { |
| 129 | if (!tipc_ref_table.entries) | ||
| 130 | return; | ||
| 131 | |||
| 132 | vfree(tipc_ref_table.entries); | 129 | vfree(tipc_ref_table.entries); |
| 133 | tipc_ref_table.entries = NULL; | 130 | tipc_ref_table.entries = NULL; |
| 134 | } | 131 | } |
diff --git a/net/tipc/server.c b/net/tipc/server.c index b635ca347a87..373979789a73 100644 --- a/net/tipc/server.c +++ b/net/tipc/server.c | |||
| @@ -573,7 +573,6 @@ int tipc_server_start(struct tipc_server *s) | |||
| 573 | kmem_cache_destroy(s->rcvbuf_cache); | 573 | kmem_cache_destroy(s->rcvbuf_cache); |
| 574 | return ret; | 574 | return ret; |
| 575 | } | 575 | } |
| 576 | s->enabled = 1; | ||
| 577 | return ret; | 576 | return ret; |
| 578 | } | 577 | } |
| 579 | 578 | ||
| @@ -583,10 +582,6 @@ void tipc_server_stop(struct tipc_server *s) | |||
| 583 | int total = 0; | 582 | int total = 0; |
| 584 | int id; | 583 | int id; |
| 585 | 584 | ||
| 586 | if (!s->enabled) | ||
| 587 | return; | ||
| 588 | |||
| 589 | s->enabled = 0; | ||
| 590 | spin_lock_bh(&s->idr_lock); | 585 | spin_lock_bh(&s->idr_lock); |
| 591 | for (id = 0; total < s->idr_in_use; id++) { | 586 | for (id = 0; total < s->idr_in_use; id++) { |
| 592 | con = idr_find(&s->conn_idr, id); | 587 | con = idr_find(&s->conn_idr, id); |
diff --git a/net/tipc/server.h b/net/tipc/server.h index 98b23f20bc0f..be817b0b547e 100644 --- a/net/tipc/server.h +++ b/net/tipc/server.h | |||
| @@ -56,7 +56,6 @@ | |||
| 56 | * @name: server name | 56 | * @name: server name |
| 57 | * @imp: message importance | 57 | * @imp: message importance |
| 58 | * @type: socket type | 58 | * @type: socket type |
| 59 | * @enabled: identify whether server is launched or not | ||
| 60 | */ | 59 | */ |
| 61 | struct tipc_server { | 60 | struct tipc_server { |
| 62 | struct idr conn_idr; | 61 | struct idr conn_idr; |
| @@ -74,7 +73,6 @@ struct tipc_server { | |||
| 74 | const char name[TIPC_SERVER_NAME_LEN]; | 73 | const char name[TIPC_SERVER_NAME_LEN]; |
| 75 | int imp; | 74 | int imp; |
| 76 | int type; | 75 | int type; |
| 77 | int enabled; | ||
| 78 | }; | 76 | }; |
| 79 | 77 | ||
| 80 | int tipc_conn_sendmsg(struct tipc_server *s, int conid, | 78 | int tipc_conn_sendmsg(struct tipc_server *s, int conid, |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index aab4948f0aff..a4cf274455aa 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -70,8 +70,6 @@ static const struct proto_ops msg_ops; | |||
| 70 | static struct proto tipc_proto; | 70 | static struct proto tipc_proto; |
| 71 | static struct proto tipc_proto_kern; | 71 | static struct proto tipc_proto_kern; |
| 72 | 72 | ||
| 73 | static int sockets_enabled; | ||
| 74 | |||
| 75 | /* | 73 | /* |
| 76 | * Revised TIPC socket locking policy: | 74 | * Revised TIPC socket locking policy: |
| 77 | * | 75 | * |
| @@ -2027,8 +2025,6 @@ int tipc_socket_init(void) | |||
| 2027 | proto_unregister(&tipc_proto); | 2025 | proto_unregister(&tipc_proto); |
| 2028 | goto out; | 2026 | goto out; |
| 2029 | } | 2027 | } |
| 2030 | |||
| 2031 | sockets_enabled = 1; | ||
| 2032 | out: | 2028 | out: |
| 2033 | return res; | 2029 | return res; |
| 2034 | } | 2030 | } |
| @@ -2038,10 +2034,6 @@ int tipc_socket_init(void) | |||
| 2038 | */ | 2034 | */ |
| 2039 | void tipc_socket_stop(void) | 2035 | void tipc_socket_stop(void) |
| 2040 | { | 2036 | { |
| 2041 | if (!sockets_enabled) | ||
| 2042 | return; | ||
| 2043 | |||
| 2044 | sockets_enabled = 0; | ||
| 2045 | sock_unregister(tipc_family_ops.family); | 2037 | sock_unregister(tipc_family_ops.family); |
| 2046 | proto_unregister(&tipc_proto); | 2038 | proto_unregister(&tipc_proto); |
| 2047 | } | 2039 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 9b897fca7487..f0541370e68e 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -1700,7 +1700,7 @@ static void reg_process_hint(struct regulatory_request *reg_request) | |||
| 1700 | return; | 1700 | return; |
| 1701 | case NL80211_REGDOM_SET_BY_USER: | 1701 | case NL80211_REGDOM_SET_BY_USER: |
| 1702 | treatment = reg_process_hint_user(reg_request); | 1702 | treatment = reg_process_hint_user(reg_request); |
| 1703 | if (treatment == REG_REQ_OK || | 1703 | if (treatment == REG_REQ_IGNORE || |
| 1704 | treatment == REG_REQ_ALREADY_SET) | 1704 | treatment == REG_REQ_ALREADY_SET) |
| 1705 | return; | 1705 | return; |
| 1706 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); | 1706 | schedule_delayed_work(®_timeout, msecs_to_jiffies(3142)); |
| @@ -2373,6 +2373,7 @@ static int reg_set_rd_country_ie(const struct ieee80211_regdomain *rd, | |||
| 2373 | int set_regdom(const struct ieee80211_regdomain *rd) | 2373 | int set_regdom(const struct ieee80211_regdomain *rd) |
| 2374 | { | 2374 | { |
| 2375 | struct regulatory_request *lr; | 2375 | struct regulatory_request *lr; |
| 2376 | bool user_reset = false; | ||
| 2376 | int r; | 2377 | int r; |
| 2377 | 2378 | ||
| 2378 | if (!reg_is_valid_request(rd->alpha2)) { | 2379 | if (!reg_is_valid_request(rd->alpha2)) { |
| @@ -2389,6 +2390,7 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
| 2389 | break; | 2390 | break; |
| 2390 | case NL80211_REGDOM_SET_BY_USER: | 2391 | case NL80211_REGDOM_SET_BY_USER: |
| 2391 | r = reg_set_rd_user(rd, lr); | 2392 | r = reg_set_rd_user(rd, lr); |
| 2393 | user_reset = true; | ||
| 2392 | break; | 2394 | break; |
| 2393 | case NL80211_REGDOM_SET_BY_DRIVER: | 2395 | case NL80211_REGDOM_SET_BY_DRIVER: |
| 2394 | r = reg_set_rd_driver(rd, lr); | 2396 | r = reg_set_rd_driver(rd, lr); |
| @@ -2402,8 +2404,14 @@ int set_regdom(const struct ieee80211_regdomain *rd) | |||
| 2402 | } | 2404 | } |
| 2403 | 2405 | ||
| 2404 | if (r) { | 2406 | if (r) { |
| 2405 | if (r == -EALREADY) | 2407 | switch (r) { |
| 2408 | case -EALREADY: | ||
| 2406 | reg_set_request_processed(); | 2409 | reg_set_request_processed(); |
| 2410 | break; | ||
| 2411 | default: | ||
| 2412 | /* Back to world regulatory in case of errors */ | ||
| 2413 | restore_regulatory_settings(user_reset); | ||
| 2414 | } | ||
| 2407 | 2415 | ||
| 2408 | kfree(rd); | 2416 | kfree(rd); |
| 2409 | return r; | 2417 | return r; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 4b98b25793c5..1d5c7bf29938 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -1158,7 +1158,7 @@ static struct xfrm_policy *__xfrm_policy_unlink(struct xfrm_policy *pol, | |||
| 1158 | if (hlist_unhashed(&pol->bydst)) | 1158 | if (hlist_unhashed(&pol->bydst)) |
| 1159 | return NULL; | 1159 | return NULL; |
| 1160 | 1160 | ||
| 1161 | hlist_del(&pol->bydst); | 1161 | hlist_del_init(&pol->bydst); |
| 1162 | hlist_del(&pol->byidx); | 1162 | hlist_del(&pol->byidx); |
| 1163 | list_del(&pol->walk.all); | 1163 | list_del(&pol->walk.all); |
| 1164 | net->xfrm.policy_count[dir]--; | 1164 | net->xfrm.policy_count[dir]--; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index a26b7aa79475..40f1b3e92e78 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -1159,6 +1159,11 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) | |||
| 1159 | } | 1159 | } |
| 1160 | x->props.aalgo = orig->props.aalgo; | 1160 | x->props.aalgo = orig->props.aalgo; |
| 1161 | 1161 | ||
| 1162 | if (orig->aead) { | ||
| 1163 | x->aead = xfrm_algo_aead_clone(orig->aead); | ||
| 1164 | if (!x->aead) | ||
| 1165 | goto error; | ||
| 1166 | } | ||
| 1162 | if (orig->ealg) { | 1167 | if (orig->ealg) { |
| 1163 | x->ealg = xfrm_algo_clone(orig->ealg); | 1168 | x->ealg = xfrm_algo_clone(orig->ealg); |
| 1164 | if (!x->ealg) | 1169 | if (!x->ealg) |
| @@ -1201,6 +1206,9 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, int *errp) | |||
| 1201 | x->props.flags = orig->props.flags; | 1206 | x->props.flags = orig->props.flags; |
| 1202 | x->props.extra_flags = orig->props.extra_flags; | 1207 | x->props.extra_flags = orig->props.extra_flags; |
| 1203 | 1208 | ||
| 1209 | x->tfcpad = orig->tfcpad; | ||
| 1210 | x->replay_maxdiff = orig->replay_maxdiff; | ||
| 1211 | x->replay_maxage = orig->replay_maxage; | ||
| 1204 | x->curlft.add_time = orig->curlft.add_time; | 1212 | x->curlft.add_time = orig->curlft.add_time; |
| 1205 | x->km.state = orig->km.state; | 1213 | x->km.state = orig->km.state; |
| 1206 | x->km.seq = orig->km.seq; | 1214 | x->km.seq = orig->km.seq; |
| @@ -1215,11 +1223,12 @@ out: | |||
| 1215 | return NULL; | 1223 | return NULL; |
| 1216 | } | 1224 | } |
| 1217 | 1225 | ||
| 1218 | /* net->xfrm.xfrm_state_lock is held */ | ||
| 1219 | struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net) | 1226 | struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net) |
| 1220 | { | 1227 | { |
| 1221 | unsigned int h; | 1228 | unsigned int h; |
| 1222 | struct xfrm_state *x; | 1229 | struct xfrm_state *x = NULL; |
| 1230 | |||
| 1231 | spin_lock_bh(&net->xfrm.xfrm_state_lock); | ||
| 1223 | 1232 | ||
| 1224 | if (m->reqid) { | 1233 | if (m->reqid) { |
| 1225 | h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr, | 1234 | h = xfrm_dst_hash(net, &m->old_daddr, &m->old_saddr, |
| @@ -1236,7 +1245,7 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n | |||
| 1236 | m->old_family)) | 1245 | m->old_family)) |
| 1237 | continue; | 1246 | continue; |
| 1238 | xfrm_state_hold(x); | 1247 | xfrm_state_hold(x); |
| 1239 | return x; | 1248 | break; |
| 1240 | } | 1249 | } |
| 1241 | } else { | 1250 | } else { |
| 1242 | h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr, | 1251 | h = xfrm_src_hash(net, &m->old_daddr, &m->old_saddr, |
| @@ -1251,11 +1260,13 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n | |||
| 1251 | m->old_family)) | 1260 | m->old_family)) |
| 1252 | continue; | 1261 | continue; |
| 1253 | xfrm_state_hold(x); | 1262 | xfrm_state_hold(x); |
| 1254 | return x; | 1263 | break; |
| 1255 | } | 1264 | } |
| 1256 | } | 1265 | } |
| 1257 | 1266 | ||
| 1258 | return NULL; | 1267 | spin_unlock_bh(&net->xfrm.xfrm_state_lock); |
| 1268 | |||
| 1269 | return x; | ||
| 1259 | } | 1270 | } |
| 1260 | EXPORT_SYMBOL(xfrm_migrate_state_find); | 1271 | EXPORT_SYMBOL(xfrm_migrate_state_find); |
| 1261 | 1272 | ||
| @@ -1451,7 +1462,7 @@ xfrm_state_sort(struct xfrm_state **dst, struct xfrm_state **src, int n, | |||
| 1451 | { | 1462 | { |
| 1452 | int err = 0; | 1463 | int err = 0; |
| 1453 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); | 1464 | struct xfrm_state_afinfo *afinfo = xfrm_state_get_afinfo(family); |
| 1454 | struct net *net = xs_net(*dst); | 1465 | struct net *net = xs_net(*src); |
| 1455 | 1466 | ||
| 1456 | if (!afinfo) | 1467 | if (!afinfo) |
| 1457 | return -EAFNOSUPPORT; | 1468 | return -EAFNOSUPPORT; |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 1ae3ec7c18b0..c274179d60a2 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -32,11 +32,6 @@ | |||
| 32 | #include <linux/in6.h> | 32 | #include <linux/in6.h> |
| 33 | #endif | 33 | #endif |
| 34 | 34 | ||
| 35 | static inline int aead_len(struct xfrm_algo_aead *alg) | ||
| 36 | { | ||
| 37 | return sizeof(*alg) + ((alg->alg_key_len + 7) / 8); | ||
| 38 | } | ||
| 39 | |||
| 40 | static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) | 35 | static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type) |
| 41 | { | 36 | { |
| 42 | struct nlattr *rt = attrs[type]; | 37 | struct nlattr *rt = attrs[type]; |
