diff options
Diffstat (limited to 'net')
31 files changed, 194 insertions, 184 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 574f78824d8a..32bd3ead9ba1 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
| @@ -595,7 +595,7 @@ static int br_afspec(struct net_bridge *br, | |||
| 595 | err = 0; | 595 | err = 0; |
| 596 | switch (nla_type(attr)) { | 596 | switch (nla_type(attr)) { |
| 597 | case IFLA_BRIDGE_VLAN_TUNNEL_INFO: | 597 | case IFLA_BRIDGE_VLAN_TUNNEL_INFO: |
| 598 | if (!(p->flags & BR_VLAN_TUNNEL)) | 598 | if (!p || !(p->flags & BR_VLAN_TUNNEL)) |
| 599 | return -EINVAL; | 599 | return -EINVAL; |
| 600 | err = br_parse_vlan_tunnel_info(attr, &tinfo_curr); | 600 | err = br_parse_vlan_tunnel_info(attr, &tinfo_curr); |
| 601 | if (err) | 601 | if (err) |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0db8102995a5..6f12a5271219 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
| @@ -179,7 +179,8 @@ static void br_stp_start(struct net_bridge *br) | |||
| 179 | br_debug(br, "using kernel STP\n"); | 179 | br_debug(br, "using kernel STP\n"); |
| 180 | 180 | ||
| 181 | /* To start timers on any ports left in blocking */ | 181 | /* To start timers on any ports left in blocking */ |
| 182 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | 182 | if (br->dev->flags & IFF_UP) |
| 183 | mod_timer(&br->hello_timer, jiffies + br->hello_time); | ||
| 183 | br_port_state_selection(br); | 184 | br_port_state_selection(br); |
| 184 | } | 185 | } |
| 185 | 186 | ||
diff --git a/net/core/devlink.c b/net/core/devlink.c index b0b87a292e7c..a0adfc31a3fe 100644 --- a/net/core/devlink.c +++ b/net/core/devlink.c | |||
| @@ -1680,8 +1680,10 @@ start_again: | |||
| 1680 | 1680 | ||
| 1681 | hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, | 1681 | hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, |
| 1682 | &devlink_nl_family, NLM_F_MULTI, cmd); | 1682 | &devlink_nl_family, NLM_F_MULTI, cmd); |
| 1683 | if (!hdr) | 1683 | if (!hdr) { |
| 1684 | nlmsg_free(skb); | ||
| 1684 | return -EMSGSIZE; | 1685 | return -EMSGSIZE; |
| 1686 | } | ||
| 1685 | 1687 | ||
| 1686 | if (devlink_nl_put_handle(skb, devlink)) | 1688 | if (devlink_nl_put_handle(skb, devlink)) |
| 1687 | goto nla_put_failure; | 1689 | goto nla_put_failure; |
| @@ -2098,8 +2100,10 @@ start_again: | |||
| 2098 | 2100 | ||
| 2099 | hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, | 2101 | hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq, |
| 2100 | &devlink_nl_family, NLM_F_MULTI, cmd); | 2102 | &devlink_nl_family, NLM_F_MULTI, cmd); |
| 2101 | if (!hdr) | 2103 | if (!hdr) { |
| 2104 | nlmsg_free(skb); | ||
| 2102 | return -EMSGSIZE; | 2105 | return -EMSGSIZE; |
| 2106 | } | ||
| 2103 | 2107 | ||
| 2104 | if (devlink_nl_put_handle(skb, devlink)) | 2108 | if (devlink_nl_put_handle(skb, devlink)) |
| 2105 | goto nla_put_failure; | 2109 | goto nla_put_failure; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 346d3e85dfbc..b1be7c01efe2 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3754,8 +3754,11 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk) | |||
| 3754 | 3754 | ||
| 3755 | spin_lock_irqsave(&q->lock, flags); | 3755 | spin_lock_irqsave(&q->lock, flags); |
| 3756 | skb = __skb_dequeue(q); | 3756 | skb = __skb_dequeue(q); |
| 3757 | if (skb && (skb_next = skb_peek(q))) | 3757 | if (skb && (skb_next = skb_peek(q))) { |
| 3758 | icmp_next = is_icmp_err_skb(skb_next); | 3758 | icmp_next = is_icmp_err_skb(skb_next); |
| 3759 | if (icmp_next) | ||
| 3760 | sk->sk_err = SKB_EXT_ERR(skb_next)->ee.ee_origin; | ||
| 3761 | } | ||
| 3759 | spin_unlock_irqrestore(&q->lock, flags); | 3762 | spin_unlock_irqrestore(&q->lock, flags); |
| 3760 | 3763 | ||
| 3761 | if (is_icmp_err_skb(skb) && !icmp_next) | 3764 | if (is_icmp_err_skb(skb) && !icmp_next) |
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 26130ae438da..90038d45a547 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
| @@ -223,6 +223,53 @@ static int dsa_switch_rcv(struct sk_buff *skb, struct net_device *dev, | |||
| 223 | return 0; | 223 | return 0; |
| 224 | } | 224 | } |
| 225 | 225 | ||
| 226 | #ifdef CONFIG_PM_SLEEP | ||
| 227 | int dsa_switch_suspend(struct dsa_switch *ds) | ||
| 228 | { | ||
| 229 | int i, ret = 0; | ||
| 230 | |||
| 231 | /* Suspend slave network devices */ | ||
| 232 | for (i = 0; i < ds->num_ports; i++) { | ||
| 233 | if (!dsa_is_port_initialized(ds, i)) | ||
| 234 | continue; | ||
| 235 | |||
| 236 | ret = dsa_slave_suspend(ds->ports[i].netdev); | ||
| 237 | if (ret) | ||
| 238 | return ret; | ||
| 239 | } | ||
| 240 | |||
| 241 | if (ds->ops->suspend) | ||
| 242 | ret = ds->ops->suspend(ds); | ||
| 243 | |||
| 244 | return ret; | ||
| 245 | } | ||
| 246 | EXPORT_SYMBOL_GPL(dsa_switch_suspend); | ||
| 247 | |||
| 248 | int dsa_switch_resume(struct dsa_switch *ds) | ||
| 249 | { | ||
| 250 | int i, ret = 0; | ||
| 251 | |||
| 252 | if (ds->ops->resume) | ||
| 253 | ret = ds->ops->resume(ds); | ||
| 254 | |||
| 255 | if (ret) | ||
| 256 | return ret; | ||
| 257 | |||
| 258 | /* Resume slave network devices */ | ||
| 259 | for (i = 0; i < ds->num_ports; i++) { | ||
| 260 | if (!dsa_is_port_initialized(ds, i)) | ||
| 261 | continue; | ||
| 262 | |||
| 263 | ret = dsa_slave_resume(ds->ports[i].netdev); | ||
| 264 | if (ret) | ||
| 265 | return ret; | ||
| 266 | } | ||
| 267 | |||
| 268 | return 0; | ||
| 269 | } | ||
| 270 | EXPORT_SYMBOL_GPL(dsa_switch_resume); | ||
| 271 | #endif | ||
| 272 | |||
| 226 | static struct packet_type dsa_pack_type __read_mostly = { | 273 | static struct packet_type dsa_pack_type __read_mostly = { |
| 227 | .type = cpu_to_be16(ETH_P_XDSA), | 274 | .type = cpu_to_be16(ETH_P_XDSA), |
| 228 | .func = dsa_switch_rcv, | 275 | .func = dsa_switch_rcv, |
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 033b3bfb63dc..7796580e99ee 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c | |||
| @@ -484,8 +484,10 @@ static void dsa_dst_unapply(struct dsa_switch_tree *dst) | |||
| 484 | dsa_ds_unapply(dst, ds); | 484 | dsa_ds_unapply(dst, ds); |
| 485 | } | 485 | } |
| 486 | 486 | ||
| 487 | if (dst->cpu_switch) | 487 | if (dst->cpu_switch) { |
| 488 | dsa_cpu_port_ethtool_restore(dst->cpu_switch); | 488 | dsa_cpu_port_ethtool_restore(dst->cpu_switch); |
| 489 | dst->cpu_switch = NULL; | ||
| 490 | } | ||
| 489 | 491 | ||
| 490 | pr_info("DSA: tree %d unapplied\n", dst->tree); | 492 | pr_info("DSA: tree %d unapplied\n", dst->tree); |
| 491 | dst->applied = false; | 493 | dst->applied = false; |
diff --git a/net/dsa/legacy.c b/net/dsa/legacy.c index ad345c8b0b06..7281098df04e 100644 --- a/net/dsa/legacy.c +++ b/net/dsa/legacy.c | |||
| @@ -289,53 +289,6 @@ static void dsa_switch_destroy(struct dsa_switch *ds) | |||
| 289 | dsa_switch_unregister_notifier(ds); | 289 | dsa_switch_unregister_notifier(ds); |
| 290 | } | 290 | } |
| 291 | 291 | ||
| 292 | #ifdef CONFIG_PM_SLEEP | ||
| 293 | int dsa_switch_suspend(struct dsa_switch *ds) | ||
| 294 | { | ||
| 295 | int i, ret = 0; | ||
| 296 | |||
| 297 | /* Suspend slave network devices */ | ||
| 298 | for (i = 0; i < ds->num_ports; i++) { | ||
| 299 | if (!dsa_is_port_initialized(ds, i)) | ||
| 300 | continue; | ||
| 301 | |||
| 302 | ret = dsa_slave_suspend(ds->ports[i].netdev); | ||
| 303 | if (ret) | ||
| 304 | return ret; | ||
| 305 | } | ||
| 306 | |||
| 307 | if (ds->ops->suspend) | ||
| 308 | ret = ds->ops->suspend(ds); | ||
| 309 | |||
| 310 | return ret; | ||
| 311 | } | ||
| 312 | EXPORT_SYMBOL_GPL(dsa_switch_suspend); | ||
| 313 | |||
| 314 | int dsa_switch_resume(struct dsa_switch *ds) | ||
| 315 | { | ||
| 316 | int i, ret = 0; | ||
| 317 | |||
| 318 | if (ds->ops->resume) | ||
| 319 | ret = ds->ops->resume(ds); | ||
| 320 | |||
| 321 | if (ret) | ||
| 322 | return ret; | ||
| 323 | |||
| 324 | /* Resume slave network devices */ | ||
| 325 | for (i = 0; i < ds->num_ports; i++) { | ||
| 326 | if (!dsa_is_port_initialized(ds, i)) | ||
| 327 | continue; | ||
| 328 | |||
| 329 | ret = dsa_slave_resume(ds->ports[i].netdev); | ||
| 330 | if (ret) | ||
| 331 | return ret; | ||
| 332 | } | ||
| 333 | |||
| 334 | return 0; | ||
| 335 | } | ||
| 336 | EXPORT_SYMBOL_GPL(dsa_switch_resume); | ||
| 337 | #endif | ||
| 338 | |||
| 339 | /* platform driver init and cleanup *****************************************/ | 292 | /* platform driver init and cleanup *****************************************/ |
| 340 | static int dev_is_class(struct device *dev, void *class) | 293 | static int dev_is_class(struct device *dev, void *class) |
| 341 | { | 294 | { |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f3dad1661343..58925b6597de 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -1043,7 +1043,7 @@ static struct inet_protosw inetsw_array[] = | |||
| 1043 | .type = SOCK_DGRAM, | 1043 | .type = SOCK_DGRAM, |
| 1044 | .protocol = IPPROTO_ICMP, | 1044 | .protocol = IPPROTO_ICMP, |
| 1045 | .prot = &ping_prot, | 1045 | .prot = &ping_prot, |
| 1046 | .ops = &inet_dgram_ops, | 1046 | .ops = &inet_sockraw_ops, |
| 1047 | .flags = INET_PROTOSW_REUSE, | 1047 | .flags = INET_PROTOSW_REUSE, |
| 1048 | }, | 1048 | }, |
| 1049 | 1049 | ||
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 59792d283ff8..b5ea036ca781 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -2381,9 +2381,10 @@ static int tcp_repair_set_window(struct tcp_sock *tp, char __user *optbuf, int l | |||
| 2381 | return 0; | 2381 | return 0; |
| 2382 | } | 2382 | } |
| 2383 | 2383 | ||
| 2384 | static int tcp_repair_options_est(struct tcp_sock *tp, | 2384 | static int tcp_repair_options_est(struct sock *sk, |
| 2385 | struct tcp_repair_opt __user *optbuf, unsigned int len) | 2385 | struct tcp_repair_opt __user *optbuf, unsigned int len) |
| 2386 | { | 2386 | { |
| 2387 | struct tcp_sock *tp = tcp_sk(sk); | ||
| 2387 | struct tcp_repair_opt opt; | 2388 | struct tcp_repair_opt opt; |
| 2388 | 2389 | ||
| 2389 | while (len >= sizeof(opt)) { | 2390 | while (len >= sizeof(opt)) { |
| @@ -2396,6 +2397,7 @@ static int tcp_repair_options_est(struct tcp_sock *tp, | |||
| 2396 | switch (opt.opt_code) { | 2397 | switch (opt.opt_code) { |
| 2397 | case TCPOPT_MSS: | 2398 | case TCPOPT_MSS: |
| 2398 | tp->rx_opt.mss_clamp = opt.opt_val; | 2399 | tp->rx_opt.mss_clamp = opt.opt_val; |
| 2400 | tcp_mtup_init(sk); | ||
| 2399 | break; | 2401 | break; |
| 2400 | case TCPOPT_WINDOW: | 2402 | case TCPOPT_WINDOW: |
| 2401 | { | 2403 | { |
| @@ -2555,7 +2557,7 @@ static int do_tcp_setsockopt(struct sock *sk, int level, | |||
| 2555 | if (!tp->repair) | 2557 | if (!tp->repair) |
| 2556 | err = -EINVAL; | 2558 | err = -EINVAL; |
| 2557 | else if (sk->sk_state == TCP_ESTABLISHED) | 2559 | else if (sk->sk_state == TCP_ESTABLISHED) |
| 2558 | err = tcp_repair_options_est(tp, | 2560 | err = tcp_repair_options_est(sk, |
| 2559 | (struct tcp_repair_opt __user *)optval, | 2561 | (struct tcp_repair_opt __user *)optval, |
| 2560 | optlen); | 2562 | optlen); |
| 2561 | else | 2563 | else |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index 6e3c512054a6..324c9bcc5456 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -180,6 +180,7 @@ void tcp_init_congestion_control(struct sock *sk) | |||
| 180 | { | 180 | { |
| 181 | const struct inet_connection_sock *icsk = inet_csk(sk); | 181 | const struct inet_connection_sock *icsk = inet_csk(sk); |
| 182 | 182 | ||
| 183 | tcp_sk(sk)->prior_ssthresh = 0; | ||
| 183 | if (icsk->icsk_ca_ops->init) | 184 | if (icsk->icsk_ca_ops->init) |
| 184 | icsk->icsk_ca_ops->init(sk); | 185 | icsk->icsk_ca_ops->init(sk); |
| 185 | if (tcp_ca_needs_ecn(sk)) | 186 | if (tcp_ca_needs_ecn(sk)) |
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c index 37ac9de713c6..8d772fea1dde 100644 --- a/net/ipv6/calipso.c +++ b/net/ipv6/calipso.c | |||
| @@ -1319,7 +1319,7 @@ static int calipso_skbuff_setattr(struct sk_buff *skb, | |||
| 1319 | struct ipv6hdr *ip6_hdr; | 1319 | struct ipv6hdr *ip6_hdr; |
| 1320 | struct ipv6_opt_hdr *hop; | 1320 | struct ipv6_opt_hdr *hop; |
| 1321 | unsigned char buf[CALIPSO_MAX_BUFFER]; | 1321 | unsigned char buf[CALIPSO_MAX_BUFFER]; |
| 1322 | int len_delta, new_end, pad; | 1322 | int len_delta, new_end, pad, payload; |
| 1323 | unsigned int start, end; | 1323 | unsigned int start, end; |
| 1324 | 1324 | ||
| 1325 | ip6_hdr = ipv6_hdr(skb); | 1325 | ip6_hdr = ipv6_hdr(skb); |
| @@ -1346,6 +1346,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb, | |||
| 1346 | if (ret_val < 0) | 1346 | if (ret_val < 0) |
| 1347 | return ret_val; | 1347 | return ret_val; |
| 1348 | 1348 | ||
| 1349 | ip6_hdr = ipv6_hdr(skb); /* Reset as skb_cow() may have moved it */ | ||
| 1350 | |||
| 1349 | if (len_delta) { | 1351 | if (len_delta) { |
| 1350 | if (len_delta > 0) | 1352 | if (len_delta > 0) |
| 1351 | skb_push(skb, len_delta); | 1353 | skb_push(skb, len_delta); |
| @@ -1355,6 +1357,8 @@ static int calipso_skbuff_setattr(struct sk_buff *skb, | |||
| 1355 | sizeof(*ip6_hdr) + start); | 1357 | sizeof(*ip6_hdr) + start); |
| 1356 | skb_reset_network_header(skb); | 1358 | skb_reset_network_header(skb); |
| 1357 | ip6_hdr = ipv6_hdr(skb); | 1359 | ip6_hdr = ipv6_hdr(skb); |
| 1360 | payload = ntohs(ip6_hdr->payload_len); | ||
| 1361 | ip6_hdr->payload_len = htons(payload + len_delta); | ||
| 1358 | } | 1362 | } |
| 1359 | 1363 | ||
| 1360 | hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1); | 1364 | hop = (struct ipv6_opt_hdr *)(ip6_hdr + 1); |
diff --git a/net/ipv6/ip6_offload.c b/net/ipv6/ip6_offload.c index 280268f1dd7b..cdb3728faca7 100644 --- a/net/ipv6/ip6_offload.c +++ b/net/ipv6/ip6_offload.c | |||
| @@ -116,8 +116,10 @@ static struct sk_buff *ipv6_gso_segment(struct sk_buff *skb, | |||
| 116 | 116 | ||
| 117 | if (udpfrag) { | 117 | if (udpfrag) { |
| 118 | int err = ip6_find_1stfragopt(skb, &prevhdr); | 118 | int err = ip6_find_1stfragopt(skb, &prevhdr); |
| 119 | if (err < 0) | 119 | if (err < 0) { |
| 120 | kfree_skb_list(segs); | ||
| 120 | return ERR_PTR(err); | 121 | return ERR_PTR(err); |
| 122 | } | ||
| 121 | fptr = (struct frag_hdr *)((u8 *)ipv6h + err); | 123 | fptr = (struct frag_hdr *)((u8 *)ipv6h + err); |
| 122 | fptr->frag_off = htons(offset); | 124 | fptr->frag_off = htons(offset); |
| 123 | if (skb->next) | 125 | if (skb->next) |
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 7ae6c503f1ca..9b37f9747fc6 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -1095,6 +1095,9 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, | |||
| 1095 | 1095 | ||
| 1096 | if (!dst) { | 1096 | if (!dst) { |
| 1097 | route_lookup: | 1097 | route_lookup: |
| 1098 | /* add dsfield to flowlabel for route lookup */ | ||
| 1099 | fl6->flowlabel = ip6_make_flowinfo(dsfield, fl6->flowlabel); | ||
| 1100 | |||
| 1098 | dst = ip6_route_output(net, NULL, fl6); | 1101 | dst = ip6_route_output(net, NULL, fl6); |
| 1099 | 1102 | ||
| 1100 | if (dst->error) | 1103 | if (dst->error) |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index 9b522fa90e6d..ac826dd338ff 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
| @@ -192,7 +192,7 @@ static struct inet_protosw pingv6_protosw = { | |||
| 192 | .type = SOCK_DGRAM, | 192 | .type = SOCK_DGRAM, |
| 193 | .protocol = IPPROTO_ICMPV6, | 193 | .protocol = IPPROTO_ICMPV6, |
| 194 | .prot = &pingv6_prot, | 194 | .prot = &pingv6_prot, |
| 195 | .ops = &inet6_dgram_ops, | 195 | .ops = &inet6_sockraw_ops, |
| 196 | .flags = INET_PROTOSW_REUSE, | 196 | .flags = INET_PROTOSW_REUSE, |
| 197 | }; | 197 | }; |
| 198 | 198 | ||
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 1f992d9e261d..60be012fe708 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
| @@ -1338,7 +1338,7 @@ void raw6_proc_exit(void) | |||
| 1338 | #endif /* CONFIG_PROC_FS */ | 1338 | #endif /* CONFIG_PROC_FS */ |
| 1339 | 1339 | ||
| 1340 | /* Same as inet6_dgram_ops, sans udp_poll. */ | 1340 | /* Same as inet6_dgram_ops, sans udp_poll. */ |
| 1341 | static const struct proto_ops inet6_sockraw_ops = { | 1341 | const struct proto_ops inet6_sockraw_ops = { |
| 1342 | .family = PF_INET6, | 1342 | .family = PF_INET6, |
| 1343 | .owner = THIS_MODULE, | 1343 | .owner = THIS_MODULE, |
| 1344 | .release = inet6_release, | 1344 | .release = inet6_release, |
diff --git a/net/ipv6/xfrm6_mode_ro.c b/net/ipv6/xfrm6_mode_ro.c index 0e015906f9ca..07d36573f50b 100644 --- a/net/ipv6/xfrm6_mode_ro.c +++ b/net/ipv6/xfrm6_mode_ro.c | |||
| @@ -47,6 +47,8 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 47 | iph = ipv6_hdr(skb); | 47 | iph = ipv6_hdr(skb); |
| 48 | 48 | ||
| 49 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); | 49 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); |
| 50 | if (hdr_len < 0) | ||
| 51 | return hdr_len; | ||
| 50 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); | 52 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); |
| 51 | skb_set_network_header(skb, -x->props.header_len); | 53 | skb_set_network_header(skb, -x->props.header_len); |
| 52 | skb->transport_header = skb->network_header + hdr_len; | 54 | skb->transport_header = skb->network_header + hdr_len; |
diff --git a/net/ipv6/xfrm6_mode_transport.c b/net/ipv6/xfrm6_mode_transport.c index 7a92c0f31912..9ad07a91708e 100644 --- a/net/ipv6/xfrm6_mode_transport.c +++ b/net/ipv6/xfrm6_mode_transport.c | |||
| @@ -30,6 +30,8 @@ static int xfrm6_transport_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 30 | skb_set_inner_transport_header(skb, skb_transport_offset(skb)); | 30 | skb_set_inner_transport_header(skb, skb_transport_offset(skb)); |
| 31 | 31 | ||
| 32 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); | 32 | hdr_len = x->type->hdr_offset(x, skb, &prevhdr); |
| 33 | if (hdr_len < 0) | ||
| 34 | return hdr_len; | ||
| 33 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); | 35 | skb_set_mac_header(skb, (prevhdr - x->props.header_len) - skb->data); |
| 34 | skb_set_network_header(skb, -x->props.header_len); | 36 | skb_set_network_header(skb, -x->props.header_len); |
| 35 | skb->transport_header = skb->network_header + hdr_len; | 37 | skb->transport_header = skb->network_header + hdr_len; |
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c index 60e2a62f7bef..cf2392b2ac71 100644 --- a/net/mac80211/agg-tx.c +++ b/net/mac80211/agg-tx.c | |||
| @@ -7,7 +7,7 @@ | |||
| 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
| 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
| 9 | * Copyright 2007-2010, Intel Corporation | 9 | * Copyright 2007-2010, Intel Corporation |
| 10 | * Copyright(c) 2015 Intel Deutschland GmbH | 10 | * Copyright(c) 2015-2017 Intel Deutschland GmbH |
| 11 | * | 11 | * |
| 12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 13 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
| @@ -741,46 +741,43 @@ static void ieee80211_agg_tx_operational(struct ieee80211_local *local, | |||
| 741 | ieee80211_agg_start_txq(sta, tid, true); | 741 | ieee80211_agg_start_txq(sta, tid, true); |
| 742 | } | 742 | } |
| 743 | 743 | ||
| 744 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid) | 744 | void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, |
| 745 | struct tid_ampdu_tx *tid_tx) | ||
| 745 | { | 746 | { |
| 746 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 747 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 747 | struct ieee80211_local *local = sdata->local; | 748 | struct ieee80211_local *local = sdata->local; |
| 748 | struct sta_info *sta; | ||
| 749 | struct tid_ampdu_tx *tid_tx; | ||
| 750 | 749 | ||
| 751 | trace_api_start_tx_ba_cb(sdata, ra, tid); | 750 | if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) |
| 751 | return; | ||
| 752 | |||
| 753 | if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) | ||
| 754 | ieee80211_agg_tx_operational(local, sta, tid); | ||
| 755 | } | ||
| 756 | |||
| 757 | static struct tid_ampdu_tx * | ||
| 758 | ieee80211_lookup_tid_tx(struct ieee80211_sub_if_data *sdata, | ||
| 759 | const u8 *ra, u16 tid, struct sta_info **sta) | ||
| 760 | { | ||
| 761 | struct tid_ampdu_tx *tid_tx; | ||
| 752 | 762 | ||
| 753 | if (tid >= IEEE80211_NUM_TIDS) { | 763 | if (tid >= IEEE80211_NUM_TIDS) { |
| 754 | ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", | 764 | ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", |
| 755 | tid, IEEE80211_NUM_TIDS); | 765 | tid, IEEE80211_NUM_TIDS); |
| 756 | return; | 766 | return NULL; |
| 757 | } | 767 | } |
| 758 | 768 | ||
| 759 | mutex_lock(&local->sta_mtx); | 769 | *sta = sta_info_get_bss(sdata, ra); |
| 760 | sta = sta_info_get_bss(sdata, ra); | 770 | if (!*sta) { |
| 761 | if (!sta) { | ||
| 762 | mutex_unlock(&local->sta_mtx); | ||
| 763 | ht_dbg(sdata, "Could not find station: %pM\n", ra); | 771 | ht_dbg(sdata, "Could not find station: %pM\n", ra); |
| 764 | return; | 772 | return NULL; |
| 765 | } | 773 | } |
| 766 | 774 | ||
| 767 | mutex_lock(&sta->ampdu_mlme.mtx); | 775 | tid_tx = rcu_dereference((*sta)->ampdu_mlme.tid_tx[tid]); |
| 768 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | ||
| 769 | 776 | ||
| 770 | if (WARN_ON(!tid_tx)) { | 777 | if (WARN_ON(!tid_tx)) |
| 771 | ht_dbg(sdata, "addBA was not requested!\n"); | 778 | ht_dbg(sdata, "addBA was not requested!\n"); |
| 772 | goto unlock; | ||
| 773 | } | ||
| 774 | 779 | ||
| 775 | if (WARN_ON(test_and_set_bit(HT_AGG_STATE_DRV_READY, &tid_tx->state))) | 780 | return tid_tx; |
| 776 | goto unlock; | ||
| 777 | |||
| 778 | if (test_bit(HT_AGG_STATE_RESPONSE_RECEIVED, &tid_tx->state)) | ||
| 779 | ieee80211_agg_tx_operational(local, sta, tid); | ||
| 780 | |||
| 781 | unlock: | ||
| 782 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
| 783 | mutex_unlock(&local->sta_mtx); | ||
| 784 | } | 781 | } |
| 785 | 782 | ||
| 786 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, | 783 | void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
| @@ -788,19 +785,20 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, | |||
| 788 | { | 785 | { |
| 789 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 786 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
| 790 | struct ieee80211_local *local = sdata->local; | 787 | struct ieee80211_local *local = sdata->local; |
| 791 | struct ieee80211_ra_tid *ra_tid; | 788 | struct sta_info *sta; |
| 792 | struct sk_buff *skb = dev_alloc_skb(0); | 789 | struct tid_ampdu_tx *tid_tx; |
| 793 | 790 | ||
| 794 | if (unlikely(!skb)) | 791 | trace_api_start_tx_ba_cb(sdata, ra, tid); |
| 795 | return; | ||
| 796 | 792 | ||
| 797 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 793 | rcu_read_lock(); |
| 798 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 794 | tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); |
| 799 | ra_tid->tid = tid; | 795 | if (!tid_tx) |
| 796 | goto out; | ||
| 800 | 797 | ||
| 801 | skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_START; | 798 | set_bit(HT_AGG_STATE_START_CB, &tid_tx->state); |
| 802 | skb_queue_tail(&sdata->skb_queue, skb); | 799 | ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); |
| 803 | ieee80211_queue_work(&local->hw, &sdata->work); | 800 | out: |
| 801 | rcu_read_unlock(); | ||
| 804 | } | 802 | } |
| 805 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); | 803 | EXPORT_SYMBOL(ieee80211_start_tx_ba_cb_irqsafe); |
| 806 | 804 | ||
| @@ -860,37 +858,18 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid) | |||
| 860 | } | 858 | } |
| 861 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); | 859 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_session); |
| 862 | 860 | ||
| 863 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | 861 | void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, |
| 862 | struct tid_ampdu_tx *tid_tx) | ||
| 864 | { | 863 | { |
| 865 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 864 | struct ieee80211_sub_if_data *sdata = sta->sdata; |
| 866 | struct ieee80211_local *local = sdata->local; | ||
| 867 | struct sta_info *sta; | ||
| 868 | struct tid_ampdu_tx *tid_tx; | ||
| 869 | bool send_delba = false; | 865 | bool send_delba = false; |
| 870 | 866 | ||
| 871 | trace_api_stop_tx_ba_cb(sdata, ra, tid); | 867 | ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", |
| 872 | 868 | sta->sta.addr, tid); | |
| 873 | if (tid >= IEEE80211_NUM_TIDS) { | ||
| 874 | ht_dbg(sdata, "Bad TID value: tid = %d (>= %d)\n", | ||
| 875 | tid, IEEE80211_NUM_TIDS); | ||
| 876 | return; | ||
| 877 | } | ||
| 878 | |||
| 879 | ht_dbg(sdata, "Stopping Tx BA session for %pM tid %d\n", ra, tid); | ||
| 880 | |||
| 881 | mutex_lock(&local->sta_mtx); | ||
| 882 | |||
| 883 | sta = sta_info_get_bss(sdata, ra); | ||
| 884 | if (!sta) { | ||
| 885 | ht_dbg(sdata, "Could not find station: %pM\n", ra); | ||
| 886 | goto unlock; | ||
| 887 | } | ||
| 888 | 869 | ||
| 889 | mutex_lock(&sta->ampdu_mlme.mtx); | ||
| 890 | spin_lock_bh(&sta->lock); | 870 | spin_lock_bh(&sta->lock); |
| 891 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | ||
| 892 | 871 | ||
| 893 | if (!tid_tx || !test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { | 872 | if (!test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) { |
| 894 | ht_dbg(sdata, | 873 | ht_dbg(sdata, |
| 895 | "unexpected callback to A-MPDU stop for %pM tid %d\n", | 874 | "unexpected callback to A-MPDU stop for %pM tid %d\n", |
| 896 | sta->sta.addr, tid); | 875 | sta->sta.addr, tid); |
| @@ -906,12 +885,8 @@ void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid) | |||
| 906 | spin_unlock_bh(&sta->lock); | 885 | spin_unlock_bh(&sta->lock); |
| 907 | 886 | ||
| 908 | if (send_delba) | 887 | if (send_delba) |
| 909 | ieee80211_send_delba(sdata, ra, tid, | 888 | ieee80211_send_delba(sdata, sta->sta.addr, tid, |
| 910 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); | 889 | WLAN_BACK_INITIATOR, WLAN_REASON_QSTA_NOT_USE); |
| 911 | |||
| 912 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
| 913 | unlock: | ||
| 914 | mutex_unlock(&local->sta_mtx); | ||
| 915 | } | 890 | } |
| 916 | 891 | ||
| 917 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, | 892 | void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, |
| @@ -919,19 +894,20 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif, | |||
| 919 | { | 894 | { |
| 920 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); | 895 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); |
| 921 | struct ieee80211_local *local = sdata->local; | 896 | struct ieee80211_local *local = sdata->local; |
| 922 | struct ieee80211_ra_tid *ra_tid; | 897 | struct sta_info *sta; |
| 923 | struct sk_buff *skb = dev_alloc_skb(0); | 898 | struct tid_ampdu_tx *tid_tx; |
| 924 | 899 | ||
| 925 | if (unlikely(!skb)) | 900 | trace_api_stop_tx_ba_cb(sdata, ra, tid); |
| 926 | return; | ||
| 927 | 901 | ||
| 928 | ra_tid = (struct ieee80211_ra_tid *) &skb->cb; | 902 | rcu_read_lock(); |
| 929 | memcpy(&ra_tid->ra, ra, ETH_ALEN); | 903 | tid_tx = ieee80211_lookup_tid_tx(sdata, ra, tid, &sta); |
| 930 | ra_tid->tid = tid; | 904 | if (!tid_tx) |
| 905 | goto out; | ||
| 931 | 906 | ||
| 932 | skb->pkt_type = IEEE80211_SDATA_QUEUE_AGG_STOP; | 907 | set_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state); |
| 933 | skb_queue_tail(&sdata->skb_queue, skb); | 908 | ieee80211_queue_work(&local->hw, &sta->ampdu_mlme.work); |
| 934 | ieee80211_queue_work(&local->hw, &sdata->work); | 909 | out: |
| 910 | rcu_read_unlock(); | ||
| 935 | } | 911 | } |
| 936 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); | 912 | EXPORT_SYMBOL(ieee80211_stop_tx_ba_cb_irqsafe); |
| 937 | 913 | ||
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index f4a528773563..6ca5442b1e03 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> | 7 | * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz> |
| 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> | 8 | * Copyright 2007, Michael Wu <flamingice@sourmilk.net> |
| 9 | * Copyright 2007-2010, Intel Corporation | 9 | * Copyright 2007-2010, Intel Corporation |
| 10 | * Copyright 2017 Intel Deutschland GmbH | ||
| 10 | * | 11 | * |
| 11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
| 12 | * it under the terms of the GNU General Public License version 2 as | 13 | * it under the terms of the GNU General Public License version 2 as |
| @@ -289,8 +290,6 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, | |||
| 289 | { | 290 | { |
| 290 | int i; | 291 | int i; |
| 291 | 292 | ||
| 292 | cancel_work_sync(&sta->ampdu_mlme.work); | ||
| 293 | |||
| 294 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 293 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { |
| 295 | __ieee80211_stop_tx_ba_session(sta, i, reason); | 294 | __ieee80211_stop_tx_ba_session(sta, i, reason); |
| 296 | __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, | 295 | __ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, |
| @@ -298,6 +297,9 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, | |||
| 298 | reason != AGG_STOP_DESTROY_STA && | 297 | reason != AGG_STOP_DESTROY_STA && |
| 299 | reason != AGG_STOP_PEER_REQUEST); | 298 | reason != AGG_STOP_PEER_REQUEST); |
| 300 | } | 299 | } |
| 300 | |||
| 301 | /* stopping might queue the work again - so cancel only afterwards */ | ||
| 302 | cancel_work_sync(&sta->ampdu_mlme.work); | ||
| 301 | } | 303 | } |
| 302 | 304 | ||
| 303 | void ieee80211_ba_session_work(struct work_struct *work) | 305 | void ieee80211_ba_session_work(struct work_struct *work) |
| @@ -352,10 +354,16 @@ void ieee80211_ba_session_work(struct work_struct *work) | |||
| 352 | spin_unlock_bh(&sta->lock); | 354 | spin_unlock_bh(&sta->lock); |
| 353 | 355 | ||
| 354 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); | 356 | tid_tx = rcu_dereference_protected_tid_tx(sta, tid); |
| 355 | if (tid_tx && test_and_clear_bit(HT_AGG_STATE_WANT_STOP, | 357 | if (!tid_tx) |
| 356 | &tid_tx->state)) | 358 | continue; |
| 359 | |||
| 360 | if (test_and_clear_bit(HT_AGG_STATE_START_CB, &tid_tx->state)) | ||
| 361 | ieee80211_start_tx_ba_cb(sta, tid, tid_tx); | ||
| 362 | if (test_and_clear_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state)) | ||
| 357 | ___ieee80211_stop_tx_ba_session(sta, tid, | 363 | ___ieee80211_stop_tx_ba_session(sta, tid, |
| 358 | AGG_STOP_LOCAL_REQUEST); | 364 | AGG_STOP_LOCAL_REQUEST); |
| 365 | if (test_and_clear_bit(HT_AGG_STATE_STOP_CB, &tid_tx->state)) | ||
| 366 | ieee80211_stop_tx_ba_cb(sta, tid, tid_tx); | ||
| 359 | } | 367 | } |
| 360 | mutex_unlock(&sta->ampdu_mlme.mtx); | 368 | mutex_unlock(&sta->ampdu_mlme.mtx); |
| 361 | } | 369 | } |
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index f8f6c148f554..665501ac358f 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -1036,8 +1036,6 @@ struct ieee80211_rx_agg { | |||
| 1036 | 1036 | ||
| 1037 | enum sdata_queue_type { | 1037 | enum sdata_queue_type { |
| 1038 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, | 1038 | IEEE80211_SDATA_QUEUE_TYPE_FRAME = 0, |
| 1039 | IEEE80211_SDATA_QUEUE_AGG_START = 1, | ||
| 1040 | IEEE80211_SDATA_QUEUE_AGG_STOP = 2, | ||
| 1041 | IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, | 1039 | IEEE80211_SDATA_QUEUE_RX_AGG_START = 3, |
| 1042 | IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, | 1040 | IEEE80211_SDATA_QUEUE_RX_AGG_STOP = 4, |
| 1043 | }; | 1041 | }; |
| @@ -1427,12 +1425,6 @@ ieee80211_get_sband(struct ieee80211_sub_if_data *sdata) | |||
| 1427 | return local->hw.wiphy->bands[band]; | 1425 | return local->hw.wiphy->bands[band]; |
| 1428 | } | 1426 | } |
| 1429 | 1427 | ||
| 1430 | /* this struct represents 802.11n's RA/TID combination */ | ||
| 1431 | struct ieee80211_ra_tid { | ||
| 1432 | u8 ra[ETH_ALEN]; | ||
| 1433 | u16 tid; | ||
| 1434 | }; | ||
| 1435 | |||
| 1436 | /* this struct holds the value parsing from channel switch IE */ | 1428 | /* this struct holds the value parsing from channel switch IE */ |
| 1437 | struct ieee80211_csa_ie { | 1429 | struct ieee80211_csa_ie { |
| 1438 | struct cfg80211_chan_def chandef; | 1430 | struct cfg80211_chan_def chandef; |
| @@ -1794,8 +1786,10 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | |||
| 1794 | enum ieee80211_agg_stop_reason reason); | 1786 | enum ieee80211_agg_stop_reason reason); |
| 1795 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, | 1787 | int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid, |
| 1796 | enum ieee80211_agg_stop_reason reason); | 1788 | enum ieee80211_agg_stop_reason reason); |
| 1797 | void ieee80211_start_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u16 tid); | 1789 | void ieee80211_start_tx_ba_cb(struct sta_info *sta, int tid, |
| 1798 | void ieee80211_stop_tx_ba_cb(struct ieee80211_vif *vif, u8 *ra, u8 tid); | 1790 | struct tid_ampdu_tx *tid_tx); |
| 1791 | void ieee80211_stop_tx_ba_cb(struct sta_info *sta, int tid, | ||
| 1792 | struct tid_ampdu_tx *tid_tx); | ||
| 1799 | void ieee80211_ba_session_work(struct work_struct *work); | 1793 | void ieee80211_ba_session_work(struct work_struct *work); |
| 1800 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); | 1794 | void ieee80211_tx_ba_session_handle_start(struct sta_info *sta, int tid); |
| 1801 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); | 1795 | void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 3bd5b81f5d81..8fae1a72e6a7 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1237,7 +1237,6 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
| 1237 | struct ieee80211_local *local = sdata->local; | 1237 | struct ieee80211_local *local = sdata->local; |
| 1238 | struct sk_buff *skb; | 1238 | struct sk_buff *skb; |
| 1239 | struct sta_info *sta; | 1239 | struct sta_info *sta; |
| 1240 | struct ieee80211_ra_tid *ra_tid; | ||
| 1241 | struct ieee80211_rx_agg *rx_agg; | 1240 | struct ieee80211_rx_agg *rx_agg; |
| 1242 | 1241 | ||
| 1243 | if (!ieee80211_sdata_running(sdata)) | 1242 | if (!ieee80211_sdata_running(sdata)) |
| @@ -1253,15 +1252,7 @@ static void ieee80211_iface_work(struct work_struct *work) | |||
| 1253 | while ((skb = skb_dequeue(&sdata->skb_queue))) { | 1252 | while ((skb = skb_dequeue(&sdata->skb_queue))) { |
| 1254 | struct ieee80211_mgmt *mgmt = (void *)skb->data; | 1253 | struct ieee80211_mgmt *mgmt = (void *)skb->data; |
| 1255 | 1254 | ||
| 1256 | if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_START) { | 1255 | if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { |
| 1257 | ra_tid = (void *)&skb->cb; | ||
| 1258 | ieee80211_start_tx_ba_cb(&sdata->vif, ra_tid->ra, | ||
| 1259 | ra_tid->tid); | ||
| 1260 | } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_AGG_STOP) { | ||
| 1261 | ra_tid = (void *)&skb->cb; | ||
| 1262 | ieee80211_stop_tx_ba_cb(&sdata->vif, ra_tid->ra, | ||
| 1263 | ra_tid->tid); | ||
| 1264 | } else if (skb->pkt_type == IEEE80211_SDATA_QUEUE_RX_AGG_START) { | ||
| 1265 | rx_agg = (void *)&skb->cb; | 1256 | rx_agg = (void *)&skb->cb; |
| 1266 | mutex_lock(&local->sta_mtx); | 1257 | mutex_lock(&local->sta_mtx); |
| 1267 | sta = sta_info_get_bss(sdata, rx_agg->addr); | 1258 | sta = sta_info_get_bss(sdata, rx_agg->addr); |
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c index 7cdf7a835bb0..403e3cc58b57 100644 --- a/net/mac80211/sta_info.c +++ b/net/mac80211/sta_info.c | |||
| @@ -2155,7 +2155,7 @@ void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) | |||
| 2155 | struct ieee80211_sta_rx_stats *cpurxs; | 2155 | struct ieee80211_sta_rx_stats *cpurxs; |
| 2156 | 2156 | ||
| 2157 | cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); | 2157 | cpurxs = per_cpu_ptr(sta->pcpu_rx_stats, cpu); |
| 2158 | sinfo->rx_packets += cpurxs->dropped; | 2158 | sinfo->rx_dropped_misc += cpurxs->dropped; |
| 2159 | } | 2159 | } |
| 2160 | } | 2160 | } |
| 2161 | 2161 | ||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 5609cacb20d5..ea0747d6a6da 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
| @@ -116,6 +116,8 @@ enum ieee80211_sta_info_flags { | |||
| 116 | #define HT_AGG_STATE_STOPPING 3 | 116 | #define HT_AGG_STATE_STOPPING 3 |
| 117 | #define HT_AGG_STATE_WANT_START 4 | 117 | #define HT_AGG_STATE_WANT_START 4 |
| 118 | #define HT_AGG_STATE_WANT_STOP 5 | 118 | #define HT_AGG_STATE_WANT_STOP 5 |
| 119 | #define HT_AGG_STATE_START_CB 6 | ||
| 120 | #define HT_AGG_STATE_STOP_CB 7 | ||
| 119 | 121 | ||
| 120 | enum ieee80211_agg_stop_reason { | 122 | enum ieee80211_agg_stop_reason { |
| 121 | AGG_STOP_DECLINED, | 123 | AGG_STOP_DECLINED, |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 257ec66009da..7b05fd1497ce 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
| @@ -1418,7 +1418,7 @@ static void mpls_ifup(struct net_device *dev, unsigned int flags) | |||
| 1418 | continue; | 1418 | continue; |
| 1419 | alive++; | 1419 | alive++; |
| 1420 | nh_flags &= ~flags; | 1420 | nh_flags &= ~flags; |
| 1421 | WRITE_ONCE(nh->nh_flags, flags); | 1421 | WRITE_ONCE(nh->nh_flags, nh_flags); |
| 1422 | } endfor_nexthops(rt); | 1422 | } endfor_nexthops(rt); |
| 1423 | 1423 | ||
| 1424 | WRITE_ONCE(rt->rt_nhn_alive, alive); | 1424 | WRITE_ONCE(rt->rt_nhn_alive, alive); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 9799a50bc604..a8be9b72e6cd 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
| @@ -890,8 +890,13 @@ restart: | |||
| 890 | } | 890 | } |
| 891 | out: | 891 | out: |
| 892 | local_bh_enable(); | 892 | local_bh_enable(); |
| 893 | if (last) | 893 | if (last) { |
| 894 | /* nf ct hash resize happened, now clear the leftover. */ | ||
| 895 | if ((struct nf_conn *)cb->args[1] == last) | ||
| 896 | cb->args[1] = 0; | ||
| 897 | |||
| 894 | nf_ct_put(last); | 898 | nf_ct_put(last); |
| 899 | } | ||
| 895 | 900 | ||
| 896 | while (i) { | 901 | while (i) { |
| 897 | i--; | 902 | i--; |
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c index 13875d599a85..1c5b14a6cab3 100644 --- a/net/netfilter/nf_conntrack_proto_sctp.c +++ b/net/netfilter/nf_conntrack_proto_sctp.c | |||
| @@ -512,16 +512,19 @@ static int sctp_error(struct net *net, struct nf_conn *tpl, struct sk_buff *skb, | |||
| 512 | u8 pf, unsigned int hooknum) | 512 | u8 pf, unsigned int hooknum) |
| 513 | { | 513 | { |
| 514 | const struct sctphdr *sh; | 514 | const struct sctphdr *sh; |
| 515 | struct sctphdr _sctph; | ||
| 516 | const char *logmsg; | 515 | const char *logmsg; |
| 517 | 516 | ||
| 518 | sh = skb_header_pointer(skb, dataoff, sizeof(_sctph), &_sctph); | 517 | if (skb->len < dataoff + sizeof(struct sctphdr)) { |
| 519 | if (!sh) { | ||
| 520 | logmsg = "nf_ct_sctp: short packet "; | 518 | logmsg = "nf_ct_sctp: short packet "; |
| 521 | goto out_invalid; | 519 | goto out_invalid; |
| 522 | } | 520 | } |
| 523 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && | 521 | if (net->ct.sysctl_checksum && hooknum == NF_INET_PRE_ROUTING && |
| 524 | skb->ip_summed == CHECKSUM_NONE) { | 522 | skb->ip_summed == CHECKSUM_NONE) { |
| 523 | if (!skb_make_writable(skb, dataoff + sizeof(struct sctphdr))) { | ||
| 524 | logmsg = "nf_ct_sctp: failed to read header "; | ||
| 525 | goto out_invalid; | ||
| 526 | } | ||
| 527 | sh = (const struct sctphdr *)(skb->data + dataoff); | ||
| 525 | if (sh->checksum != sctp_compute_cksum(skb, dataoff)) { | 528 | if (sh->checksum != sctp_compute_cksum(skb, dataoff)) { |
| 526 | logmsg = "nf_ct_sctp: bad CRC "; | 529 | logmsg = "nf_ct_sctp: bad CRC "; |
| 527 | goto out_invalid; | 530 | goto out_invalid; |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index ef0be325a0c6..6c72922d20ca 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
| @@ -566,7 +566,7 @@ static int nf_nat_proto_clean(struct nf_conn *ct, void *data) | |||
| 566 | * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack() | 566 | * Else, when the conntrack is destoyed, nf_nat_cleanup_conntrack() |
| 567 | * will delete entry from already-freed table. | 567 | * will delete entry from already-freed table. |
| 568 | */ | 568 | */ |
| 569 | ct->status &= ~IPS_NAT_DONE_MASK; | 569 | clear_bit(IPS_SRC_NAT_DONE_BIT, &ct->status); |
| 570 | rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, | 570 | rhltable_remove(&nf_nat_bysource_table, &ct->nat_bysource, |
| 571 | nf_nat_bysource_params); | 571 | nf_nat_bysource_params); |
| 572 | 572 | ||
diff --git a/net/netfilter/nft_set_rbtree.c b/net/netfilter/nft_set_rbtree.c index e97e2fb53f0a..fbdbaa00dd5f 100644 --- a/net/netfilter/nft_set_rbtree.c +++ b/net/netfilter/nft_set_rbtree.c | |||
| @@ -116,17 +116,17 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, | |||
| 116 | else if (d > 0) | 116 | else if (d > 0) |
| 117 | p = &parent->rb_right; | 117 | p = &parent->rb_right; |
| 118 | else { | 118 | else { |
| 119 | if (nft_set_elem_active(&rbe->ext, genmask)) { | 119 | if (nft_rbtree_interval_end(rbe) && |
| 120 | if (nft_rbtree_interval_end(rbe) && | 120 | !nft_rbtree_interval_end(new)) { |
| 121 | !nft_rbtree_interval_end(new)) | 121 | p = &parent->rb_left; |
| 122 | p = &parent->rb_left; | 122 | } else if (!nft_rbtree_interval_end(rbe) && |
| 123 | else if (!nft_rbtree_interval_end(rbe) && | 123 | nft_rbtree_interval_end(new)) { |
| 124 | nft_rbtree_interval_end(new)) | 124 | p = &parent->rb_right; |
| 125 | p = &parent->rb_right; | 125 | } else if (nft_set_elem_active(&rbe->ext, genmask)) { |
| 126 | else { | 126 | *ext = &rbe->ext; |
| 127 | *ext = &rbe->ext; | 127 | return -EEXIST; |
| 128 | return -EEXIST; | 128 | } else { |
| 129 | } | 129 | p = &parent->rb_left; |
| 130 | } | 130 | } |
| 131 | } | 131 | } |
| 132 | } | 132 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index ee841f00a6ec..7586d446d7dc 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -62,6 +62,7 @@ | |||
| 62 | #include <asm/cacheflush.h> | 62 | #include <asm/cacheflush.h> |
| 63 | #include <linux/hash.h> | 63 | #include <linux/hash.h> |
| 64 | #include <linux/genetlink.h> | 64 | #include <linux/genetlink.h> |
| 65 | #include <linux/net_namespace.h> | ||
| 65 | 66 | ||
| 66 | #include <net/net_namespace.h> | 67 | #include <net/net_namespace.h> |
| 67 | #include <net/sock.h> | 68 | #include <net/sock.h> |
| @@ -1415,7 +1416,8 @@ static void do_one_broadcast(struct sock *sk, | |||
| 1415 | goto out; | 1416 | goto out; |
| 1416 | } | 1417 | } |
| 1417 | NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net); | 1418 | NETLINK_CB(p->skb2).nsid = peernet2id(sock_net(sk), p->net); |
| 1418 | NETLINK_CB(p->skb2).nsid_is_set = true; | 1419 | if (NETLINK_CB(p->skb2).nsid != NETNSA_NSID_NOT_ASSIGNED) |
| 1420 | NETLINK_CB(p->skb2).nsid_is_set = true; | ||
| 1419 | val = netlink_broadcast_deliver(sk, p->skb2); | 1421 | val = netlink_broadcast_deliver(sk, p->skb2); |
| 1420 | if (val < 0) { | 1422 | if (val < 0) { |
| 1421 | netlink_overrun(sk); | 1423 | netlink_overrun(sk); |
diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c index 24fedd4b117e..03f6b5840764 100644 --- a/net/sunrpc/xprtrdma/backchannel.c +++ b/net/sunrpc/xprtrdma/backchannel.c | |||
| @@ -119,11 +119,9 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs) | |||
| 119 | 119 | ||
| 120 | for (i = 0; i < (reqs << 1); i++) { | 120 | for (i = 0; i < (reqs << 1); i++) { |
| 121 | rqst = kzalloc(sizeof(*rqst), GFP_KERNEL); | 121 | rqst = kzalloc(sizeof(*rqst), GFP_KERNEL); |
| 122 | if (!rqst) { | 122 | if (!rqst) |
| 123 | pr_err("RPC: %s: Failed to create bc rpc_rqst\n", | ||
| 124 | __func__); | ||
| 125 | goto out_free; | 123 | goto out_free; |
| 126 | } | 124 | |
| 127 | dprintk("RPC: %s: new rqst %p\n", __func__, rqst); | 125 | dprintk("RPC: %s: new rqst %p\n", __func__, rqst); |
| 128 | 126 | ||
| 129 | rqst->rq_xprt = &r_xprt->rx_xprt; | 127 | rqst->rq_xprt = &r_xprt->rx_xprt; |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 16aff8ddc16f..d5b54c020dec 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -2432,7 +2432,12 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
| 2432 | case -ENETUNREACH: | 2432 | case -ENETUNREACH: |
| 2433 | case -EADDRINUSE: | 2433 | case -EADDRINUSE: |
| 2434 | case -ENOBUFS: | 2434 | case -ENOBUFS: |
| 2435 | /* retry with existing socket, after a delay */ | 2435 | /* |
| 2436 | * xs_tcp_force_close() wakes tasks with -EIO. | ||
| 2437 | * We need to wake them first to ensure the | ||
| 2438 | * correct error code. | ||
| 2439 | */ | ||
| 2440 | xprt_wake_pending_tasks(xprt, status); | ||
| 2436 | xs_tcp_force_close(xprt); | 2441 | xs_tcp_force_close(xprt); |
| 2437 | goto out; | 2442 | goto out; |
| 2438 | } | 2443 | } |
