diff options
| author | David S. Miller <davem@davemloft.net> | 2019-04-17 14:26:25 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-04-17 14:26:25 -0400 |
| commit | 6b0a7f84ea1fe248df96ccc4dd86e817e32ef65b (patch) | |
| tree | 0a7976054052e793da782c2b7ec34eccfbf66449 /net | |
| parent | cea0aa9cbd5ad4efe267e9487ed5d48d16756253 (diff) | |
| parent | fe5cdef29e41c8bda8cd1a11545e7c6bfe25570e (diff) | |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflict resolution of af_smc.c from Stephen Rothwell.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
58 files changed, 460 insertions, 258 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c index d7f5cf5b7594..ad4f829193f0 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
| @@ -710,7 +710,10 @@ static int lec_vcc_attach(struct atm_vcc *vcc, void __user *arg) | |||
| 710 | 710 | ||
| 711 | static int lec_mcast_attach(struct atm_vcc *vcc, int arg) | 711 | static int lec_mcast_attach(struct atm_vcc *vcc, int arg) |
| 712 | { | 712 | { |
| 713 | if (arg < 0 || arg >= MAX_LEC_ITF || !dev_lec[arg]) | 713 | if (arg < 0 || arg >= MAX_LEC_ITF) |
| 714 | return -EINVAL; | ||
| 715 | arg = array_index_nospec(arg, MAX_LEC_ITF); | ||
| 716 | if (!dev_lec[arg]) | ||
| 714 | return -EINVAL; | 717 | return -EINVAL; |
| 715 | vcc->proto_data = dev_lec[arg]; | 718 | vcc->proto_data = dev_lec[arg]; |
| 716 | return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); | 719 | return lec_mcast_make(netdev_priv(dev_lec[arg]), vcc); |
| @@ -728,6 +731,7 @@ static int lecd_attach(struct atm_vcc *vcc, int arg) | |||
| 728 | i = arg; | 731 | i = arg; |
| 729 | if (arg >= MAX_LEC_ITF) | 732 | if (arg >= MAX_LEC_ITF) |
| 730 | return -EINVAL; | 733 | return -EINVAL; |
| 734 | i = array_index_nospec(arg, MAX_LEC_ITF); | ||
| 731 | if (!dev_lec[i]) { | 735 | if (!dev_lec[i]) { |
| 732 | int size; | 736 | int size; |
| 733 | 737 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index 9a580999ca57..d892b7c3cc42 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
| @@ -523,12 +523,12 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, | |||
| 523 | struct sock *sk = sock->sk; | 523 | struct sock *sk = sock->sk; |
| 524 | int err = 0; | 524 | int err = 0; |
| 525 | 525 | ||
| 526 | BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr); | ||
| 527 | |||
| 528 | if (!addr || addr_len < sizeof(struct sockaddr_sco) || | 526 | if (!addr || addr_len < sizeof(struct sockaddr_sco) || |
| 529 | addr->sa_family != AF_BLUETOOTH) | 527 | addr->sa_family != AF_BLUETOOTH) |
| 530 | return -EINVAL; | 528 | return -EINVAL; |
| 531 | 529 | ||
| 530 | BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr); | ||
| 531 | |||
| 532 | lock_sock(sk); | 532 | lock_sock(sk); |
| 533 | 533 | ||
| 534 | if (sk->sk_state != BT_OPEN) { | 534 | if (sk->sk_state != BT_OPEN) { |
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index 86dc46f6a68f..014af7efef25 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c | |||
| @@ -196,13 +196,10 @@ static void __br_handle_local_finish(struct sk_buff *skb) | |||
| 196 | /* note: already called with rcu_read_lock */ | 196 | /* note: already called with rcu_read_lock */ |
| 197 | static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | 197 | static int br_handle_local_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
| 198 | { | 198 | { |
| 199 | struct net_bridge_port *p = br_port_get_rcu(skb->dev); | ||
| 200 | |||
| 201 | __br_handle_local_finish(skb); | 199 | __br_handle_local_finish(skb); |
| 202 | 200 | ||
| 203 | BR_INPUT_SKB_CB(skb)->brdev = p->br->dev; | 201 | /* return 1 to signal the okfn() was called so it's ok to use the skb */ |
| 204 | br_pass_frame_up(skb); | 202 | return 1; |
| 205 | return 0; | ||
| 206 | } | 203 | } |
| 207 | 204 | ||
| 208 | static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb) | 205 | static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb) |
| @@ -333,10 +330,18 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb) | |||
| 333 | goto forward; | 330 | goto forward; |
| 334 | } | 331 | } |
| 335 | 332 | ||
| 336 | /* Deliver packet to local host only */ | 333 | /* The else clause should be hit when nf_hook(): |
| 337 | NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, dev_net(skb->dev), | 334 | * - returns < 0 (drop/error) |
| 338 | NULL, skb, skb->dev, NULL, br_handle_local_finish); | 335 | * - returns = 0 (stolen/nf_queue) |
| 339 | return RX_HANDLER_CONSUMED; | 336 | * Thus return 1 from the okfn() to signal the skb is ok to pass |
| 337 | */ | ||
| 338 | if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, | ||
| 339 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, | ||
| 340 | br_handle_local_finish) == 1) { | ||
| 341 | return RX_HANDLER_PASS; | ||
| 342 | } else { | ||
| 343 | return RX_HANDLER_CONSUMED; | ||
| 344 | } | ||
| 340 | } | 345 | } |
| 341 | 346 | ||
| 342 | forward: | 347 | forward: |
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index 812560d7f7a2..c2a30f79a9d0 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c | |||
| @@ -2013,7 +2013,8 @@ static void br_multicast_start_querier(struct net_bridge *br, | |||
| 2013 | 2013 | ||
| 2014 | __br_multicast_open(br, query); | 2014 | __br_multicast_open(br, query); |
| 2015 | 2015 | ||
| 2016 | list_for_each_entry(port, &br->port_list, list) { | 2016 | rcu_read_lock(); |
| 2017 | list_for_each_entry_rcu(port, &br->port_list, list) { | ||
| 2017 | if (port->state == BR_STATE_DISABLED || | 2018 | if (port->state == BR_STATE_DISABLED || |
| 2018 | port->state == BR_STATE_BLOCKING) | 2019 | port->state == BR_STATE_BLOCKING) |
| 2019 | continue; | 2020 | continue; |
| @@ -2025,6 +2026,7 @@ static void br_multicast_start_querier(struct net_bridge *br, | |||
| 2025 | br_multicast_enable(&port->ip6_own_query); | 2026 | br_multicast_enable(&port->ip6_own_query); |
| 2026 | #endif | 2027 | #endif |
| 2027 | } | 2028 | } |
| 2029 | rcu_read_unlock(); | ||
| 2028 | } | 2030 | } |
| 2029 | 2031 | ||
| 2030 | int br_multicast_toggle(struct net_bridge *br, unsigned long val) | 2032 | int br_multicast_toggle(struct net_bridge *br, unsigned long val) |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 4f9f59eba8b4..8dfcc2d285d8 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
| @@ -1441,7 +1441,7 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) | |||
| 1441 | nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED, | 1441 | nla_put_u8(skb, IFLA_BR_VLAN_STATS_ENABLED, |
| 1442 | br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) || | 1442 | br_opt_get(br, BROPT_VLAN_STATS_ENABLED)) || |
| 1443 | nla_put_u8(skb, IFLA_BR_VLAN_STATS_PER_PORT, | 1443 | nla_put_u8(skb, IFLA_BR_VLAN_STATS_PER_PORT, |
| 1444 | br_opt_get(br, IFLA_BR_VLAN_STATS_PER_PORT))) | 1444 | br_opt_get(br, BROPT_VLAN_STATS_PER_PORT))) |
| 1445 | return -EMSGSIZE; | 1445 | return -EMSGSIZE; |
| 1446 | #endif | 1446 | #endif |
| 1447 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 1447 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
diff --git a/net/core/dev.c b/net/core/dev.c index b430f851f377..22f2640f559a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
| @@ -1184,7 +1184,21 @@ int dev_change_name(struct net_device *dev, const char *newname) | |||
| 1184 | BUG_ON(!dev_net(dev)); | 1184 | BUG_ON(!dev_net(dev)); |
| 1185 | 1185 | ||
| 1186 | net = dev_net(dev); | 1186 | net = dev_net(dev); |
| 1187 | if (dev->flags & IFF_UP) | 1187 | |
| 1188 | /* Some auto-enslaved devices e.g. failover slaves are | ||
| 1189 | * special, as userspace might rename the device after | ||
| 1190 | * the interface had been brought up and running since | ||
| 1191 | * the point kernel initiated auto-enslavement. Allow | ||
| 1192 | * live name change even when these slave devices are | ||
| 1193 | * up and running. | ||
| 1194 | * | ||
| 1195 | * Typically, users of these auto-enslaving devices | ||
| 1196 | * don't actually care about slave name change, as | ||
| 1197 | * they are supposed to operate on master interface | ||
| 1198 | * directly. | ||
| 1199 | */ | ||
| 1200 | if (dev->flags & IFF_UP && | ||
| 1201 | likely(!(dev->priv_flags & IFF_LIVE_RENAME_OK))) | ||
| 1188 | return -EBUSY; | 1202 | return -EBUSY; |
| 1189 | 1203 | ||
| 1190 | write_seqcount_begin(&devnet_rename_seq); | 1204 | write_seqcount_begin(&devnet_rename_seq); |
diff --git a/net/core/failover.c b/net/core/failover.c index 4a92a98ccce9..b5cd3c727285 100644 --- a/net/core/failover.c +++ b/net/core/failover.c | |||
| @@ -80,14 +80,14 @@ static int failover_slave_register(struct net_device *slave_dev) | |||
| 80 | goto err_upper_link; | 80 | goto err_upper_link; |
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | slave_dev->priv_flags |= IFF_FAILOVER_SLAVE; | 83 | slave_dev->priv_flags |= (IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); |
| 84 | 84 | ||
| 85 | if (fops && fops->slave_register && | 85 | if (fops && fops->slave_register && |
| 86 | !fops->slave_register(slave_dev, failover_dev)) | 86 | !fops->slave_register(slave_dev, failover_dev)) |
| 87 | return NOTIFY_OK; | 87 | return NOTIFY_OK; |
| 88 | 88 | ||
| 89 | netdev_upper_dev_unlink(slave_dev, failover_dev); | 89 | netdev_upper_dev_unlink(slave_dev, failover_dev); |
| 90 | slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; | 90 | slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); |
| 91 | err_upper_link: | 91 | err_upper_link: |
| 92 | netdev_rx_handler_unregister(slave_dev); | 92 | netdev_rx_handler_unregister(slave_dev); |
| 93 | done: | 93 | done: |
| @@ -121,7 +121,7 @@ int failover_slave_unregister(struct net_device *slave_dev) | |||
| 121 | 121 | ||
| 122 | netdev_rx_handler_unregister(slave_dev); | 122 | netdev_rx_handler_unregister(slave_dev); |
| 123 | netdev_upper_dev_unlink(slave_dev, failover_dev); | 123 | netdev_upper_dev_unlink(slave_dev, failover_dev); |
| 124 | slave_dev->priv_flags &= ~IFF_FAILOVER_SLAVE; | 124 | slave_dev->priv_flags &= ~(IFF_FAILOVER_SLAVE | IFF_LIVE_RENAME_OK); |
| 125 | 125 | ||
| 126 | if (fops && fops->slave_unregister && | 126 | if (fops && fops->slave_unregister && |
| 127 | !fops->slave_unregister(slave_dev, failover_dev)) | 127 | !fops->slave_unregister(slave_dev, failover_dev)) |
diff --git a/net/core/filter.c b/net/core/filter.c index 95a27fdf9a40..07687e2a2e66 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
| @@ -4462,6 +4462,8 @@ BPF_CALL_3(bpf_bind, struct bpf_sock_addr_kern *, ctx, struct sockaddr *, addr, | |||
| 4462 | * Only binding to IP is supported. | 4462 | * Only binding to IP is supported. |
| 4463 | */ | 4463 | */ |
| 4464 | err = -EINVAL; | 4464 | err = -EINVAL; |
| 4465 | if (addr_len < offsetofend(struct sockaddr, sa_family)) | ||
| 4466 | return err; | ||
| 4465 | if (addr->sa_family == AF_INET) { | 4467 | if (addr->sa_family == AF_INET) { |
| 4466 | if (addr_len < sizeof(struct sockaddr_in)) | 4468 | if (addr_len < sizeof(struct sockaddr_in)) |
| 4467 | return err; | 4469 | return err; |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index c14f0dc0157c..e4fd68389d6f 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
| @@ -1747,20 +1747,16 @@ int netdev_register_kobject(struct net_device *ndev) | |||
| 1747 | 1747 | ||
| 1748 | error = device_add(dev); | 1748 | error = device_add(dev); |
| 1749 | if (error) | 1749 | if (error) |
| 1750 | goto error_put_device; | 1750 | return error; |
| 1751 | 1751 | ||
| 1752 | error = register_queue_kobjects(ndev); | 1752 | error = register_queue_kobjects(ndev); |
| 1753 | if (error) | 1753 | if (error) { |
| 1754 | goto error_device_del; | 1754 | device_del(dev); |
| 1755 | return error; | ||
| 1756 | } | ||
| 1755 | 1757 | ||
| 1756 | pm_runtime_set_memalloc_noio(dev, true); | 1758 | pm_runtime_set_memalloc_noio(dev, true); |
| 1757 | 1759 | ||
| 1758 | return 0; | ||
| 1759 | |||
| 1760 | error_device_del: | ||
| 1761 | device_del(dev); | ||
| 1762 | error_put_device: | ||
| 1763 | put_device(dev); | ||
| 1764 | return error; | 1760 | return error; |
| 1765 | } | 1761 | } |
| 1766 | 1762 | ||
diff --git a/net/core/ptp_classifier.c b/net/core/ptp_classifier.c index 703cf76aa7c2..7109c168b5e0 100644 --- a/net/core/ptp_classifier.c +++ b/net/core/ptp_classifier.c | |||
| @@ -185,9 +185,10 @@ void __init ptp_classifier_init(void) | |||
| 185 | { 0x16, 0, 0, 0x00000000 }, | 185 | { 0x16, 0, 0, 0x00000000 }, |
| 186 | { 0x06, 0, 0, 0x00000000 }, | 186 | { 0x06, 0, 0, 0x00000000 }, |
| 187 | }; | 187 | }; |
| 188 | struct sock_fprog_kern ptp_prog = { | 188 | struct sock_fprog_kern ptp_prog; |
| 189 | .len = ARRAY_SIZE(ptp_filter), .filter = ptp_filter, | 189 | |
| 190 | }; | 190 | ptp_prog.len = ARRAY_SIZE(ptp_filter); |
| 191 | ptp_prog.filter = ptp_filter; | ||
| 191 | 192 | ||
| 192 | BUG_ON(bpf_prog_create(&ptp_insns, &ptp_prog)); | 193 | BUG_ON(bpf_prog_create(&ptp_insns, &ptp_prog)); |
| 193 | } | 194 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index f9b964fd4e4d..5fa5bf3e9945 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -4951,7 +4951,7 @@ static int rtnl_valid_stats_req(const struct nlmsghdr *nlh, bool strict_check, | |||
| 4951 | { | 4951 | { |
| 4952 | struct if_stats_msg *ifsm; | 4952 | struct if_stats_msg *ifsm; |
| 4953 | 4953 | ||
| 4954 | if (nlh->nlmsg_len < sizeof(*ifsm)) { | 4954 | if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifsm))) { |
| 4955 | NL_SET_ERR_MSG(extack, "Invalid header for stats dump"); | 4955 | NL_SET_ERR_MSG(extack, "Invalid header for stats dump"); |
| 4956 | return -EINVAL; | 4956 | return -EINVAL; |
| 4957 | } | 4957 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 9901f5322852..a083e188374f 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -5082,7 +5082,8 @@ EXPORT_SYMBOL_GPL(skb_gso_validate_mac_len); | |||
| 5082 | 5082 | ||
| 5083 | static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) | 5083 | static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) |
| 5084 | { | 5084 | { |
| 5085 | int mac_len; | 5085 | int mac_len, meta_len; |
| 5086 | void *meta; | ||
| 5086 | 5087 | ||
| 5087 | if (skb_cow(skb, skb_headroom(skb)) < 0) { | 5088 | if (skb_cow(skb, skb_headroom(skb)) < 0) { |
| 5088 | kfree_skb(skb); | 5089 | kfree_skb(skb); |
| @@ -5094,6 +5095,13 @@ static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) | |||
| 5094 | memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb), | 5095 | memmove(skb_mac_header(skb) + VLAN_HLEN, skb_mac_header(skb), |
| 5095 | mac_len - VLAN_HLEN - ETH_TLEN); | 5096 | mac_len - VLAN_HLEN - ETH_TLEN); |
| 5096 | } | 5097 | } |
| 5098 | |||
| 5099 | meta_len = skb_metadata_len(skb); | ||
| 5100 | if (meta_len) { | ||
| 5101 | meta = skb_metadata_end(skb) - meta_len; | ||
| 5102 | memmove(meta + VLAN_HLEN, meta, meta_len); | ||
| 5103 | } | ||
| 5104 | |||
| 5097 | skb->mac_header += VLAN_HLEN; | 5105 | skb->mac_header += VLAN_HLEN; |
| 5098 | return skb; | 5106 | return skb; |
| 5099 | } | 5107 | } |
diff --git a/net/core/sock.c b/net/core/sock.c index 782343bb925b..067878a1e4c5 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -348,7 +348,7 @@ static int sock_get_timeout(long timeo, void *optval, bool old_timeval) | |||
| 348 | tv.tv_usec = ((timeo % HZ) * USEC_PER_SEC) / HZ; | 348 | tv.tv_usec = ((timeo % HZ) * USEC_PER_SEC) / HZ; |
| 349 | } | 349 | } |
| 350 | 350 | ||
| 351 | if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { | 351 | if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { |
| 352 | struct old_timeval32 tv32 = { tv.tv_sec, tv.tv_usec }; | 352 | struct old_timeval32 tv32 = { tv.tv_sec, tv.tv_usec }; |
| 353 | *(struct old_timeval32 *)optval = tv32; | 353 | *(struct old_timeval32 *)optval = tv32; |
| 354 | return sizeof(tv32); | 354 | return sizeof(tv32); |
| @@ -372,7 +372,7 @@ static int sock_set_timeout(long *timeo_p, char __user *optval, int optlen, bool | |||
| 372 | { | 372 | { |
| 373 | struct __kernel_sock_timeval tv; | 373 | struct __kernel_sock_timeval tv; |
| 374 | 374 | ||
| 375 | if (in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { | 375 | if (old_timeval && in_compat_syscall() && !COMPAT_USE_64BIT_TIME) { |
| 376 | struct old_timeval32 tv32; | 376 | struct old_timeval32 tv32; |
| 377 | 377 | ||
| 378 | if (optlen < sizeof(tv32)) | 378 | if (optlen < sizeof(tv32)) |
diff --git a/net/ipv4/fou.c b/net/ipv4/fou.c index b038f563baa4..1ca1586a7e46 100644 --- a/net/ipv4/fou.c +++ b/net/ipv4/fou.c | |||
| @@ -121,6 +121,7 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
| 121 | struct guehdr *guehdr; | 121 | struct guehdr *guehdr; |
| 122 | void *data; | 122 | void *data; |
| 123 | u16 doffset = 0; | 123 | u16 doffset = 0; |
| 124 | u8 proto_ctype; | ||
| 124 | 125 | ||
| 125 | if (!fou) | 126 | if (!fou) |
| 126 | return 1; | 127 | return 1; |
| @@ -210,13 +211,14 @@ static int gue_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
| 210 | if (unlikely(guehdr->control)) | 211 | if (unlikely(guehdr->control)) |
| 211 | return gue_control_message(skb, guehdr); | 212 | return gue_control_message(skb, guehdr); |
| 212 | 213 | ||
| 214 | proto_ctype = guehdr->proto_ctype; | ||
| 213 | __skb_pull(skb, sizeof(struct udphdr) + hdrlen); | 215 | __skb_pull(skb, sizeof(struct udphdr) + hdrlen); |
| 214 | skb_reset_transport_header(skb); | 216 | skb_reset_transport_header(skb); |
| 215 | 217 | ||
| 216 | if (iptunnel_pull_offloads(skb)) | 218 | if (iptunnel_pull_offloads(skb)) |
| 217 | goto drop; | 219 | goto drop; |
| 218 | 220 | ||
| 219 | return -guehdr->proto_ctype; | 221 | return -proto_ctype; |
| 220 | 222 | ||
| 221 | drop: | 223 | drop: |
| 222 | kfree_skb(skb); | 224 | kfree_skb(skb); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index efa6a36cbfff..d9b5aa2290d6 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -1200,9 +1200,23 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie) | |||
| 1200 | 1200 | ||
| 1201 | static void ipv4_link_failure(struct sk_buff *skb) | 1201 | static void ipv4_link_failure(struct sk_buff *skb) |
| 1202 | { | 1202 | { |
| 1203 | struct ip_options opt; | ||
| 1203 | struct rtable *rt; | 1204 | struct rtable *rt; |
| 1205 | int res; | ||
| 1204 | 1206 | ||
| 1205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 1207 | /* Recompile ip options since IPCB may not be valid anymore. |
| 1208 | */ | ||
| 1209 | memset(&opt, 0, sizeof(opt)); | ||
| 1210 | opt.optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); | ||
| 1211 | |||
| 1212 | rcu_read_lock(); | ||
| 1213 | res = __ip_options_compile(dev_net(skb->dev), &opt, skb, NULL); | ||
| 1214 | rcu_read_unlock(); | ||
| 1215 | |||
| 1216 | if (res) | ||
| 1217 | return; | ||
| 1218 | |||
| 1219 | __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0, &opt); | ||
| 1206 | 1220 | ||
| 1207 | rt = skb_rtable(skb); | 1221 | rt = skb_rtable(skb); |
| 1208 | if (rt) | 1222 | if (rt) |
diff --git a/net/ipv4/tcp_dctcp.c b/net/ipv4/tcp_dctcp.c index 359da68d7c06..477cb4aa456c 100644 --- a/net/ipv4/tcp_dctcp.c +++ b/net/ipv4/tcp_dctcp.c | |||
| @@ -49,9 +49,8 @@ | |||
| 49 | #define DCTCP_MAX_ALPHA 1024U | 49 | #define DCTCP_MAX_ALPHA 1024U |
| 50 | 50 | ||
| 51 | struct dctcp { | 51 | struct dctcp { |
| 52 | u32 acked_bytes_ecn; | 52 | u32 old_delivered; |
| 53 | u32 acked_bytes_total; | 53 | u32 old_delivered_ce; |
| 54 | u32 prior_snd_una; | ||
| 55 | u32 prior_rcv_nxt; | 54 | u32 prior_rcv_nxt; |
| 56 | u32 dctcp_alpha; | 55 | u32 dctcp_alpha; |
| 57 | u32 next_seq; | 56 | u32 next_seq; |
| @@ -73,8 +72,8 @@ static void dctcp_reset(const struct tcp_sock *tp, struct dctcp *ca) | |||
| 73 | { | 72 | { |
| 74 | ca->next_seq = tp->snd_nxt; | 73 | ca->next_seq = tp->snd_nxt; |
| 75 | 74 | ||
| 76 | ca->acked_bytes_ecn = 0; | 75 | ca->old_delivered = tp->delivered; |
| 77 | ca->acked_bytes_total = 0; | 76 | ca->old_delivered_ce = tp->delivered_ce; |
| 78 | } | 77 | } |
| 79 | 78 | ||
| 80 | static void dctcp_init(struct sock *sk) | 79 | static void dctcp_init(struct sock *sk) |
| @@ -86,7 +85,6 @@ static void dctcp_init(struct sock *sk) | |||
| 86 | sk->sk_state == TCP_CLOSE)) { | 85 | sk->sk_state == TCP_CLOSE)) { |
| 87 | struct dctcp *ca = inet_csk_ca(sk); | 86 | struct dctcp *ca = inet_csk_ca(sk); |
| 88 | 87 | ||
| 89 | ca->prior_snd_una = tp->snd_una; | ||
| 90 | ca->prior_rcv_nxt = tp->rcv_nxt; | 88 | ca->prior_rcv_nxt = tp->rcv_nxt; |
| 91 | 89 | ||
| 92 | ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA); | 90 | ca->dctcp_alpha = min(dctcp_alpha_on_init, DCTCP_MAX_ALPHA); |
| @@ -118,37 +116,25 @@ static void dctcp_update_alpha(struct sock *sk, u32 flags) | |||
| 118 | { | 116 | { |
| 119 | const struct tcp_sock *tp = tcp_sk(sk); | 117 | const struct tcp_sock *tp = tcp_sk(sk); |
| 120 | struct dctcp *ca = inet_csk_ca(sk); | 118 | struct dctcp *ca = inet_csk_ca(sk); |
| 121 | u32 acked_bytes = tp->snd_una - ca->prior_snd_una; | ||
| 122 | |||
| 123 | /* If ack did not advance snd_una, count dupack as MSS size. | ||
| 124 | * If ack did update window, do not count it at all. | ||
| 125 | */ | ||
| 126 | if (acked_bytes == 0 && !(flags & CA_ACK_WIN_UPDATE)) | ||
| 127 | acked_bytes = inet_csk(sk)->icsk_ack.rcv_mss; | ||
| 128 | if (acked_bytes) { | ||
| 129 | ca->acked_bytes_total += acked_bytes; | ||
| 130 | ca->prior_snd_una = tp->snd_una; | ||
| 131 | |||
| 132 | if (flags & CA_ACK_ECE) | ||
| 133 | ca->acked_bytes_ecn += acked_bytes; | ||
| 134 | } | ||
| 135 | 119 | ||
| 136 | /* Expired RTT */ | 120 | /* Expired RTT */ |
| 137 | if (!before(tp->snd_una, ca->next_seq)) { | 121 | if (!before(tp->snd_una, ca->next_seq)) { |
| 138 | u64 bytes_ecn = ca->acked_bytes_ecn; | 122 | u32 delivered_ce = tp->delivered_ce - ca->old_delivered_ce; |
| 139 | u32 alpha = ca->dctcp_alpha; | 123 | u32 alpha = ca->dctcp_alpha; |
| 140 | 124 | ||
| 141 | /* alpha = (1 - g) * alpha + g * F */ | 125 | /* alpha = (1 - g) * alpha + g * F */ |
| 142 | 126 | ||
| 143 | alpha -= min_not_zero(alpha, alpha >> dctcp_shift_g); | 127 | alpha -= min_not_zero(alpha, alpha >> dctcp_shift_g); |
| 144 | if (bytes_ecn) { | 128 | if (delivered_ce) { |
| 129 | u32 delivered = tp->delivered - ca->old_delivered; | ||
| 130 | |||
| 145 | /* If dctcp_shift_g == 1, a 32bit value would overflow | 131 | /* If dctcp_shift_g == 1, a 32bit value would overflow |
| 146 | * after 8 Mbytes. | 132 | * after 8 M packets. |
| 147 | */ | 133 | */ |
| 148 | bytes_ecn <<= (10 - dctcp_shift_g); | 134 | delivered_ce <<= (10 - dctcp_shift_g); |
| 149 | do_div(bytes_ecn, max(1U, ca->acked_bytes_total)); | 135 | delivered_ce /= max(1U, delivered); |
| 150 | 136 | ||
| 151 | alpha = min(alpha + (u32)bytes_ecn, DCTCP_MAX_ALPHA); | 137 | alpha = min(alpha + delivered_ce, DCTCP_MAX_ALPHA); |
| 152 | } | 138 | } |
| 153 | /* dctcp_alpha can be read from dctcp_get_info() without | 139 | /* dctcp_alpha can be read from dctcp_get_info() without |
| 154 | * synchro, so we ask compiler to not use dctcp_alpha | 140 | * synchro, so we ask compiler to not use dctcp_alpha |
| @@ -200,6 +186,7 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, | |||
| 200 | union tcp_cc_info *info) | 186 | union tcp_cc_info *info) |
| 201 | { | 187 | { |
| 202 | const struct dctcp *ca = inet_csk_ca(sk); | 188 | const struct dctcp *ca = inet_csk_ca(sk); |
| 189 | const struct tcp_sock *tp = tcp_sk(sk); | ||
| 203 | 190 | ||
| 204 | /* Fill it also in case of VEGASINFO due to req struct limits. | 191 | /* Fill it also in case of VEGASINFO due to req struct limits. |
| 205 | * We can still correctly retrieve it later. | 192 | * We can still correctly retrieve it later. |
| @@ -211,8 +198,10 @@ static size_t dctcp_get_info(struct sock *sk, u32 ext, int *attr, | |||
| 211 | info->dctcp.dctcp_enabled = 1; | 198 | info->dctcp.dctcp_enabled = 1; |
| 212 | info->dctcp.dctcp_ce_state = (u16) ca->ce_state; | 199 | info->dctcp.dctcp_ce_state = (u16) ca->ce_state; |
| 213 | info->dctcp.dctcp_alpha = ca->dctcp_alpha; | 200 | info->dctcp.dctcp_alpha = ca->dctcp_alpha; |
| 214 | info->dctcp.dctcp_ab_ecn = ca->acked_bytes_ecn; | 201 | info->dctcp.dctcp_ab_ecn = tp->mss_cache * |
| 215 | info->dctcp.dctcp_ab_tot = ca->acked_bytes_total; | 202 | (tp->delivered_ce - ca->old_delivered_ce); |
| 203 | info->dctcp.dctcp_ab_tot = tp->mss_cache * | ||
| 204 | (tp->delivered - ca->old_delivered); | ||
| 216 | } | 205 | } |
| 217 | 206 | ||
| 218 | *attr = INET_DIAG_DCTCPINFO; | 207 | *attr = INET_DIAG_DCTCPINFO; |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6660ce2a7333..97671bff597a 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
| @@ -402,11 +402,12 @@ static int __tcp_grow_window(const struct sock *sk, const struct sk_buff *skb) | |||
| 402 | static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) | 402 | static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) |
| 403 | { | 403 | { |
| 404 | struct tcp_sock *tp = tcp_sk(sk); | 404 | struct tcp_sock *tp = tcp_sk(sk); |
| 405 | int room; | ||
| 406 | |||
| 407 | room = min_t(int, tp->window_clamp, tcp_space(sk)) - tp->rcv_ssthresh; | ||
| 405 | 408 | ||
| 406 | /* Check #1 */ | 409 | /* Check #1 */ |
| 407 | if (tp->rcv_ssthresh < tp->window_clamp && | 410 | if (room > 0 && !tcp_under_memory_pressure(sk)) { |
| 408 | (int)tp->rcv_ssthresh < tcp_space(sk) && | ||
| 409 | !tcp_under_memory_pressure(sk)) { | ||
| 410 | int incr; | 411 | int incr; |
| 411 | 412 | ||
| 412 | /* Check #2. Increase window, if skb with such overhead | 413 | /* Check #2. Increase window, if skb with such overhead |
| @@ -419,8 +420,7 @@ static void tcp_grow_window(struct sock *sk, const struct sk_buff *skb) | |||
| 419 | 420 | ||
| 420 | if (incr) { | 421 | if (incr) { |
| 421 | incr = max_t(int, incr, 2 * skb->len); | 422 | incr = max_t(int, incr, 2 * skb->len); |
| 422 | tp->rcv_ssthresh = min(tp->rcv_ssthresh + incr, | 423 | tp->rcv_ssthresh += min(room, incr); |
| 423 | tp->window_clamp); | ||
| 424 | inet_csk(sk)->icsk_ack.quick |= 1; | 424 | inet_csk(sk)->icsk_ack.quick |= 1; |
| 425 | } | 425 | } |
| 426 | } | 426 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index a77c004d67fb..9ece8067a59b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -2331,6 +2331,10 @@ static void __ip6_rt_update_pmtu(struct dst_entry *dst, const struct sock *sk, | |||
| 2331 | 2331 | ||
| 2332 | rcu_read_lock(); | 2332 | rcu_read_lock(); |
| 2333 | from = rcu_dereference(rt6->from); | 2333 | from = rcu_dereference(rt6->from); |
| 2334 | if (!from) { | ||
| 2335 | rcu_read_unlock(); | ||
| 2336 | return; | ||
| 2337 | } | ||
| 2334 | nrt6 = ip6_rt_cache_alloc(from, daddr, saddr); | 2338 | nrt6 = ip6_rt_cache_alloc(from, daddr, saddr); |
| 2335 | if (nrt6) { | 2339 | if (nrt6) { |
| 2336 | rt6_do_update_pmtu(nrt6, mtu); | 2340 | rt6_do_update_pmtu(nrt6, mtu); |
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c index d538fafaf4a9..2464fba569b4 100644 --- a/net/ipv6/udp.c +++ b/net/ipv6/udp.c | |||
| @@ -1045,6 +1045,8 @@ static void udp_v6_flush_pending_frames(struct sock *sk) | |||
| 1045 | static int udpv6_pre_connect(struct sock *sk, struct sockaddr *uaddr, | 1045 | static int udpv6_pre_connect(struct sock *sk, struct sockaddr *uaddr, |
| 1046 | int addr_len) | 1046 | int addr_len) |
| 1047 | { | 1047 | { |
| 1048 | if (addr_len < offsetofend(struct sockaddr, sa_family)) | ||
| 1049 | return -EINVAL; | ||
| 1048 | /* The following checks are replicated from __ip6_datagram_connect() | 1050 | /* The following checks are replicated from __ip6_datagram_connect() |
| 1049 | * and intended to prevent BPF program called below from accessing | 1051 | * and intended to prevent BPF program called below from accessing |
| 1050 | * bytes that are out of the bound specified by user in addr_len. | 1052 | * bytes that are out of the bound specified by user in addr_len. |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index b99e73a7e7e0..2017b7d780f5 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
| @@ -320,14 +320,13 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) | |||
| 320 | struct llc_sap *sap; | 320 | struct llc_sap *sap; |
| 321 | int rc = -EINVAL; | 321 | int rc = -EINVAL; |
| 322 | 322 | ||
| 323 | dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); | ||
| 324 | |||
| 325 | lock_sock(sk); | 323 | lock_sock(sk); |
| 326 | if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) | 324 | if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) |
| 327 | goto out; | 325 | goto out; |
| 328 | rc = -EAFNOSUPPORT; | 326 | rc = -EAFNOSUPPORT; |
| 329 | if (unlikely(addr->sllc_family != AF_LLC)) | 327 | if (unlikely(addr->sllc_family != AF_LLC)) |
| 330 | goto out; | 328 | goto out; |
| 329 | dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); | ||
| 331 | rc = -ENODEV; | 330 | rc = -ENODEV; |
| 332 | rcu_read_lock(); | 331 | rcu_read_lock(); |
| 333 | if (sk->sk_bound_dev_if) { | 332 | if (sk->sk_bound_dev_if) { |
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h index 28d022a3eee3..ae4f0be3b393 100644 --- a/net/mac80211/driver-ops.h +++ b/net/mac80211/driver-ops.h | |||
| @@ -1195,6 +1195,9 @@ static inline void drv_wake_tx_queue(struct ieee80211_local *local, | |||
| 1195 | { | 1195 | { |
| 1196 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); | 1196 | struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); |
| 1197 | 1197 | ||
| 1198 | if (local->in_reconfig) | ||
| 1199 | return; | ||
| 1200 | |||
| 1198 | if (!check_sdata_in_driver(sdata)) | 1201 | if (!check_sdata_in_driver(sdata)) |
| 1199 | return; | 1202 | return; |
| 1200 | 1203 | ||
diff --git a/net/mac80211/key.c b/net/mac80211/key.c index 4700718e010f..37e372896230 100644 --- a/net/mac80211/key.c +++ b/net/mac80211/key.c | |||
| @@ -167,8 +167,10 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
| 167 | * The driver doesn't know anything about VLAN interfaces. | 167 | * The driver doesn't know anything about VLAN interfaces. |
| 168 | * Hence, don't send GTKs for VLAN interfaces to the driver. | 168 | * Hence, don't send GTKs for VLAN interfaces to the driver. |
| 169 | */ | 169 | */ |
| 170 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) | 170 | if (!(key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE)) { |
| 171 | ret = 1; | ||
| 171 | goto out_unsupported; | 172 | goto out_unsupported; |
| 173 | } | ||
| 172 | } | 174 | } |
| 173 | 175 | ||
| 174 | ret = drv_set_key(key->local, SET_KEY, sdata, | 176 | ret = drv_set_key(key->local, SET_KEY, sdata, |
| @@ -213,11 +215,8 @@ static int ieee80211_key_enable_hw_accel(struct ieee80211_key *key) | |||
| 213 | /* all of these we can do in software - if driver can */ | 215 | /* all of these we can do in software - if driver can */ |
| 214 | if (ret == 1) | 216 | if (ret == 1) |
| 215 | return 0; | 217 | return 0; |
| 216 | if (ieee80211_hw_check(&key->local->hw, SW_CRYPTO_CONTROL)) { | 218 | if (ieee80211_hw_check(&key->local->hw, SW_CRYPTO_CONTROL)) |
| 217 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
| 218 | return 0; | ||
| 219 | return -EINVAL; | 219 | return -EINVAL; |
| 220 | } | ||
| 221 | return 0; | 220 | return 0; |
| 222 | default: | 221 | default: |
| 223 | return -EINVAL; | 222 | return -EINVAL; |
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c index 95eb5064fa91..b76a2aefa9ec 100644 --- a/net/mac80211/mesh_pathtbl.c +++ b/net/mac80211/mesh_pathtbl.c | |||
| @@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct mesh_table *tbl, struct mesh_path *mpath); | |||
| 23 | static u32 mesh_table_hash(const void *addr, u32 len, u32 seed) | 23 | static u32 mesh_table_hash(const void *addr, u32 len, u32 seed) |
| 24 | { | 24 | { |
| 25 | /* Use last four bytes of hw addr as hash index */ | 25 | /* Use last four bytes of hw addr as hash index */ |
| 26 | return jhash_1word(*(u32 *)(addr+2), seed); | 26 | return jhash_1word(__get_unaligned_cpu32((u8 *)addr + 2), seed); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | static const struct rhashtable_params mesh_rht_params = { | 29 | static const struct rhashtable_params mesh_rht_params = { |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 7f8d93401ce0..bf0b187f994e 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -1568,7 +1568,15 @@ static void sta_ps_start(struct sta_info *sta) | |||
| 1568 | return; | 1568 | return; |
| 1569 | 1569 | ||
| 1570 | for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { | 1570 | for (tid = 0; tid < IEEE80211_NUM_TIDS; tid++) { |
| 1571 | if (txq_has_queue(sta->sta.txq[tid])) | 1571 | struct ieee80211_txq *txq = sta->sta.txq[tid]; |
| 1572 | struct txq_info *txqi = to_txq_info(txq); | ||
| 1573 | |||
| 1574 | spin_lock(&local->active_txq_lock[txq->ac]); | ||
| 1575 | if (!list_empty(&txqi->schedule_order)) | ||
| 1576 | list_del_init(&txqi->schedule_order); | ||
| 1577 | spin_unlock(&local->active_txq_lock[txq->ac]); | ||
| 1578 | |||
| 1579 | if (txq_has_queue(txq)) | ||
| 1572 | set_bit(tid, &sta->txq_buffered_tids); | 1580 | set_bit(tid, &sta->txq_buffered_tids); |
| 1573 | else | 1581 | else |
| 1574 | clear_bit(tid, &sta->txq_buffered_tids); | 1582 | clear_bit(tid, &sta->txq_buffered_tids); |
diff --git a/net/mac80211/trace_msg.h b/net/mac80211/trace_msg.h index 366b9e6f043e..40141df09f25 100644 --- a/net/mac80211/trace_msg.h +++ b/net/mac80211/trace_msg.h | |||
| @@ -1,4 +1,9 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
| 2 | /* | ||
| 3 | * Portions of this file | ||
| 4 | * Copyright (C) 2019 Intel Corporation | ||
| 5 | */ | ||
| 6 | |||
| 2 | #ifdef CONFIG_MAC80211_MESSAGE_TRACING | 7 | #ifdef CONFIG_MAC80211_MESSAGE_TRACING |
| 3 | 8 | ||
| 4 | #if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) | 9 | #if !defined(__MAC80211_MSG_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ) |
| @@ -11,7 +16,7 @@ | |||
| 11 | #undef TRACE_SYSTEM | 16 | #undef TRACE_SYSTEM |
| 12 | #define TRACE_SYSTEM mac80211_msg | 17 | #define TRACE_SYSTEM mac80211_msg |
| 13 | 18 | ||
| 14 | #define MAX_MSG_LEN 100 | 19 | #define MAX_MSG_LEN 120 |
| 15 | 20 | ||
| 16 | DECLARE_EVENT_CLASS(mac80211_msg_event, | 21 | DECLARE_EVENT_CLASS(mac80211_msg_event, |
| 17 | TP_PROTO(struct va_format *vaf), | 22 | TP_PROTO(struct va_format *vaf), |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 8a49a74c0a37..2e816dd67be7 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
| @@ -3221,6 +3221,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, | |||
| 3221 | u8 max_subframes = sta->sta.max_amsdu_subframes; | 3221 | u8 max_subframes = sta->sta.max_amsdu_subframes; |
| 3222 | int max_frags = local->hw.max_tx_fragments; | 3222 | int max_frags = local->hw.max_tx_fragments; |
| 3223 | int max_amsdu_len = sta->sta.max_amsdu_len; | 3223 | int max_amsdu_len = sta->sta.max_amsdu_len; |
| 3224 | int orig_truesize; | ||
| 3224 | __be16 len; | 3225 | __be16 len; |
| 3225 | void *data; | 3226 | void *data; |
| 3226 | bool ret = false; | 3227 | bool ret = false; |
| @@ -3261,6 +3262,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, | |||
| 3261 | if (!head || skb_is_gso(head)) | 3262 | if (!head || skb_is_gso(head)) |
| 3262 | goto out; | 3263 | goto out; |
| 3263 | 3264 | ||
| 3265 | orig_truesize = head->truesize; | ||
| 3264 | orig_len = head->len; | 3266 | orig_len = head->len; |
| 3265 | 3267 | ||
| 3266 | if (skb->len + head->len > max_amsdu_len) | 3268 | if (skb->len + head->len > max_amsdu_len) |
| @@ -3318,6 +3320,7 @@ static bool ieee80211_amsdu_aggregate(struct ieee80211_sub_if_data *sdata, | |||
| 3318 | *frag_tail = skb; | 3320 | *frag_tail = skb; |
| 3319 | 3321 | ||
| 3320 | out_recalc: | 3322 | out_recalc: |
| 3323 | fq->memory_usage += head->truesize - orig_truesize; | ||
| 3321 | if (head->len != orig_len) { | 3324 | if (head->len != orig_len) { |
| 3322 | flow->backlog += head->len - orig_len; | 3325 | flow->backlog += head->len - orig_len; |
| 3323 | tin->backlog_bytes += head->len - orig_len; | 3326 | tin->backlog_bytes += head->len - orig_len; |
| @@ -3646,16 +3649,17 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); | |||
| 3646 | struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) | 3649 | struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) |
| 3647 | { | 3650 | { |
| 3648 | struct ieee80211_local *local = hw_to_local(hw); | 3651 | struct ieee80211_local *local = hw_to_local(hw); |
| 3652 | struct ieee80211_txq *ret = NULL; | ||
| 3649 | struct txq_info *txqi = NULL; | 3653 | struct txq_info *txqi = NULL; |
| 3650 | 3654 | ||
| 3651 | lockdep_assert_held(&local->active_txq_lock[ac]); | 3655 | spin_lock_bh(&local->active_txq_lock[ac]); |
| 3652 | 3656 | ||
| 3653 | begin: | 3657 | begin: |
| 3654 | txqi = list_first_entry_or_null(&local->active_txqs[ac], | 3658 | txqi = list_first_entry_or_null(&local->active_txqs[ac], |
| 3655 | struct txq_info, | 3659 | struct txq_info, |
| 3656 | schedule_order); | 3660 | schedule_order); |
| 3657 | if (!txqi) | 3661 | if (!txqi) |
| 3658 | return NULL; | 3662 | goto out; |
| 3659 | 3663 | ||
| 3660 | if (txqi->txq.sta) { | 3664 | if (txqi->txq.sta) { |
| 3661 | struct sta_info *sta = container_of(txqi->txq.sta, | 3665 | struct sta_info *sta = container_of(txqi->txq.sta, |
| @@ -3672,24 +3676,30 @@ struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) | |||
| 3672 | 3676 | ||
| 3673 | 3677 | ||
| 3674 | if (txqi->schedule_round == local->schedule_round[ac]) | 3678 | if (txqi->schedule_round == local->schedule_round[ac]) |
| 3675 | return NULL; | 3679 | goto out; |
| 3676 | 3680 | ||
| 3677 | list_del_init(&txqi->schedule_order); | 3681 | list_del_init(&txqi->schedule_order); |
| 3678 | txqi->schedule_round = local->schedule_round[ac]; | 3682 | txqi->schedule_round = local->schedule_round[ac]; |
| 3679 | return &txqi->txq; | 3683 | ret = &txqi->txq; |
| 3684 | |||
| 3685 | out: | ||
| 3686 | spin_unlock_bh(&local->active_txq_lock[ac]); | ||
| 3687 | return ret; | ||
| 3680 | } | 3688 | } |
| 3681 | EXPORT_SYMBOL(ieee80211_next_txq); | 3689 | EXPORT_SYMBOL(ieee80211_next_txq); |
| 3682 | 3690 | ||
| 3683 | void ieee80211_return_txq(struct ieee80211_hw *hw, | 3691 | void __ieee80211_schedule_txq(struct ieee80211_hw *hw, |
| 3684 | struct ieee80211_txq *txq) | 3692 | struct ieee80211_txq *txq, |
| 3693 | bool force) | ||
| 3685 | { | 3694 | { |
| 3686 | struct ieee80211_local *local = hw_to_local(hw); | 3695 | struct ieee80211_local *local = hw_to_local(hw); |
| 3687 | struct txq_info *txqi = to_txq_info(txq); | 3696 | struct txq_info *txqi = to_txq_info(txq); |
| 3688 | 3697 | ||
| 3689 | lockdep_assert_held(&local->active_txq_lock[txq->ac]); | 3698 | spin_lock_bh(&local->active_txq_lock[txq->ac]); |
| 3690 | 3699 | ||
| 3691 | if (list_empty(&txqi->schedule_order) && | 3700 | if (list_empty(&txqi->schedule_order) && |
| 3692 | (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) { | 3701 | (force || !skb_queue_empty(&txqi->frags) || |
| 3702 | txqi->tin.backlog_packets)) { | ||
| 3693 | /* If airtime accounting is active, always enqueue STAs at the | 3703 | /* If airtime accounting is active, always enqueue STAs at the |
| 3694 | * head of the list to ensure that they only get moved to the | 3704 | * head of the list to ensure that they only get moved to the |
| 3695 | * back by the airtime DRR scheduler once they have a negative | 3705 | * back by the airtime DRR scheduler once they have a negative |
| @@ -3706,20 +3716,10 @@ void ieee80211_return_txq(struct ieee80211_hw *hw, | |||
| 3706 | list_add_tail(&txqi->schedule_order, | 3716 | list_add_tail(&txqi->schedule_order, |
| 3707 | &local->active_txqs[txq->ac]); | 3717 | &local->active_txqs[txq->ac]); |
| 3708 | } | 3718 | } |
| 3709 | } | ||
| 3710 | EXPORT_SYMBOL(ieee80211_return_txq); | ||
| 3711 | 3719 | ||
| 3712 | void ieee80211_schedule_txq(struct ieee80211_hw *hw, | ||
| 3713 | struct ieee80211_txq *txq) | ||
| 3714 | __acquires(txq_lock) __releases(txq_lock) | ||
| 3715 | { | ||
| 3716 | struct ieee80211_local *local = hw_to_local(hw); | ||
| 3717 | |||
| 3718 | spin_lock_bh(&local->active_txq_lock[txq->ac]); | ||
| 3719 | ieee80211_return_txq(hw, txq); | ||
| 3720 | spin_unlock_bh(&local->active_txq_lock[txq->ac]); | 3720 | spin_unlock_bh(&local->active_txq_lock[txq->ac]); |
| 3721 | } | 3721 | } |
| 3722 | EXPORT_SYMBOL(ieee80211_schedule_txq); | 3722 | EXPORT_SYMBOL(__ieee80211_schedule_txq); |
| 3723 | 3723 | ||
| 3724 | bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, | 3724 | bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, |
| 3725 | struct ieee80211_txq *txq) | 3725 | struct ieee80211_txq *txq) |
| @@ -3729,7 +3729,7 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, | |||
| 3729 | struct sta_info *sta; | 3729 | struct sta_info *sta; |
| 3730 | u8 ac = txq->ac; | 3730 | u8 ac = txq->ac; |
| 3731 | 3731 | ||
| 3732 | lockdep_assert_held(&local->active_txq_lock[ac]); | 3732 | spin_lock_bh(&local->active_txq_lock[ac]); |
| 3733 | 3733 | ||
| 3734 | if (!txqi->txq.sta) | 3734 | if (!txqi->txq.sta) |
| 3735 | goto out; | 3735 | goto out; |
| @@ -3759,34 +3759,27 @@ bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, | |||
| 3759 | 3759 | ||
| 3760 | sta->airtime[ac].deficit += sta->airtime_weight; | 3760 | sta->airtime[ac].deficit += sta->airtime_weight; |
| 3761 | list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); | 3761 | list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); |
| 3762 | spin_unlock_bh(&local->active_txq_lock[ac]); | ||
| 3762 | 3763 | ||
| 3763 | return false; | 3764 | return false; |
| 3764 | out: | 3765 | out: |
| 3765 | if (!list_empty(&txqi->schedule_order)) | 3766 | if (!list_empty(&txqi->schedule_order)) |
| 3766 | list_del_init(&txqi->schedule_order); | 3767 | list_del_init(&txqi->schedule_order); |
| 3768 | spin_unlock_bh(&local->active_txq_lock[ac]); | ||
| 3767 | 3769 | ||
| 3768 | return true; | 3770 | return true; |
| 3769 | } | 3771 | } |
| 3770 | EXPORT_SYMBOL(ieee80211_txq_may_transmit); | 3772 | EXPORT_SYMBOL(ieee80211_txq_may_transmit); |
| 3771 | 3773 | ||
| 3772 | void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) | 3774 | void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) |
| 3773 | __acquires(txq_lock) | ||
| 3774 | { | 3775 | { |
| 3775 | struct ieee80211_local *local = hw_to_local(hw); | 3776 | struct ieee80211_local *local = hw_to_local(hw); |
| 3776 | 3777 | ||
| 3777 | spin_lock_bh(&local->active_txq_lock[ac]); | 3778 | spin_lock_bh(&local->active_txq_lock[ac]); |
| 3778 | local->schedule_round[ac]++; | 3779 | local->schedule_round[ac]++; |
| 3779 | } | ||
| 3780 | EXPORT_SYMBOL(ieee80211_txq_schedule_start); | ||
| 3781 | |||
| 3782 | void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) | ||
| 3783 | __releases(txq_lock) | ||
| 3784 | { | ||
| 3785 | struct ieee80211_local *local = hw_to_local(hw); | ||
| 3786 | |||
| 3787 | spin_unlock_bh(&local->active_txq_lock[ac]); | 3780 | spin_unlock_bh(&local->active_txq_lock[ac]); |
| 3788 | } | 3781 | } |
| 3789 | EXPORT_SYMBOL(ieee80211_txq_schedule_end); | 3782 | EXPORT_SYMBOL(ieee80211_txq_schedule_start); |
| 3790 | 3783 | ||
| 3791 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, | 3784 | void __ieee80211_subif_start_xmit(struct sk_buff *skb, |
| 3792 | struct net_device *dev, | 3785 | struct net_device *dev, |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index f28e937320a3..216ab915dd54 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
| @@ -988,7 +988,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
| 988 | struct netlink_sock *nlk = nlk_sk(sk); | 988 | struct netlink_sock *nlk = nlk_sk(sk); |
| 989 | struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; | 989 | struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr; |
| 990 | int err = 0; | 990 | int err = 0; |
| 991 | unsigned long groups = nladdr->nl_groups; | 991 | unsigned long groups; |
| 992 | bool bound; | 992 | bool bound; |
| 993 | 993 | ||
| 994 | if (addr_len < sizeof(struct sockaddr_nl)) | 994 | if (addr_len < sizeof(struct sockaddr_nl)) |
| @@ -996,6 +996,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
| 996 | 996 | ||
| 997 | if (nladdr->nl_family != AF_NETLINK) | 997 | if (nladdr->nl_family != AF_NETLINK) |
| 998 | return -EINVAL; | 998 | return -EINVAL; |
| 999 | groups = nladdr->nl_groups; | ||
| 999 | 1000 | ||
| 1000 | /* Only superuser is allowed to listen multicasts */ | 1001 | /* Only superuser is allowed to listen multicasts */ |
| 1001 | if (groups) { | 1002 | if (groups) { |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 1d3144d19903..71ffd1a6dc7c 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
| @@ -1392,18 +1392,22 @@ static int __init nr_proto_init(void) | |||
| 1392 | int i; | 1392 | int i; |
| 1393 | int rc = proto_register(&nr_proto, 0); | 1393 | int rc = proto_register(&nr_proto, 0); |
| 1394 | 1394 | ||
| 1395 | if (rc != 0) | 1395 | if (rc) |
| 1396 | goto out; | 1396 | return rc; |
| 1397 | 1397 | ||
| 1398 | if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) { | 1398 | if (nr_ndevs > 0x7fffffff/sizeof(struct net_device *)) { |
| 1399 | printk(KERN_ERR "NET/ROM: nr_proto_init - nr_ndevs parameter to large\n"); | 1399 | pr_err("NET/ROM: %s - nr_ndevs parameter too large\n", |
| 1400 | return -1; | 1400 | __func__); |
| 1401 | rc = -EINVAL; | ||
| 1402 | goto unregister_proto; | ||
| 1401 | } | 1403 | } |
| 1402 | 1404 | ||
| 1403 | dev_nr = kcalloc(nr_ndevs, sizeof(struct net_device *), GFP_KERNEL); | 1405 | dev_nr = kcalloc(nr_ndevs, sizeof(struct net_device *), GFP_KERNEL); |
| 1404 | if (dev_nr == NULL) { | 1406 | if (!dev_nr) { |
| 1405 | printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device array\n"); | 1407 | pr_err("NET/ROM: %s - unable to allocate device array\n", |
| 1406 | return -1; | 1408 | __func__); |
| 1409 | rc = -ENOMEM; | ||
| 1410 | goto unregister_proto; | ||
| 1407 | } | 1411 | } |
| 1408 | 1412 | ||
| 1409 | for (i = 0; i < nr_ndevs; i++) { | 1413 | for (i = 0; i < nr_ndevs; i++) { |
| @@ -1413,13 +1417,13 @@ static int __init nr_proto_init(void) | |||
| 1413 | sprintf(name, "nr%d", i); | 1417 | sprintf(name, "nr%d", i); |
| 1414 | dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, nr_setup); | 1418 | dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, nr_setup); |
| 1415 | if (!dev) { | 1419 | if (!dev) { |
| 1416 | printk(KERN_ERR "NET/ROM: nr_proto_init - unable to allocate device structure\n"); | 1420 | rc = -ENOMEM; |
| 1417 | goto fail; | 1421 | goto fail; |
| 1418 | } | 1422 | } |
| 1419 | 1423 | ||
| 1420 | dev->base_addr = i; | 1424 | dev->base_addr = i; |
| 1421 | if (register_netdev(dev)) { | 1425 | rc = register_netdev(dev); |
| 1422 | printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register network device\n"); | 1426 | if (rc) { |
| 1423 | free_netdev(dev); | 1427 | free_netdev(dev); |
| 1424 | goto fail; | 1428 | goto fail; |
| 1425 | } | 1429 | } |
| @@ -1427,36 +1431,64 @@ static int __init nr_proto_init(void) | |||
| 1427 | dev_nr[i] = dev; | 1431 | dev_nr[i] = dev; |
| 1428 | } | 1432 | } |
| 1429 | 1433 | ||
| 1430 | if (sock_register(&nr_family_ops)) { | 1434 | rc = sock_register(&nr_family_ops); |
| 1431 | printk(KERN_ERR "NET/ROM: nr_proto_init - unable to register socket family\n"); | 1435 | if (rc) |
| 1432 | goto fail; | 1436 | goto fail; |
| 1433 | } | ||
| 1434 | 1437 | ||
| 1435 | register_netdevice_notifier(&nr_dev_notifier); | 1438 | rc = register_netdevice_notifier(&nr_dev_notifier); |
| 1439 | if (rc) | ||
| 1440 | goto out_sock; | ||
| 1436 | 1441 | ||
| 1437 | ax25_register_pid(&nr_pid); | 1442 | ax25_register_pid(&nr_pid); |
| 1438 | ax25_linkfail_register(&nr_linkfail_notifier); | 1443 | ax25_linkfail_register(&nr_linkfail_notifier); |
| 1439 | 1444 | ||
| 1440 | #ifdef CONFIG_SYSCTL | 1445 | #ifdef CONFIG_SYSCTL |
| 1441 | nr_register_sysctl(); | 1446 | rc = nr_register_sysctl(); |
| 1447 | if (rc) | ||
| 1448 | goto out_sysctl; | ||
| 1442 | #endif | 1449 | #endif |
| 1443 | 1450 | ||
| 1444 | nr_loopback_init(); | 1451 | nr_loopback_init(); |
| 1445 | 1452 | ||
| 1446 | proc_create_seq("nr", 0444, init_net.proc_net, &nr_info_seqops); | 1453 | rc = -ENOMEM; |
| 1447 | proc_create_seq("nr_neigh", 0444, init_net.proc_net, &nr_neigh_seqops); | 1454 | if (!proc_create_seq("nr", 0444, init_net.proc_net, &nr_info_seqops)) |
| 1448 | proc_create_seq("nr_nodes", 0444, init_net.proc_net, &nr_node_seqops); | 1455 | goto proc_remove1; |
| 1449 | out: | 1456 | if (!proc_create_seq("nr_neigh", 0444, init_net.proc_net, |
| 1450 | return rc; | 1457 | &nr_neigh_seqops)) |
| 1458 | goto proc_remove2; | ||
| 1459 | if (!proc_create_seq("nr_nodes", 0444, init_net.proc_net, | ||
| 1460 | &nr_node_seqops)) | ||
| 1461 | goto proc_remove3; | ||
| 1462 | |||
| 1463 | return 0; | ||
| 1464 | |||
| 1465 | proc_remove3: | ||
| 1466 | remove_proc_entry("nr_neigh", init_net.proc_net); | ||
| 1467 | proc_remove2: | ||
| 1468 | remove_proc_entry("nr", init_net.proc_net); | ||
| 1469 | proc_remove1: | ||
| 1470 | |||
| 1471 | nr_loopback_clear(); | ||
| 1472 | nr_rt_free(); | ||
| 1473 | |||
| 1474 | #ifdef CONFIG_SYSCTL | ||
| 1475 | nr_unregister_sysctl(); | ||
| 1476 | out_sysctl: | ||
| 1477 | #endif | ||
| 1478 | ax25_linkfail_release(&nr_linkfail_notifier); | ||
| 1479 | ax25_protocol_release(AX25_P_NETROM); | ||
| 1480 | unregister_netdevice_notifier(&nr_dev_notifier); | ||
| 1481 | out_sock: | ||
| 1482 | sock_unregister(PF_NETROM); | ||
| 1451 | fail: | 1483 | fail: |
| 1452 | while (--i >= 0) { | 1484 | while (--i >= 0) { |
| 1453 | unregister_netdev(dev_nr[i]); | 1485 | unregister_netdev(dev_nr[i]); |
| 1454 | free_netdev(dev_nr[i]); | 1486 | free_netdev(dev_nr[i]); |
| 1455 | } | 1487 | } |
| 1456 | kfree(dev_nr); | 1488 | kfree(dev_nr); |
| 1489 | unregister_proto: | ||
| 1457 | proto_unregister(&nr_proto); | 1490 | proto_unregister(&nr_proto); |
| 1458 | rc = -1; | 1491 | return rc; |
| 1459 | goto out; | ||
| 1460 | } | 1492 | } |
| 1461 | 1493 | ||
| 1462 | module_init(nr_proto_init); | 1494 | module_init(nr_proto_init); |
diff --git a/net/netrom/nr_loopback.c b/net/netrom/nr_loopback.c index 215ad22a9647..93d13f019981 100644 --- a/net/netrom/nr_loopback.c +++ b/net/netrom/nr_loopback.c | |||
| @@ -70,7 +70,7 @@ static void nr_loopback_timer(struct timer_list *unused) | |||
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | void __exit nr_loopback_clear(void) | 73 | void nr_loopback_clear(void) |
| 74 | { | 74 | { |
| 75 | del_timer_sync(&loopback_timer); | 75 | del_timer_sync(&loopback_timer); |
| 76 | skb_queue_purge(&loopback_queue); | 76 | skb_queue_purge(&loopback_queue); |
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c index 6485f593e2f0..b76aa668a94b 100644 --- a/net/netrom/nr_route.c +++ b/net/netrom/nr_route.c | |||
| @@ -953,7 +953,7 @@ const struct seq_operations nr_neigh_seqops = { | |||
| 953 | /* | 953 | /* |
| 954 | * Free all memory associated with the nodes and routes lists. | 954 | * Free all memory associated with the nodes and routes lists. |
| 955 | */ | 955 | */ |
| 956 | void __exit nr_rt_free(void) | 956 | void nr_rt_free(void) |
| 957 | { | 957 | { |
| 958 | struct nr_neigh *s = NULL; | 958 | struct nr_neigh *s = NULL; |
| 959 | struct nr_node *t = NULL; | 959 | struct nr_node *t = NULL; |
diff --git a/net/netrom/sysctl_net_netrom.c b/net/netrom/sysctl_net_netrom.c index ba1c368b3f18..771011b84270 100644 --- a/net/netrom/sysctl_net_netrom.c +++ b/net/netrom/sysctl_net_netrom.c | |||
| @@ -146,9 +146,12 @@ static struct ctl_table nr_table[] = { | |||
| 146 | { } | 146 | { } |
| 147 | }; | 147 | }; |
| 148 | 148 | ||
| 149 | void __init nr_register_sysctl(void) | 149 | int __init nr_register_sysctl(void) |
| 150 | { | 150 | { |
| 151 | nr_table_header = register_net_sysctl(&init_net, "net/netrom", nr_table); | 151 | nr_table_header = register_net_sysctl(&init_net, "net/netrom", nr_table); |
| 152 | if (!nr_table_header) | ||
| 153 | return -ENOMEM; | ||
| 154 | return 0; | ||
| 152 | } | 155 | } |
| 153 | 156 | ||
| 154 | void nr_unregister_sysctl(void) | 157 | void nr_unregister_sysctl(void) |
diff --git a/net/rds/af_rds.c b/net/rds/af_rds.c index d6cc97fbbbb0..2b969f99ef13 100644 --- a/net/rds/af_rds.c +++ b/net/rds/af_rds.c | |||
| @@ -543,6 +543,9 @@ static int rds_connect(struct socket *sock, struct sockaddr *uaddr, | |||
| 543 | struct rds_sock *rs = rds_sk_to_rs(sk); | 543 | struct rds_sock *rs = rds_sk_to_rs(sk); |
| 544 | int ret = 0; | 544 | int ret = 0; |
| 545 | 545 | ||
| 546 | if (addr_len < offsetofend(struct sockaddr, sa_family)) | ||
| 547 | return -EINVAL; | ||
| 548 | |||
| 546 | lock_sock(sk); | 549 | lock_sock(sk); |
| 547 | 550 | ||
| 548 | switch (uaddr->sa_family) { | 551 | switch (uaddr->sa_family) { |
diff --git a/net/rds/bind.c b/net/rds/bind.c index 17c9d9f0c848..0f4398e7f2a7 100644 --- a/net/rds/bind.c +++ b/net/rds/bind.c | |||
| @@ -173,6 +173,8 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
| 173 | /* We allow an RDS socket to be bound to either IPv4 or IPv6 | 173 | /* We allow an RDS socket to be bound to either IPv4 or IPv6 |
| 174 | * address. | 174 | * address. |
| 175 | */ | 175 | */ |
| 176 | if (addr_len < offsetofend(struct sockaddr, sa_family)) | ||
| 177 | return -EINVAL; | ||
| 176 | if (uaddr->sa_family == AF_INET) { | 178 | if (uaddr->sa_family == AF_INET) { |
| 177 | struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; | 179 | struct sockaddr_in *sin = (struct sockaddr_in *)uaddr; |
| 178 | 180 | ||
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c index 96f2952bbdfd..ae8c5d7f3bf1 100644 --- a/net/rxrpc/af_rxrpc.c +++ b/net/rxrpc/af_rxrpc.c | |||
| @@ -135,7 +135,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len) | |||
| 135 | struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr; | 135 | struct sockaddr_rxrpc *srx = (struct sockaddr_rxrpc *)saddr; |
| 136 | struct rxrpc_local *local; | 136 | struct rxrpc_local *local; |
| 137 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); | 137 | struct rxrpc_sock *rx = rxrpc_sk(sock->sk); |
| 138 | u16 service_id = srx->srx_service; | 138 | u16 service_id; |
| 139 | int ret; | 139 | int ret; |
| 140 | 140 | ||
| 141 | _enter("%p,%p,%d", rx, saddr, len); | 141 | _enter("%p,%p,%d", rx, saddr, len); |
| @@ -143,6 +143,7 @@ static int rxrpc_bind(struct socket *sock, struct sockaddr *saddr, int len) | |||
| 143 | ret = rxrpc_validate_address(rx, srx, len); | 143 | ret = rxrpc_validate_address(rx, srx, len); |
| 144 | if (ret < 0) | 144 | if (ret < 0) |
| 145 | goto error; | 145 | goto error; |
| 146 | service_id = srx->srx_service; | ||
| 146 | 147 | ||
| 147 | lock_sock(&rx->sk); | 148 | lock_sock(&rx->sk); |
| 148 | 149 | ||
| @@ -370,18 +371,22 @@ EXPORT_SYMBOL(rxrpc_kernel_end_call); | |||
| 370 | * rxrpc_kernel_check_life - Check to see whether a call is still alive | 371 | * rxrpc_kernel_check_life - Check to see whether a call is still alive |
| 371 | * @sock: The socket the call is on | 372 | * @sock: The socket the call is on |
| 372 | * @call: The call to check | 373 | * @call: The call to check |
| 374 | * @_life: Where to store the life value | ||
| 373 | * | 375 | * |
| 374 | * Allow a kernel service to find out whether a call is still alive - ie. we're | 376 | * Allow a kernel service to find out whether a call is still alive - ie. we're |
| 375 | * getting ACKs from the server. Returns a number representing the life state | 377 | * getting ACKs from the server. Passes back in *_life a number representing |
| 376 | * which can be compared to that returned by a previous call. | 378 | * the life state which can be compared to that returned by a previous call and |
| 379 | * return true if the call is still alive. | ||
| 377 | * | 380 | * |
| 378 | * If the life state stalls, rxrpc_kernel_probe_life() should be called and | 381 | * If the life state stalls, rxrpc_kernel_probe_life() should be called and |
| 379 | * then 2RTT waited. | 382 | * then 2RTT waited. |
| 380 | */ | 383 | */ |
| 381 | u32 rxrpc_kernel_check_life(const struct socket *sock, | 384 | bool rxrpc_kernel_check_life(const struct socket *sock, |
| 382 | const struct rxrpc_call *call) | 385 | const struct rxrpc_call *call, |
| 386 | u32 *_life) | ||
| 383 | { | 387 | { |
| 384 | return call->acks_latest; | 388 | *_life = call->acks_latest; |
| 389 | return call->state != RXRPC_CALL_COMPLETE; | ||
| 385 | } | 390 | } |
| 386 | EXPORT_SYMBOL(rxrpc_kernel_check_life); | 391 | EXPORT_SYMBOL(rxrpc_kernel_check_life); |
| 387 | 392 | ||
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h index 4b1a534d290a..062ca9dc29b8 100644 --- a/net/rxrpc/ar-internal.h +++ b/net/rxrpc/ar-internal.h | |||
| @@ -654,6 +654,7 @@ struct rxrpc_call { | |||
| 654 | u8 ackr_reason; /* reason to ACK */ | 654 | u8 ackr_reason; /* reason to ACK */ |
| 655 | u16 ackr_skew; /* skew on packet being ACK'd */ | 655 | u16 ackr_skew; /* skew on packet being ACK'd */ |
| 656 | rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ | 656 | rxrpc_serial_t ackr_serial; /* serial of packet being ACK'd */ |
| 657 | rxrpc_serial_t ackr_first_seq; /* first sequence number received */ | ||
| 657 | rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ | 658 | rxrpc_seq_t ackr_prev_seq; /* previous sequence number received */ |
| 658 | rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ | 659 | rxrpc_seq_t ackr_consumed; /* Highest packet shown consumed */ |
| 659 | rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ | 660 | rxrpc_seq_t ackr_seen; /* Highest packet shown seen */ |
diff --git a/net/rxrpc/conn_event.c b/net/rxrpc/conn_event.c index b6fca8ebb117..8d31fb4c51e1 100644 --- a/net/rxrpc/conn_event.c +++ b/net/rxrpc/conn_event.c | |||
| @@ -153,7 +153,8 @@ static void rxrpc_conn_retransmit_call(struct rxrpc_connection *conn, | |||
| 153 | * pass a connection-level abort onto all calls on that connection | 153 | * pass a connection-level abort onto all calls on that connection |
| 154 | */ | 154 | */ |
| 155 | static void rxrpc_abort_calls(struct rxrpc_connection *conn, | 155 | static void rxrpc_abort_calls(struct rxrpc_connection *conn, |
| 156 | enum rxrpc_call_completion compl) | 156 | enum rxrpc_call_completion compl, |
| 157 | rxrpc_serial_t serial) | ||
| 157 | { | 158 | { |
| 158 | struct rxrpc_call *call; | 159 | struct rxrpc_call *call; |
| 159 | int i; | 160 | int i; |
| @@ -173,6 +174,9 @@ static void rxrpc_abort_calls(struct rxrpc_connection *conn, | |||
| 173 | call->call_id, 0, | 174 | call->call_id, 0, |
| 174 | conn->abort_code, | 175 | conn->abort_code, |
| 175 | conn->error); | 176 | conn->error); |
| 177 | else | ||
| 178 | trace_rxrpc_rx_abort(call, serial, | ||
| 179 | conn->abort_code); | ||
| 176 | if (rxrpc_set_call_completion(call, compl, | 180 | if (rxrpc_set_call_completion(call, compl, |
| 177 | conn->abort_code, | 181 | conn->abort_code, |
| 178 | conn->error)) | 182 | conn->error)) |
| @@ -213,8 +217,6 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn, | |||
| 213 | conn->state = RXRPC_CONN_LOCALLY_ABORTED; | 217 | conn->state = RXRPC_CONN_LOCALLY_ABORTED; |
| 214 | spin_unlock_bh(&conn->state_lock); | 218 | spin_unlock_bh(&conn->state_lock); |
| 215 | 219 | ||
| 216 | rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED); | ||
| 217 | |||
| 218 | msg.msg_name = &conn->params.peer->srx.transport; | 220 | msg.msg_name = &conn->params.peer->srx.transport; |
| 219 | msg.msg_namelen = conn->params.peer->srx.transport_len; | 221 | msg.msg_namelen = conn->params.peer->srx.transport_len; |
| 220 | msg.msg_control = NULL; | 222 | msg.msg_control = NULL; |
| @@ -242,6 +244,7 @@ static int rxrpc_abort_connection(struct rxrpc_connection *conn, | |||
| 242 | len = iov[0].iov_len + iov[1].iov_len; | 244 | len = iov[0].iov_len + iov[1].iov_len; |
| 243 | 245 | ||
| 244 | serial = atomic_inc_return(&conn->serial); | 246 | serial = atomic_inc_return(&conn->serial); |
| 247 | rxrpc_abort_calls(conn, RXRPC_CALL_LOCALLY_ABORTED, serial); | ||
| 245 | whdr.serial = htonl(serial); | 248 | whdr.serial = htonl(serial); |
| 246 | _proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code); | 249 | _proto("Tx CONN ABORT %%%u { %d }", serial, conn->abort_code); |
| 247 | 250 | ||
| @@ -321,7 +324,7 @@ static int rxrpc_process_event(struct rxrpc_connection *conn, | |||
| 321 | conn->error = -ECONNABORTED; | 324 | conn->error = -ECONNABORTED; |
| 322 | conn->abort_code = abort_code; | 325 | conn->abort_code = abort_code; |
| 323 | conn->state = RXRPC_CONN_REMOTELY_ABORTED; | 326 | conn->state = RXRPC_CONN_REMOTELY_ABORTED; |
| 324 | rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED); | 327 | rxrpc_abort_calls(conn, RXRPC_CALL_REMOTELY_ABORTED, sp->hdr.serial); |
| 325 | return -ECONNABORTED; | 328 | return -ECONNABORTED; |
| 326 | 329 | ||
| 327 | case RXRPC_PACKET_TYPE_CHALLENGE: | 330 | case RXRPC_PACKET_TYPE_CHALLENGE: |
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c index 9128aa0e40aa..4c6f9d0a00e7 100644 --- a/net/rxrpc/input.c +++ b/net/rxrpc/input.c | |||
| @@ -837,7 +837,7 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 837 | u8 acks[RXRPC_MAXACKS]; | 837 | u8 acks[RXRPC_MAXACKS]; |
| 838 | } buf; | 838 | } buf; |
| 839 | rxrpc_serial_t acked_serial; | 839 | rxrpc_serial_t acked_serial; |
| 840 | rxrpc_seq_t first_soft_ack, hard_ack; | 840 | rxrpc_seq_t first_soft_ack, hard_ack, prev_pkt; |
| 841 | int nr_acks, offset, ioffset; | 841 | int nr_acks, offset, ioffset; |
| 842 | 842 | ||
| 843 | _enter(""); | 843 | _enter(""); |
| @@ -851,13 +851,14 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 851 | 851 | ||
| 852 | acked_serial = ntohl(buf.ack.serial); | 852 | acked_serial = ntohl(buf.ack.serial); |
| 853 | first_soft_ack = ntohl(buf.ack.firstPacket); | 853 | first_soft_ack = ntohl(buf.ack.firstPacket); |
| 854 | prev_pkt = ntohl(buf.ack.previousPacket); | ||
| 854 | hard_ack = first_soft_ack - 1; | 855 | hard_ack = first_soft_ack - 1; |
| 855 | nr_acks = buf.ack.nAcks; | 856 | nr_acks = buf.ack.nAcks; |
| 856 | summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ? | 857 | summary.ack_reason = (buf.ack.reason < RXRPC_ACK__INVALID ? |
| 857 | buf.ack.reason : RXRPC_ACK__INVALID); | 858 | buf.ack.reason : RXRPC_ACK__INVALID); |
| 858 | 859 | ||
| 859 | trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial, | 860 | trace_rxrpc_rx_ack(call, sp->hdr.serial, acked_serial, |
| 860 | first_soft_ack, ntohl(buf.ack.previousPacket), | 861 | first_soft_ack, prev_pkt, |
| 861 | summary.ack_reason, nr_acks); | 862 | summary.ack_reason, nr_acks); |
| 862 | 863 | ||
| 863 | if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE) | 864 | if (buf.ack.reason == RXRPC_ACK_PING_RESPONSE) |
| @@ -878,8 +879,9 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 878 | rxrpc_propose_ack_respond_to_ack); | 879 | rxrpc_propose_ack_respond_to_ack); |
| 879 | } | 880 | } |
| 880 | 881 | ||
| 881 | /* Discard any out-of-order or duplicate ACKs. */ | 882 | /* Discard any out-of-order or duplicate ACKs (outside lock). */ |
| 882 | if (before_eq(sp->hdr.serial, call->acks_latest)) | 883 | if (before(first_soft_ack, call->ackr_first_seq) || |
| 884 | before(prev_pkt, call->ackr_prev_seq)) | ||
| 883 | return; | 885 | return; |
| 884 | 886 | ||
| 885 | buf.info.rxMTU = 0; | 887 | buf.info.rxMTU = 0; |
| @@ -890,12 +892,16 @@ static void rxrpc_input_ack(struct rxrpc_call *call, struct sk_buff *skb, | |||
| 890 | 892 | ||
| 891 | spin_lock(&call->input_lock); | 893 | spin_lock(&call->input_lock); |
| 892 | 894 | ||
| 893 | /* Discard any out-of-order or duplicate ACKs. */ | 895 | /* Discard any out-of-order or duplicate ACKs (inside lock). */ |
| 894 | if (before_eq(sp->hdr.serial, call->acks_latest)) | 896 | if (before(first_soft_ack, call->ackr_first_seq) || |
| 897 | before(prev_pkt, call->ackr_prev_seq)) | ||
| 895 | goto out; | 898 | goto out; |
| 896 | call->acks_latest_ts = skb->tstamp; | 899 | call->acks_latest_ts = skb->tstamp; |
| 897 | call->acks_latest = sp->hdr.serial; | 900 | call->acks_latest = sp->hdr.serial; |
| 898 | 901 | ||
| 902 | call->ackr_first_seq = first_soft_ack; | ||
| 903 | call->ackr_prev_seq = prev_pkt; | ||
| 904 | |||
| 899 | /* Parse rwind and mtu sizes if provided. */ | 905 | /* Parse rwind and mtu sizes if provided. */ |
| 900 | if (buf.info.rxMTU) | 906 | if (buf.info.rxMTU) |
| 901 | rxrpc_input_ackinfo(call, skb, &buf.info); | 907 | rxrpc_input_ackinfo(call, skb, &buf.info); |
diff --git a/net/rxrpc/peer_event.c b/net/rxrpc/peer_event.c index bc05af89fc38..6e84d878053c 100644 --- a/net/rxrpc/peer_event.c +++ b/net/rxrpc/peer_event.c | |||
| @@ -157,6 +157,11 @@ void rxrpc_error_report(struct sock *sk) | |||
| 157 | 157 | ||
| 158 | _enter("%p{%d}", sk, local->debug_id); | 158 | _enter("%p{%d}", sk, local->debug_id); |
| 159 | 159 | ||
| 160 | /* Clear the outstanding error value on the socket so that it doesn't | ||
| 161 | * cause kernel_sendmsg() to return it later. | ||
| 162 | */ | ||
| 163 | sock_error(sk); | ||
| 164 | |||
| 160 | skb = sock_dequeue_err_skb(sk); | 165 | skb = sock_dequeue_err_skb(sk); |
| 161 | if (!skb) { | 166 | if (!skb) { |
| 162 | _leave("UDP socket errqueue empty"); | 167 | _leave("UDP socket errqueue empty"); |
diff --git a/net/rxrpc/sendmsg.c b/net/rxrpc/sendmsg.c index 46c9312085b1..bec64deb7b0a 100644 --- a/net/rxrpc/sendmsg.c +++ b/net/rxrpc/sendmsg.c | |||
| @@ -152,12 +152,13 @@ static void rxrpc_notify_end_tx(struct rxrpc_sock *rx, struct rxrpc_call *call, | |||
| 152 | } | 152 | } |
| 153 | 153 | ||
| 154 | /* | 154 | /* |
| 155 | * Queue a DATA packet for transmission, set the resend timeout and send the | 155 | * Queue a DATA packet for transmission, set the resend timeout and send |
| 156 | * packet immediately | 156 | * the packet immediately. Returns the error from rxrpc_send_data_packet() |
| 157 | * in case the caller wants to do something with it. | ||
| 157 | */ | 158 | */ |
| 158 | static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | 159 | static int rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, |
| 159 | struct sk_buff *skb, bool last, | 160 | struct sk_buff *skb, bool last, |
| 160 | rxrpc_notify_end_tx_t notify_end_tx) | 161 | rxrpc_notify_end_tx_t notify_end_tx) |
| 161 | { | 162 | { |
| 162 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); | 163 | struct rxrpc_skb_priv *sp = rxrpc_skb(skb); |
| 163 | unsigned long now; | 164 | unsigned long now; |
| @@ -250,7 +251,8 @@ static void rxrpc_queue_packet(struct rxrpc_sock *rx, struct rxrpc_call *call, | |||
| 250 | 251 | ||
| 251 | out: | 252 | out: |
| 252 | rxrpc_free_skb(skb, rxrpc_skb_tx_freed); | 253 | rxrpc_free_skb(skb, rxrpc_skb_tx_freed); |
| 253 | _leave(""); | 254 | _leave(" = %d", ret); |
| 255 | return ret; | ||
| 254 | } | 256 | } |
| 255 | 257 | ||
| 256 | /* | 258 | /* |
| @@ -423,9 +425,10 @@ static int rxrpc_send_data(struct rxrpc_sock *rx, | |||
| 423 | if (ret < 0) | 425 | if (ret < 0) |
| 424 | goto out; | 426 | goto out; |
| 425 | 427 | ||
| 426 | rxrpc_queue_packet(rx, call, skb, | 428 | ret = rxrpc_queue_packet(rx, call, skb, |
| 427 | !msg_data_left(msg) && !more, | 429 | !msg_data_left(msg) && !more, |
| 428 | notify_end_tx); | 430 | notify_end_tx); |
| 431 | /* Should check for failure here */ | ||
| 429 | skb = NULL; | 432 | skb = NULL; |
| 430 | } | 433 | } |
| 431 | } while (msg_data_left(msg) > 0); | 434 | } while (msg_data_left(msg) > 0); |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f66dca3b1055..e4e892cc5644 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
| @@ -4850,7 +4850,8 @@ static int sctp_connect(struct sock *sk, struct sockaddr *addr, | |||
| 4850 | } | 4850 | } |
| 4851 | 4851 | ||
| 4852 | /* Validate addr_len before calling common connect/connectx routine. */ | 4852 | /* Validate addr_len before calling common connect/connectx routine. */ |
| 4853 | af = sctp_get_af_specific(addr->sa_family); | 4853 | af = addr_len < offsetofend(struct sockaddr, sa_family) ? NULL : |
| 4854 | sctp_get_af_specific(addr->sa_family); | ||
| 4854 | if (!af || addr_len < af->sockaddr_len) { | 4855 | if (!af || addr_len < af->sockaddr_len) { |
| 4855 | err = -EINVAL; | 4856 | err = -EINVAL; |
| 4856 | } else { | 4857 | } else { |
diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c index e066899de72d..086d9913975d 100644 --- a/net/smc/af_smc.c +++ b/net/smc/af_smc.c | |||
| @@ -165,10 +165,9 @@ static int smc_release(struct socket *sock) | |||
| 165 | 165 | ||
| 166 | if (sk->sk_state == SMC_CLOSED) { | 166 | if (sk->sk_state == SMC_CLOSED) { |
| 167 | if (smc->clcsock) { | 167 | if (smc->clcsock) { |
| 168 | mutex_lock(&smc->clcsock_release_lock); | 168 | release_sock(sk); |
| 169 | sock_release(smc->clcsock); | 169 | smc_clcsock_release(smc); |
| 170 | smc->clcsock = NULL; | 170 | lock_sock(sk); |
| 171 | mutex_unlock(&smc->clcsock_release_lock); | ||
| 172 | } | 171 | } |
| 173 | if (!smc->use_fallback) | 172 | if (!smc->use_fallback) |
| 174 | smc_conn_free(&smc->conn); | 173 | smc_conn_free(&smc->conn); |
| @@ -444,10 +443,19 @@ static void smc_link_save_peer_info(struct smc_link *link, | |||
| 444 | link->peer_mtu = clc->qp_mtu; | 443 | link->peer_mtu = clc->qp_mtu; |
| 445 | } | 444 | } |
| 446 | 445 | ||
| 446 | static void smc_switch_to_fallback(struct smc_sock *smc) | ||
| 447 | { | ||
| 448 | smc->use_fallback = true; | ||
| 449 | if (smc->sk.sk_socket && smc->sk.sk_socket->file) { | ||
| 450 | smc->clcsock->file = smc->sk.sk_socket->file; | ||
| 451 | smc->clcsock->file->private_data = smc->clcsock; | ||
| 452 | } | ||
| 453 | } | ||
| 454 | |||
| 447 | /* fall back during connect */ | 455 | /* fall back during connect */ |
| 448 | static int smc_connect_fallback(struct smc_sock *smc, int reason_code) | 456 | static int smc_connect_fallback(struct smc_sock *smc, int reason_code) |
| 449 | { | 457 | { |
| 450 | smc->use_fallback = true; | 458 | smc_switch_to_fallback(smc); |
| 451 | smc->fallback_rsn = reason_code; | 459 | smc->fallback_rsn = reason_code; |
| 452 | smc_copy_sock_settings_to_clc(smc); | 460 | smc_copy_sock_settings_to_clc(smc); |
| 453 | smc->connect_nonblock = 0; | 461 | smc->connect_nonblock = 0; |
| @@ -780,10 +788,14 @@ static void smc_connect_work(struct work_struct *work) | |||
| 780 | smc->sk.sk_err = -rc; | 788 | smc->sk.sk_err = -rc; |
| 781 | 789 | ||
| 782 | out: | 790 | out: |
| 783 | if (smc->sk.sk_err) | 791 | if (!sock_flag(&smc->sk, SOCK_DEAD)) { |
| 784 | smc->sk.sk_state_change(&smc->sk); | 792 | if (smc->sk.sk_err) { |
| 785 | else | 793 | smc->sk.sk_state_change(&smc->sk); |
| 786 | smc->sk.sk_write_space(&smc->sk); | 794 | } else { /* allow polling before and after fallback decision */ |
| 795 | smc->clcsock->sk->sk_write_space(smc->clcsock->sk); | ||
| 796 | smc->sk.sk_write_space(&smc->sk); | ||
| 797 | } | ||
| 798 | } | ||
| 787 | release_sock(&smc->sk); | 799 | release_sock(&smc->sk); |
| 788 | } | 800 | } |
| 789 | 801 | ||
| @@ -867,11 +879,11 @@ static int smc_clcsock_accept(struct smc_sock *lsmc, struct smc_sock **new_smc) | |||
| 867 | if (rc < 0) | 879 | if (rc < 0) |
| 868 | lsk->sk_err = -rc; | 880 | lsk->sk_err = -rc; |
| 869 | if (rc < 0 || lsk->sk_state == SMC_CLOSED) { | 881 | if (rc < 0 || lsk->sk_state == SMC_CLOSED) { |
| 882 | new_sk->sk_prot->unhash(new_sk); | ||
| 870 | if (new_clcsock) | 883 | if (new_clcsock) |
| 871 | sock_release(new_clcsock); | 884 | sock_release(new_clcsock); |
| 872 | new_sk->sk_state = SMC_CLOSED; | 885 | new_sk->sk_state = SMC_CLOSED; |
| 873 | sock_set_flag(new_sk, SOCK_DEAD); | 886 | sock_set_flag(new_sk, SOCK_DEAD); |
| 874 | new_sk->sk_prot->unhash(new_sk); | ||
| 875 | sock_put(new_sk); /* final */ | 887 | sock_put(new_sk); /* final */ |
| 876 | *new_smc = NULL; | 888 | *new_smc = NULL; |
| 877 | goto out; | 889 | goto out; |
| @@ -922,16 +934,21 @@ struct sock *smc_accept_dequeue(struct sock *parent, | |||
| 922 | 934 | ||
| 923 | smc_accept_unlink(new_sk); | 935 | smc_accept_unlink(new_sk); |
| 924 | if (new_sk->sk_state == SMC_CLOSED) { | 936 | if (new_sk->sk_state == SMC_CLOSED) { |
| 937 | new_sk->sk_prot->unhash(new_sk); | ||
| 925 | if (isk->clcsock) { | 938 | if (isk->clcsock) { |
| 926 | sock_release(isk->clcsock); | 939 | sock_release(isk->clcsock); |
| 927 | isk->clcsock = NULL; | 940 | isk->clcsock = NULL; |
| 928 | } | 941 | } |
| 929 | new_sk->sk_prot->unhash(new_sk); | ||
| 930 | sock_put(new_sk); /* final */ | 942 | sock_put(new_sk); /* final */ |
| 931 | continue; | 943 | continue; |
| 932 | } | 944 | } |
| 933 | if (new_sock) | 945 | if (new_sock) { |
| 934 | sock_graft(new_sk, new_sock); | 946 | sock_graft(new_sk, new_sock); |
| 947 | if (isk->use_fallback) { | ||
| 948 | smc_sk(new_sk)->clcsock->file = new_sock->file; | ||
| 949 | isk->clcsock->file->private_data = isk->clcsock; | ||
| 950 | } | ||
| 951 | } | ||
| 935 | return new_sk; | 952 | return new_sk; |
| 936 | } | 953 | } |
| 937 | return NULL; | 954 | return NULL; |
| @@ -951,6 +968,7 @@ void smc_close_non_accepted(struct sock *sk) | |||
| 951 | sock_set_flag(sk, SOCK_DEAD); | 968 | sock_set_flag(sk, SOCK_DEAD); |
| 952 | sk->sk_shutdown |= SHUTDOWN_MASK; | 969 | sk->sk_shutdown |= SHUTDOWN_MASK; |
| 953 | } | 970 | } |
| 971 | sk->sk_prot->unhash(sk); | ||
| 954 | if (smc->clcsock) { | 972 | if (smc->clcsock) { |
| 955 | struct socket *tcp; | 973 | struct socket *tcp; |
| 956 | 974 | ||
| @@ -966,7 +984,6 @@ void smc_close_non_accepted(struct sock *sk) | |||
| 966 | smc_conn_free(&smc->conn); | 984 | smc_conn_free(&smc->conn); |
| 967 | } | 985 | } |
| 968 | release_sock(sk); | 986 | release_sock(sk); |
| 969 | sk->sk_prot->unhash(sk); | ||
| 970 | sock_put(sk); /* final sock_put */ | 987 | sock_put(sk); /* final sock_put */ |
| 971 | } | 988 | } |
| 972 | 989 | ||
| @@ -1032,13 +1049,13 @@ static void smc_listen_out(struct smc_sock *new_smc) | |||
| 1032 | struct smc_sock *lsmc = new_smc->listen_smc; | 1049 | struct smc_sock *lsmc = new_smc->listen_smc; |
| 1033 | struct sock *newsmcsk = &new_smc->sk; | 1050 | struct sock *newsmcsk = &new_smc->sk; |
| 1034 | 1051 | ||
| 1035 | lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING); | ||
| 1036 | if (lsmc->sk.sk_state == SMC_LISTEN) { | 1052 | if (lsmc->sk.sk_state == SMC_LISTEN) { |
| 1053 | lock_sock_nested(&lsmc->sk, SINGLE_DEPTH_NESTING); | ||
| 1037 | smc_accept_enqueue(&lsmc->sk, newsmcsk); | 1054 | smc_accept_enqueue(&lsmc->sk, newsmcsk); |
| 1055 | release_sock(&lsmc->sk); | ||
| 1038 | } else { /* no longer listening */ | 1056 | } else { /* no longer listening */ |
| 1039 | smc_close_non_accepted(newsmcsk); | 1057 | smc_close_non_accepted(newsmcsk); |
| 1040 | } | 1058 | } |
| 1041 | release_sock(&lsmc->sk); | ||
| 1042 | 1059 | ||
| 1043 | /* Wake up accept */ | 1060 | /* Wake up accept */ |
| 1044 | lsmc->sk.sk_data_ready(&lsmc->sk); | 1061 | lsmc->sk.sk_data_ready(&lsmc->sk); |
| @@ -1082,7 +1099,7 @@ static void smc_listen_decline(struct smc_sock *new_smc, int reason_code, | |||
| 1082 | return; | 1099 | return; |
| 1083 | } | 1100 | } |
| 1084 | smc_conn_free(&new_smc->conn); | 1101 | smc_conn_free(&new_smc->conn); |
| 1085 | new_smc->use_fallback = true; | 1102 | smc_switch_to_fallback(new_smc); |
| 1086 | new_smc->fallback_rsn = reason_code; | 1103 | new_smc->fallback_rsn = reason_code; |
| 1087 | if (reason_code && reason_code != SMC_CLC_DECL_PEERDECL) { | 1104 | if (reason_code && reason_code != SMC_CLC_DECL_PEERDECL) { |
| 1088 | if (smc_clc_send_decline(new_smc, reason_code) < 0) { | 1105 | if (smc_clc_send_decline(new_smc, reason_code) < 0) { |
| @@ -1220,6 +1237,9 @@ static void smc_listen_work(struct work_struct *work) | |||
| 1220 | u8 buf[SMC_CLC_MAX_LEN]; | 1237 | u8 buf[SMC_CLC_MAX_LEN]; |
| 1221 | int rc = 0; | 1238 | int rc = 0; |
| 1222 | 1239 | ||
| 1240 | if (new_smc->listen_smc->sk.sk_state != SMC_LISTEN) | ||
| 1241 | return smc_listen_out_err(new_smc); | ||
| 1242 | |||
| 1223 | if (new_smc->use_fallback) { | 1243 | if (new_smc->use_fallback) { |
| 1224 | smc_listen_out_connected(new_smc); | 1244 | smc_listen_out_connected(new_smc); |
| 1225 | return; | 1245 | return; |
| @@ -1227,7 +1247,7 @@ static void smc_listen_work(struct work_struct *work) | |||
| 1227 | 1247 | ||
| 1228 | /* check if peer is smc capable */ | 1248 | /* check if peer is smc capable */ |
| 1229 | if (!tcp_sk(newclcsock->sk)->syn_smc) { | 1249 | if (!tcp_sk(newclcsock->sk)->syn_smc) { |
| 1230 | new_smc->use_fallback = true; | 1250 | smc_switch_to_fallback(new_smc); |
| 1231 | new_smc->fallback_rsn = SMC_CLC_DECL_PEERNOSMC; | 1251 | new_smc->fallback_rsn = SMC_CLC_DECL_PEERNOSMC; |
| 1232 | smc_listen_out_connected(new_smc); | 1252 | smc_listen_out_connected(new_smc); |
| 1233 | return; | 1253 | return; |
| @@ -1507,7 +1527,7 @@ static int smc_sendmsg(struct socket *sock, struct msghdr *msg, size_t len) | |||
| 1507 | 1527 | ||
| 1508 | if (msg->msg_flags & MSG_FASTOPEN) { | 1528 | if (msg->msg_flags & MSG_FASTOPEN) { |
| 1509 | if (sk->sk_state == SMC_INIT) { | 1529 | if (sk->sk_state == SMC_INIT) { |
| 1510 | smc->use_fallback = true; | 1530 | smc_switch_to_fallback(smc); |
| 1511 | smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; | 1531 | smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; |
| 1512 | } else { | 1532 | } else { |
| 1513 | rc = -EINVAL; | 1533 | rc = -EINVAL; |
| @@ -1712,7 +1732,7 @@ static int smc_setsockopt(struct socket *sock, int level, int optname, | |||
| 1712 | case TCP_FASTOPEN_NO_COOKIE: | 1732 | case TCP_FASTOPEN_NO_COOKIE: |
| 1713 | /* option not supported by SMC */ | 1733 | /* option not supported by SMC */ |
| 1714 | if (sk->sk_state == SMC_INIT) { | 1734 | if (sk->sk_state == SMC_INIT) { |
| 1715 | smc->use_fallback = true; | 1735 | smc_switch_to_fallback(smc); |
| 1716 | smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; | 1736 | smc->fallback_rsn = SMC_CLC_DECL_OPTUNSUPP; |
| 1717 | } else { | 1737 | } else { |
| 1718 | if (!smc->use_fallback) | 1738 | if (!smc->use_fallback) |
diff --git a/net/smc/smc_close.c b/net/smc/smc_close.c index 2ad37e998509..fc06720b53c1 100644 --- a/net/smc/smc_close.c +++ b/net/smc/smc_close.c | |||
| @@ -21,6 +21,22 @@ | |||
| 21 | 21 | ||
| 22 | #define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ) | 22 | #define SMC_CLOSE_WAIT_LISTEN_CLCSOCK_TIME (5 * HZ) |
| 23 | 23 | ||
| 24 | /* release the clcsock that is assigned to the smc_sock */ | ||
| 25 | void smc_clcsock_release(struct smc_sock *smc) | ||
| 26 | { | ||
| 27 | struct socket *tcp; | ||
| 28 | |||
| 29 | if (smc->listen_smc && current_work() != &smc->smc_listen_work) | ||
| 30 | cancel_work_sync(&smc->smc_listen_work); | ||
| 31 | mutex_lock(&smc->clcsock_release_lock); | ||
| 32 | if (smc->clcsock) { | ||
| 33 | tcp = smc->clcsock; | ||
| 34 | smc->clcsock = NULL; | ||
| 35 | sock_release(tcp); | ||
| 36 | } | ||
| 37 | mutex_unlock(&smc->clcsock_release_lock); | ||
| 38 | } | ||
| 39 | |||
| 24 | static void smc_close_cleanup_listen(struct sock *parent) | 40 | static void smc_close_cleanup_listen(struct sock *parent) |
| 25 | { | 41 | { |
| 26 | struct sock *sk; | 42 | struct sock *sk; |
| @@ -321,6 +337,7 @@ static void smc_close_passive_work(struct work_struct *work) | |||
| 321 | close_work); | 337 | close_work); |
| 322 | struct smc_sock *smc = container_of(conn, struct smc_sock, conn); | 338 | struct smc_sock *smc = container_of(conn, struct smc_sock, conn); |
| 323 | struct smc_cdc_conn_state_flags *rxflags; | 339 | struct smc_cdc_conn_state_flags *rxflags; |
| 340 | bool release_clcsock = false; | ||
| 324 | struct sock *sk = &smc->sk; | 341 | struct sock *sk = &smc->sk; |
| 325 | int old_state; | 342 | int old_state; |
| 326 | 343 | ||
| @@ -400,13 +417,13 @@ wakeup: | |||
| 400 | if ((sk->sk_state == SMC_CLOSED) && | 417 | if ((sk->sk_state == SMC_CLOSED) && |
| 401 | (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) { | 418 | (sock_flag(sk, SOCK_DEAD) || !sk->sk_socket)) { |
| 402 | smc_conn_free(conn); | 419 | smc_conn_free(conn); |
| 403 | if (smc->clcsock) { | 420 | if (smc->clcsock) |
| 404 | sock_release(smc->clcsock); | 421 | release_clcsock = true; |
| 405 | smc->clcsock = NULL; | ||
| 406 | } | ||
| 407 | } | 422 | } |
| 408 | } | 423 | } |
| 409 | release_sock(sk); | 424 | release_sock(sk); |
| 425 | if (release_clcsock) | ||
| 426 | smc_clcsock_release(smc); | ||
| 410 | sock_put(sk); /* sock_hold done by schedulers of close_work */ | 427 | sock_put(sk); /* sock_hold done by schedulers of close_work */ |
| 411 | } | 428 | } |
| 412 | 429 | ||
diff --git a/net/smc/smc_close.h b/net/smc/smc_close.h index 19eb6a211c23..e0e3b5df25d2 100644 --- a/net/smc/smc_close.h +++ b/net/smc/smc_close.h | |||
| @@ -23,5 +23,6 @@ void smc_close_wake_tx_prepared(struct smc_sock *smc); | |||
| 23 | int smc_close_active(struct smc_sock *smc); | 23 | int smc_close_active(struct smc_sock *smc); |
| 24 | int smc_close_shutdown_write(struct smc_sock *smc); | 24 | int smc_close_shutdown_write(struct smc_sock *smc); |
| 25 | void smc_close_init(struct smc_sock *smc); | 25 | void smc_close_init(struct smc_sock *smc); |
| 26 | void smc_clcsock_release(struct smc_sock *smc); | ||
| 26 | 27 | ||
| 27 | #endif /* SMC_CLOSE_H */ | 28 | #endif /* SMC_CLOSE_H */ |
diff --git a/net/smc/smc_ism.c b/net/smc/smc_ism.c index 2fff79db1a59..e89e918b88e0 100644 --- a/net/smc/smc_ism.c +++ b/net/smc/smc_ism.c | |||
| @@ -289,6 +289,11 @@ struct smcd_dev *smcd_alloc_dev(struct device *parent, const char *name, | |||
| 289 | INIT_LIST_HEAD(&smcd->vlan); | 289 | INIT_LIST_HEAD(&smcd->vlan); |
| 290 | smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)", | 290 | smcd->event_wq = alloc_ordered_workqueue("ism_evt_wq-%s)", |
| 291 | WQ_MEM_RECLAIM, name); | 291 | WQ_MEM_RECLAIM, name); |
| 292 | if (!smcd->event_wq) { | ||
| 293 | kfree(smcd->conn); | ||
| 294 | kfree(smcd); | ||
| 295 | return NULL; | ||
| 296 | } | ||
| 292 | return smcd; | 297 | return smcd; |
| 293 | } | 298 | } |
| 294 | EXPORT_SYMBOL_GPL(smcd_alloc_dev); | 299 | EXPORT_SYMBOL_GPL(smcd_alloc_dev); |
diff --git a/net/smc/smc_pnet.c b/net/smc/smc_pnet.c index 2b246b94a3af..9f5d8f36f2d7 100644 --- a/net/smc/smc_pnet.c +++ b/net/smc/smc_pnet.c | |||
| @@ -604,7 +604,8 @@ static int smc_pnet_flush(struct sk_buff *skb, struct genl_info *info) | |||
| 604 | { | 604 | { |
| 605 | struct net *net = genl_info_net(info); | 605 | struct net *net = genl_info_net(info); |
| 606 | 606 | ||
| 607 | return smc_pnet_remove_by_pnetid(net, NULL); | 607 | smc_pnet_remove_by_pnetid(net, NULL); |
| 608 | return 0; | ||
| 608 | } | 609 | } |
| 609 | 610 | ||
| 610 | /* SMC_PNETID generic netlink operation definition */ | 611 | /* SMC_PNETID generic netlink operation definition */ |
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index 68a0885b9319..0ba363624339 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c | |||
| @@ -140,13 +140,11 @@ static int __strp_recv(read_descriptor_t *desc, struct sk_buff *orig_skb, | |||
| 140 | /* We are going to append to the frags_list of head. | 140 | /* We are going to append to the frags_list of head. |
| 141 | * Need to unshare the frag_list. | 141 | * Need to unshare the frag_list. |
| 142 | */ | 142 | */ |
| 143 | if (skb_has_frag_list(head)) { | 143 | err = skb_unclone(head, GFP_ATOMIC); |
| 144 | err = skb_unclone(head, GFP_ATOMIC); | 144 | if (err) { |
| 145 | if (err) { | 145 | STRP_STATS_INCR(strp->stats.mem_fail); |
| 146 | STRP_STATS_INCR(strp->stats.mem_fail); | 146 | desc->error = err; |
| 147 | desc->error = err; | 147 | return 0; |
| 148 | return 0; | ||
| 149 | } | ||
| 150 | } | 148 | } |
| 151 | 149 | ||
| 152 | if (unlikely(skb_shinfo(head)->frag_list)) { | 150 | if (unlikely(skb_shinfo(head)->frag_list)) { |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 187d10443a15..1d0395ef62c9 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
| @@ -1540,7 +1540,6 @@ call_start(struct rpc_task *task) | |||
| 1540 | clnt->cl_stats->rpccnt++; | 1540 | clnt->cl_stats->rpccnt++; |
| 1541 | task->tk_action = call_reserve; | 1541 | task->tk_action = call_reserve; |
| 1542 | rpc_task_set_transport(task, clnt); | 1542 | rpc_task_set_transport(task, clnt); |
| 1543 | call_reserve(task); | ||
| 1544 | } | 1543 | } |
| 1545 | 1544 | ||
| 1546 | /* | 1545 | /* |
| @@ -1554,9 +1553,6 @@ call_reserve(struct rpc_task *task) | |||
| 1554 | task->tk_status = 0; | 1553 | task->tk_status = 0; |
| 1555 | task->tk_action = call_reserveresult; | 1554 | task->tk_action = call_reserveresult; |
| 1556 | xprt_reserve(task); | 1555 | xprt_reserve(task); |
| 1557 | if (rpc_task_need_resched(task)) | ||
| 1558 | return; | ||
| 1559 | call_reserveresult(task); | ||
| 1560 | } | 1556 | } |
| 1561 | 1557 | ||
| 1562 | static void call_retry_reserve(struct rpc_task *task); | 1558 | static void call_retry_reserve(struct rpc_task *task); |
| @@ -1579,7 +1575,6 @@ call_reserveresult(struct rpc_task *task) | |||
| 1579 | if (status >= 0) { | 1575 | if (status >= 0) { |
| 1580 | if (task->tk_rqstp) { | 1576 | if (task->tk_rqstp) { |
| 1581 | task->tk_action = call_refresh; | 1577 | task->tk_action = call_refresh; |
| 1582 | call_refresh(task); | ||
| 1583 | return; | 1578 | return; |
| 1584 | } | 1579 | } |
| 1585 | 1580 | ||
| @@ -1605,7 +1600,6 @@ call_reserveresult(struct rpc_task *task) | |||
| 1605 | /* fall through */ | 1600 | /* fall through */ |
| 1606 | case -EAGAIN: /* woken up; retry */ | 1601 | case -EAGAIN: /* woken up; retry */ |
| 1607 | task->tk_action = call_retry_reserve; | 1602 | task->tk_action = call_retry_reserve; |
| 1608 | call_retry_reserve(task); | ||
| 1609 | return; | 1603 | return; |
| 1610 | case -EIO: /* probably a shutdown */ | 1604 | case -EIO: /* probably a shutdown */ |
| 1611 | break; | 1605 | break; |
| @@ -1628,9 +1622,6 @@ call_retry_reserve(struct rpc_task *task) | |||
| 1628 | task->tk_status = 0; | 1622 | task->tk_status = 0; |
| 1629 | task->tk_action = call_reserveresult; | 1623 | task->tk_action = call_reserveresult; |
| 1630 | xprt_retry_reserve(task); | 1624 | xprt_retry_reserve(task); |
| 1631 | if (rpc_task_need_resched(task)) | ||
| 1632 | return; | ||
| 1633 | call_reserveresult(task); | ||
| 1634 | } | 1625 | } |
| 1635 | 1626 | ||
| 1636 | /* | 1627 | /* |
| @@ -1645,9 +1636,6 @@ call_refresh(struct rpc_task *task) | |||
| 1645 | task->tk_status = 0; | 1636 | task->tk_status = 0; |
| 1646 | task->tk_client->cl_stats->rpcauthrefresh++; | 1637 | task->tk_client->cl_stats->rpcauthrefresh++; |
| 1647 | rpcauth_refreshcred(task); | 1638 | rpcauth_refreshcred(task); |
| 1648 | if (rpc_task_need_resched(task)) | ||
| 1649 | return; | ||
| 1650 | call_refreshresult(task); | ||
| 1651 | } | 1639 | } |
| 1652 | 1640 | ||
| 1653 | /* | 1641 | /* |
| @@ -1666,7 +1654,6 @@ call_refreshresult(struct rpc_task *task) | |||
| 1666 | case 0: | 1654 | case 0: |
| 1667 | if (rpcauth_uptodatecred(task)) { | 1655 | if (rpcauth_uptodatecred(task)) { |
| 1668 | task->tk_action = call_allocate; | 1656 | task->tk_action = call_allocate; |
| 1669 | call_allocate(task); | ||
| 1670 | return; | 1657 | return; |
| 1671 | } | 1658 | } |
| 1672 | /* Use rate-limiting and a max number of retries if refresh | 1659 | /* Use rate-limiting and a max number of retries if refresh |
| @@ -1685,7 +1672,6 @@ call_refreshresult(struct rpc_task *task) | |||
| 1685 | task->tk_cred_retry--; | 1672 | task->tk_cred_retry--; |
| 1686 | dprintk("RPC: %5u %s: retry refresh creds\n", | 1673 | dprintk("RPC: %5u %s: retry refresh creds\n", |
| 1687 | task->tk_pid, __func__); | 1674 | task->tk_pid, __func__); |
| 1688 | call_refresh(task); | ||
| 1689 | return; | 1675 | return; |
| 1690 | } | 1676 | } |
| 1691 | dprintk("RPC: %5u %s: refresh creds failed with error %d\n", | 1677 | dprintk("RPC: %5u %s: refresh creds failed with error %d\n", |
| @@ -1711,10 +1697,8 @@ call_allocate(struct rpc_task *task) | |||
| 1711 | task->tk_status = 0; | 1697 | task->tk_status = 0; |
| 1712 | task->tk_action = call_encode; | 1698 | task->tk_action = call_encode; |
| 1713 | 1699 | ||
| 1714 | if (req->rq_buffer) { | 1700 | if (req->rq_buffer) |
| 1715 | call_encode(task); | ||
| 1716 | return; | 1701 | return; |
| 1717 | } | ||
| 1718 | 1702 | ||
| 1719 | if (proc->p_proc != 0) { | 1703 | if (proc->p_proc != 0) { |
| 1720 | BUG_ON(proc->p_arglen == 0); | 1704 | BUG_ON(proc->p_arglen == 0); |
| @@ -1740,12 +1724,8 @@ call_allocate(struct rpc_task *task) | |||
| 1740 | 1724 | ||
| 1741 | status = xprt->ops->buf_alloc(task); | 1725 | status = xprt->ops->buf_alloc(task); |
| 1742 | xprt_inject_disconnect(xprt); | 1726 | xprt_inject_disconnect(xprt); |
| 1743 | if (status == 0) { | 1727 | if (status == 0) |
| 1744 | if (rpc_task_need_resched(task)) | ||
| 1745 | return; | ||
| 1746 | call_encode(task); | ||
| 1747 | return; | 1728 | return; |
| 1748 | } | ||
| 1749 | if (status != -ENOMEM) { | 1729 | if (status != -ENOMEM) { |
| 1750 | rpc_exit(task, status); | 1730 | rpc_exit(task, status); |
| 1751 | return; | 1731 | return; |
| @@ -1828,8 +1808,12 @@ call_encode(struct rpc_task *task) | |||
| 1828 | xprt_request_enqueue_receive(task); | 1808 | xprt_request_enqueue_receive(task); |
| 1829 | xprt_request_enqueue_transmit(task); | 1809 | xprt_request_enqueue_transmit(task); |
| 1830 | out: | 1810 | out: |
| 1831 | task->tk_action = call_bind; | 1811 | task->tk_action = call_transmit; |
| 1832 | call_bind(task); | 1812 | /* Check that the connection is OK */ |
| 1813 | if (!xprt_bound(task->tk_xprt)) | ||
| 1814 | task->tk_action = call_bind; | ||
| 1815 | else if (!xprt_connected(task->tk_xprt)) | ||
| 1816 | task->tk_action = call_connect; | ||
| 1833 | } | 1817 | } |
| 1834 | 1818 | ||
| 1835 | /* | 1819 | /* |
| @@ -1847,7 +1831,6 @@ rpc_task_handle_transmitted(struct rpc_task *task) | |||
| 1847 | { | 1831 | { |
| 1848 | xprt_end_transmit(task); | 1832 | xprt_end_transmit(task); |
| 1849 | task->tk_action = call_transmit_status; | 1833 | task->tk_action = call_transmit_status; |
| 1850 | call_transmit_status(task); | ||
| 1851 | } | 1834 | } |
| 1852 | 1835 | ||
| 1853 | /* | 1836 | /* |
| @@ -1865,7 +1848,6 @@ call_bind(struct rpc_task *task) | |||
| 1865 | 1848 | ||
| 1866 | if (xprt_bound(xprt)) { | 1849 | if (xprt_bound(xprt)) { |
| 1867 | task->tk_action = call_connect; | 1850 | task->tk_action = call_connect; |
| 1868 | call_connect(task); | ||
| 1869 | return; | 1851 | return; |
| 1870 | } | 1852 | } |
| 1871 | 1853 | ||
| @@ -1896,7 +1878,6 @@ call_bind_status(struct rpc_task *task) | |||
| 1896 | dprint_status(task); | 1878 | dprint_status(task); |
| 1897 | task->tk_status = 0; | 1879 | task->tk_status = 0; |
| 1898 | task->tk_action = call_connect; | 1880 | task->tk_action = call_connect; |
| 1899 | call_connect(task); | ||
| 1900 | return; | 1881 | return; |
| 1901 | } | 1882 | } |
| 1902 | 1883 | ||
| @@ -1981,7 +1962,6 @@ call_connect(struct rpc_task *task) | |||
| 1981 | 1962 | ||
| 1982 | if (xprt_connected(xprt)) { | 1963 | if (xprt_connected(xprt)) { |
| 1983 | task->tk_action = call_transmit; | 1964 | task->tk_action = call_transmit; |
| 1984 | call_transmit(task); | ||
| 1985 | return; | 1965 | return; |
| 1986 | } | 1966 | } |
| 1987 | 1967 | ||
| @@ -2051,7 +2031,6 @@ call_connect_status(struct rpc_task *task) | |||
| 2051 | case 0: | 2031 | case 0: |
| 2052 | clnt->cl_stats->netreconn++; | 2032 | clnt->cl_stats->netreconn++; |
| 2053 | task->tk_action = call_transmit; | 2033 | task->tk_action = call_transmit; |
| 2054 | call_transmit(task); | ||
| 2055 | return; | 2034 | return; |
| 2056 | } | 2035 | } |
| 2057 | rpc_exit(task, status); | 2036 | rpc_exit(task, status); |
| @@ -2087,9 +2066,6 @@ call_transmit(struct rpc_task *task) | |||
| 2087 | xprt_transmit(task); | 2066 | xprt_transmit(task); |
| 2088 | } | 2067 | } |
| 2089 | xprt_end_transmit(task); | 2068 | xprt_end_transmit(task); |
| 2090 | if (rpc_task_need_resched(task)) | ||
| 2091 | return; | ||
| 2092 | call_transmit_status(task); | ||
| 2093 | } | 2069 | } |
| 2094 | 2070 | ||
| 2095 | /* | 2071 | /* |
| @@ -2107,9 +2083,6 @@ call_transmit_status(struct rpc_task *task) | |||
| 2107 | if (rpc_task_transmitted(task)) { | 2083 | if (rpc_task_transmitted(task)) { |
| 2108 | if (task->tk_status == 0) | 2084 | if (task->tk_status == 0) |
| 2109 | xprt_request_wait_receive(task); | 2085 | xprt_request_wait_receive(task); |
| 2110 | if (rpc_task_need_resched(task)) | ||
| 2111 | return; | ||
| 2112 | call_status(task); | ||
| 2113 | return; | 2086 | return; |
| 2114 | } | 2087 | } |
| 2115 | 2088 | ||
| @@ -2170,7 +2143,6 @@ call_bc_encode(struct rpc_task *task) | |||
| 2170 | { | 2143 | { |
| 2171 | xprt_request_enqueue_transmit(task); | 2144 | xprt_request_enqueue_transmit(task); |
| 2172 | task->tk_action = call_bc_transmit; | 2145 | task->tk_action = call_bc_transmit; |
| 2173 | call_bc_transmit(task); | ||
| 2174 | } | 2146 | } |
| 2175 | 2147 | ||
| 2176 | /* | 2148 | /* |
| @@ -2261,7 +2233,6 @@ call_status(struct rpc_task *task) | |||
| 2261 | status = task->tk_status; | 2233 | status = task->tk_status; |
| 2262 | if (status >= 0) { | 2234 | if (status >= 0) { |
| 2263 | task->tk_action = call_decode; | 2235 | task->tk_action = call_decode; |
| 2264 | call_decode(task); | ||
| 2265 | return; | 2236 | return; |
| 2266 | } | 2237 | } |
| 2267 | 2238 | ||
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 89a63391d4d4..30cfc0efe699 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
| @@ -90,7 +90,7 @@ static void rpcrdma_xprt_drain(struct rpcrdma_xprt *r_xprt) | |||
| 90 | /* Flush Receives, then wait for deferred Reply work | 90 | /* Flush Receives, then wait for deferred Reply work |
| 91 | * to complete. | 91 | * to complete. |
| 92 | */ | 92 | */ |
| 93 | ib_drain_qp(ia->ri_id->qp); | 93 | ib_drain_rq(ia->ri_id->qp); |
| 94 | drain_workqueue(buf->rb_completion_wq); | 94 | drain_workqueue(buf->rb_completion_wq); |
| 95 | 95 | ||
| 96 | /* Deferred Reply processing might have scheduled | 96 | /* Deferred Reply processing might have scheduled |
diff --git a/net/tipc/link.c b/net/tipc/link.c index 3cb9f326ee6f..6053489c8063 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -876,6 +876,8 @@ void tipc_link_reset(struct tipc_link *l) | |||
| 876 | __skb_queue_head_init(&list); | 876 | __skb_queue_head_init(&list); |
| 877 | 877 | ||
| 878 | l->in_session = false; | 878 | l->in_session = false; |
| 879 | /* Force re-synch of peer session number before establishing */ | ||
| 880 | l->peer_session--; | ||
| 879 | l->session++; | 881 | l->session++; |
| 880 | l->mtu = l->advertised_mtu; | 882 | l->mtu = l->advertised_mtu; |
| 881 | 883 | ||
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c index bff241f03525..89993afe0fbd 100644 --- a/net/tipc/name_table.c +++ b/net/tipc/name_table.c | |||
| @@ -909,7 +909,8 @@ static int tipc_nl_service_list(struct net *net, struct tipc_nl_msg *msg, | |||
| 909 | for (; i < TIPC_NAMETBL_SIZE; i++) { | 909 | for (; i < TIPC_NAMETBL_SIZE; i++) { |
| 910 | head = &tn->nametbl->services[i]; | 910 | head = &tn->nametbl->services[i]; |
| 911 | 911 | ||
| 912 | if (*last_type) { | 912 | if (*last_type || |
| 913 | (!i && *last_key && (*last_lower == *last_key))) { | ||
| 913 | service = tipc_service_find(net, *last_type); | 914 | service = tipc_service_find(net, *last_type); |
| 914 | if (!service) | 915 | if (!service) |
| 915 | return -EPIPE; | 916 | return -EPIPE; |
diff --git a/net/tipc/sysctl.c b/net/tipc/sysctl.c index 3481e4906bd6..9df82a573aa7 100644 --- a/net/tipc/sysctl.c +++ b/net/tipc/sysctl.c | |||
| @@ -38,6 +38,8 @@ | |||
| 38 | 38 | ||
| 39 | #include <linux/sysctl.h> | 39 | #include <linux/sysctl.h> |
| 40 | 40 | ||
| 41 | static int zero; | ||
| 42 | static int one = 1; | ||
| 41 | static struct ctl_table_header *tipc_ctl_hdr; | 43 | static struct ctl_table_header *tipc_ctl_hdr; |
| 42 | 44 | ||
| 43 | static struct ctl_table tipc_table[] = { | 45 | static struct ctl_table tipc_table[] = { |
| @@ -46,14 +48,16 @@ static struct ctl_table tipc_table[] = { | |||
| 46 | .data = &sysctl_tipc_rmem, | 48 | .data = &sysctl_tipc_rmem, |
| 47 | .maxlen = sizeof(sysctl_tipc_rmem), | 49 | .maxlen = sizeof(sysctl_tipc_rmem), |
| 48 | .mode = 0644, | 50 | .mode = 0644, |
| 49 | .proc_handler = proc_dointvec, | 51 | .proc_handler = proc_dointvec_minmax, |
| 52 | .extra1 = &one, | ||
| 50 | }, | 53 | }, |
| 51 | { | 54 | { |
| 52 | .procname = "named_timeout", | 55 | .procname = "named_timeout", |
| 53 | .data = &sysctl_tipc_named_timeout, | 56 | .data = &sysctl_tipc_named_timeout, |
| 54 | .maxlen = sizeof(sysctl_tipc_named_timeout), | 57 | .maxlen = sizeof(sysctl_tipc_named_timeout), |
| 55 | .mode = 0644, | 58 | .mode = 0644, |
| 56 | .proc_handler = proc_dointvec, | 59 | .proc_handler = proc_dointvec_minmax, |
| 60 | .extra1 = &zero, | ||
| 57 | }, | 61 | }, |
| 58 | { | 62 | { |
| 59 | .procname = "sk_filter", | 63 | .procname = "sk_filter", |
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 135a7ee9db03..9f3bdbc1e593 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c | |||
| @@ -52,8 +52,11 @@ static DEFINE_SPINLOCK(tls_device_lock); | |||
| 52 | 52 | ||
| 53 | static void tls_device_free_ctx(struct tls_context *ctx) | 53 | static void tls_device_free_ctx(struct tls_context *ctx) |
| 54 | { | 54 | { |
| 55 | if (ctx->tx_conf == TLS_HW) | 55 | if (ctx->tx_conf == TLS_HW) { |
| 56 | kfree(tls_offload_ctx_tx(ctx)); | 56 | kfree(tls_offload_ctx_tx(ctx)); |
| 57 | kfree(ctx->tx.rec_seq); | ||
| 58 | kfree(ctx->tx.iv); | ||
| 59 | } | ||
| 57 | 60 | ||
| 58 | if (ctx->rx_conf == TLS_HW) | 61 | if (ctx->rx_conf == TLS_HW) |
| 59 | kfree(tls_offload_ctx_rx(ctx)); | 62 | kfree(tls_offload_ctx_rx(ctx)); |
| @@ -216,6 +219,13 @@ void tls_device_sk_destruct(struct sock *sk) | |||
| 216 | } | 219 | } |
| 217 | EXPORT_SYMBOL(tls_device_sk_destruct); | 220 | EXPORT_SYMBOL(tls_device_sk_destruct); |
| 218 | 221 | ||
| 222 | void tls_device_free_resources_tx(struct sock *sk) | ||
| 223 | { | ||
| 224 | struct tls_context *tls_ctx = tls_get_ctx(sk); | ||
| 225 | |||
| 226 | tls_free_partial_record(sk, tls_ctx); | ||
| 227 | } | ||
| 228 | |||
| 219 | static void tls_append_frag(struct tls_record_info *record, | 229 | static void tls_append_frag(struct tls_record_info *record, |
| 220 | struct page_frag *pfrag, | 230 | struct page_frag *pfrag, |
| 221 | int size) | 231 | int size) |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index 0e24edab2535..7e546b8ec000 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
| @@ -208,6 +208,26 @@ int tls_push_partial_record(struct sock *sk, struct tls_context *ctx, | |||
| 208 | return tls_push_sg(sk, ctx, sg, offset, flags); | 208 | return tls_push_sg(sk, ctx, sg, offset, flags); |
| 209 | } | 209 | } |
| 210 | 210 | ||
| 211 | bool tls_free_partial_record(struct sock *sk, struct tls_context *ctx) | ||
| 212 | { | ||
| 213 | struct scatterlist *sg; | ||
| 214 | |||
| 215 | sg = ctx->partially_sent_record; | ||
| 216 | if (!sg) | ||
| 217 | return false; | ||
| 218 | |||
| 219 | while (1) { | ||
| 220 | put_page(sg_page(sg)); | ||
| 221 | sk_mem_uncharge(sk, sg->length); | ||
| 222 | |||
| 223 | if (sg_is_last(sg)) | ||
| 224 | break; | ||
| 225 | sg++; | ||
| 226 | } | ||
| 227 | ctx->partially_sent_record = NULL; | ||
| 228 | return true; | ||
| 229 | } | ||
| 230 | |||
| 211 | static void tls_write_space(struct sock *sk) | 231 | static void tls_write_space(struct sock *sk) |
| 212 | { | 232 | { |
| 213 | struct tls_context *ctx = tls_get_ctx(sk); | 233 | struct tls_context *ctx = tls_get_ctx(sk); |
| @@ -267,6 +287,10 @@ static void tls_sk_proto_close(struct sock *sk, long timeout) | |||
| 267 | kfree(ctx->tx.rec_seq); | 287 | kfree(ctx->tx.rec_seq); |
| 268 | kfree(ctx->tx.iv); | 288 | kfree(ctx->tx.iv); |
| 269 | tls_sw_free_resources_tx(sk); | 289 | tls_sw_free_resources_tx(sk); |
| 290 | #ifdef CONFIG_TLS_DEVICE | ||
| 291 | } else if (ctx->tx_conf == TLS_HW) { | ||
| 292 | tls_device_free_resources_tx(sk); | ||
| 293 | #endif | ||
| 270 | } | 294 | } |
| 271 | 295 | ||
| 272 | if (ctx->rx_conf == TLS_SW) { | 296 | if (ctx->rx_conf == TLS_SW) { |
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 4741edf4bb1e..f780b473827b 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
| @@ -2065,20 +2065,7 @@ void tls_sw_free_resources_tx(struct sock *sk) | |||
| 2065 | /* Free up un-sent records in tx_list. First, free | 2065 | /* Free up un-sent records in tx_list. First, free |
| 2066 | * the partially sent record if any at head of tx_list. | 2066 | * the partially sent record if any at head of tx_list. |
| 2067 | */ | 2067 | */ |
| 2068 | if (tls_ctx->partially_sent_record) { | 2068 | if (tls_free_partial_record(sk, tls_ctx)) { |
| 2069 | struct scatterlist *sg = tls_ctx->partially_sent_record; | ||
| 2070 | |||
| 2071 | while (1) { | ||
| 2072 | put_page(sg_page(sg)); | ||
| 2073 | sk_mem_uncharge(sk, sg->length); | ||
| 2074 | |||
| 2075 | if (sg_is_last(sg)) | ||
| 2076 | break; | ||
| 2077 | sg++; | ||
| 2078 | } | ||
| 2079 | |||
| 2080 | tls_ctx->partially_sent_record = NULL; | ||
| 2081 | |||
| 2082 | rec = list_first_entry(&ctx->tx_list, | 2069 | rec = list_first_entry(&ctx->tx_list, |
| 2083 | struct tls_rec, list); | 2070 | struct tls_rec, list); |
| 2084 | list_del(&rec->list); | 2071 | list_del(&rec->list); |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 33408ba1d7ee..e7ee18ab6cb7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -13614,7 +13614,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 13614 | .doit = nl80211_associate, | 13614 | .doit = nl80211_associate, |
| 13615 | .flags = GENL_UNS_ADMIN_PERM, | 13615 | .flags = GENL_UNS_ADMIN_PERM, |
| 13616 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 13616 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 13617 | NL80211_FLAG_NEED_RTNL, | 13617 | NL80211_FLAG_NEED_RTNL | |
| 13618 | NL80211_FLAG_CLEAR_SKB, | ||
| 13618 | }, | 13619 | }, |
| 13619 | { | 13620 | { |
| 13620 | .cmd = NL80211_CMD_DEAUTHENTICATE, | 13621 | .cmd = NL80211_CMD_DEAUTHENTICATE, |
| @@ -13659,14 +13660,16 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 13659 | .doit = nl80211_connect, | 13660 | .doit = nl80211_connect, |
| 13660 | .flags = GENL_UNS_ADMIN_PERM, | 13661 | .flags = GENL_UNS_ADMIN_PERM, |
| 13661 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 13662 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 13662 | NL80211_FLAG_NEED_RTNL, | 13663 | NL80211_FLAG_NEED_RTNL | |
| 13664 | NL80211_FLAG_CLEAR_SKB, | ||
| 13663 | }, | 13665 | }, |
| 13664 | { | 13666 | { |
| 13665 | .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS, | 13667 | .cmd = NL80211_CMD_UPDATE_CONNECT_PARAMS, |
| 13666 | .doit = nl80211_update_connect_params, | 13668 | .doit = nl80211_update_connect_params, |
| 13667 | .flags = GENL_ADMIN_PERM, | 13669 | .flags = GENL_ADMIN_PERM, |
| 13668 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 13670 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 13669 | NL80211_FLAG_NEED_RTNL, | 13671 | NL80211_FLAG_NEED_RTNL | |
| 13672 | NL80211_FLAG_CLEAR_SKB, | ||
| 13670 | }, | 13673 | }, |
| 13671 | { | 13674 | { |
| 13672 | .cmd = NL80211_CMD_DISCONNECT, | 13675 | .cmd = NL80211_CMD_DISCONNECT, |
| @@ -13691,7 +13694,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 13691 | .doit = nl80211_setdel_pmksa, | 13694 | .doit = nl80211_setdel_pmksa, |
| 13692 | .flags = GENL_UNS_ADMIN_PERM, | 13695 | .flags = GENL_UNS_ADMIN_PERM, |
| 13693 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 13696 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 13694 | NL80211_FLAG_NEED_RTNL, | 13697 | NL80211_FLAG_NEED_RTNL | |
| 13698 | NL80211_FLAG_CLEAR_SKB, | ||
| 13695 | }, | 13699 | }, |
| 13696 | { | 13700 | { |
| 13697 | .cmd = NL80211_CMD_DEL_PMKSA, | 13701 | .cmd = NL80211_CMD_DEL_PMKSA, |
| @@ -13999,7 +14003,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 13999 | .dumpit = nl80211_vendor_cmd_dump, | 14003 | .dumpit = nl80211_vendor_cmd_dump, |
| 14000 | .flags = GENL_UNS_ADMIN_PERM, | 14004 | .flags = GENL_UNS_ADMIN_PERM, |
| 14001 | .internal_flags = NL80211_FLAG_NEED_WIPHY | | 14005 | .internal_flags = NL80211_FLAG_NEED_WIPHY | |
| 14002 | NL80211_FLAG_NEED_RTNL, | 14006 | NL80211_FLAG_NEED_RTNL | |
| 14007 | NL80211_FLAG_CLEAR_SKB, | ||
| 14003 | }, | 14008 | }, |
| 14004 | { | 14009 | { |
| 14005 | .cmd = NL80211_CMD_SET_QOS_MAP, | 14010 | .cmd = NL80211_CMD_SET_QOS_MAP, |
| @@ -14047,7 +14052,8 @@ static const struct genl_ops nl80211_ops[] = { | |||
| 14047 | .cmd = NL80211_CMD_SET_PMK, | 14052 | .cmd = NL80211_CMD_SET_PMK, |
| 14048 | .doit = nl80211_set_pmk, | 14053 | .doit = nl80211_set_pmk, |
| 14049 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | | 14054 | .internal_flags = NL80211_FLAG_NEED_NETDEV_UP | |
| 14050 | NL80211_FLAG_NEED_RTNL, | 14055 | NL80211_FLAG_NEED_RTNL | |
| 14056 | NL80211_FLAG_CLEAR_SKB, | ||
| 14051 | }, | 14057 | }, |
| 14052 | { | 14058 | { |
| 14053 | .cmd = NL80211_CMD_DEL_PMK, | 14059 | .cmd = NL80211_CMD_DEL_PMK, |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 2f1bf91eb226..0ba778f371cb 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -1309,6 +1309,16 @@ reg_intersect_dfs_region(const enum nl80211_dfs_regions dfs_region1, | |||
| 1309 | return dfs_region1; | 1309 | return dfs_region1; |
| 1310 | } | 1310 | } |
| 1311 | 1311 | ||
| 1312 | static void reg_wmm_rules_intersect(const struct ieee80211_wmm_ac *wmm_ac1, | ||
| 1313 | const struct ieee80211_wmm_ac *wmm_ac2, | ||
| 1314 | struct ieee80211_wmm_ac *intersect) | ||
| 1315 | { | ||
| 1316 | intersect->cw_min = max_t(u16, wmm_ac1->cw_min, wmm_ac2->cw_min); | ||
| 1317 | intersect->cw_max = max_t(u16, wmm_ac1->cw_max, wmm_ac2->cw_max); | ||
| 1318 | intersect->cot = min_t(u16, wmm_ac1->cot, wmm_ac2->cot); | ||
| 1319 | intersect->aifsn = max_t(u8, wmm_ac1->aifsn, wmm_ac2->aifsn); | ||
| 1320 | } | ||
| 1321 | |||
| 1312 | /* | 1322 | /* |
| 1313 | * Helper for regdom_intersect(), this does the real | 1323 | * Helper for regdom_intersect(), this does the real |
| 1314 | * mathematical intersection fun | 1324 | * mathematical intersection fun |
| @@ -1323,6 +1333,8 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
| 1323 | struct ieee80211_freq_range *freq_range; | 1333 | struct ieee80211_freq_range *freq_range; |
| 1324 | const struct ieee80211_power_rule *power_rule1, *power_rule2; | 1334 | const struct ieee80211_power_rule *power_rule1, *power_rule2; |
| 1325 | struct ieee80211_power_rule *power_rule; | 1335 | struct ieee80211_power_rule *power_rule; |
| 1336 | const struct ieee80211_wmm_rule *wmm_rule1, *wmm_rule2; | ||
| 1337 | struct ieee80211_wmm_rule *wmm_rule; | ||
| 1326 | u32 freq_diff, max_bandwidth1, max_bandwidth2; | 1338 | u32 freq_diff, max_bandwidth1, max_bandwidth2; |
| 1327 | 1339 | ||
| 1328 | freq_range1 = &rule1->freq_range; | 1340 | freq_range1 = &rule1->freq_range; |
| @@ -1333,6 +1345,10 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
| 1333 | power_rule2 = &rule2->power_rule; | 1345 | power_rule2 = &rule2->power_rule; |
| 1334 | power_rule = &intersected_rule->power_rule; | 1346 | power_rule = &intersected_rule->power_rule; |
| 1335 | 1347 | ||
| 1348 | wmm_rule1 = &rule1->wmm_rule; | ||
| 1349 | wmm_rule2 = &rule2->wmm_rule; | ||
| 1350 | wmm_rule = &intersected_rule->wmm_rule; | ||
| 1351 | |||
| 1336 | freq_range->start_freq_khz = max(freq_range1->start_freq_khz, | 1352 | freq_range->start_freq_khz = max(freq_range1->start_freq_khz, |
| 1337 | freq_range2->start_freq_khz); | 1353 | freq_range2->start_freq_khz); |
| 1338 | freq_range->end_freq_khz = min(freq_range1->end_freq_khz, | 1354 | freq_range->end_freq_khz = min(freq_range1->end_freq_khz, |
| @@ -1376,6 +1392,29 @@ static int reg_rules_intersect(const struct ieee80211_regdomain *rd1, | |||
| 1376 | intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms, | 1392 | intersected_rule->dfs_cac_ms = max(rule1->dfs_cac_ms, |
| 1377 | rule2->dfs_cac_ms); | 1393 | rule2->dfs_cac_ms); |
| 1378 | 1394 | ||
| 1395 | if (rule1->has_wmm && rule2->has_wmm) { | ||
| 1396 | u8 ac; | ||
| 1397 | |||
| 1398 | for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { | ||
| 1399 | reg_wmm_rules_intersect(&wmm_rule1->client[ac], | ||
| 1400 | &wmm_rule2->client[ac], | ||
| 1401 | &wmm_rule->client[ac]); | ||
| 1402 | reg_wmm_rules_intersect(&wmm_rule1->ap[ac], | ||
| 1403 | &wmm_rule2->ap[ac], | ||
| 1404 | &wmm_rule->ap[ac]); | ||
| 1405 | } | ||
| 1406 | |||
| 1407 | intersected_rule->has_wmm = true; | ||
| 1408 | } else if (rule1->has_wmm) { | ||
| 1409 | *wmm_rule = *wmm_rule1; | ||
| 1410 | intersected_rule->has_wmm = true; | ||
| 1411 | } else if (rule2->has_wmm) { | ||
| 1412 | *wmm_rule = *wmm_rule2; | ||
| 1413 | intersected_rule->has_wmm = true; | ||
| 1414 | } else { | ||
| 1415 | intersected_rule->has_wmm = false; | ||
| 1416 | } | ||
| 1417 | |||
| 1379 | if (!is_valid_reg_rule(intersected_rule)) | 1418 | if (!is_valid_reg_rule(intersected_rule)) |
| 1380 | return -EINVAL; | 1419 | return -EINVAL; |
| 1381 | 1420 | ||
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 287518c6caa4..04d888628f29 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
| @@ -190,10 +190,9 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen, | |||
| 190 | /* copy subelement as we need to change its content to | 190 | /* copy subelement as we need to change its content to |
| 191 | * mark an ie after it is processed. | 191 | * mark an ie after it is processed. |
| 192 | */ | 192 | */ |
| 193 | sub_copy = kmalloc(subie_len, gfp); | 193 | sub_copy = kmemdup(subelement, subie_len, gfp); |
| 194 | if (!sub_copy) | 194 | if (!sub_copy) |
| 195 | return 0; | 195 | return 0; |
| 196 | memcpy(sub_copy, subelement, subie_len); | ||
| 197 | 196 | ||
| 198 | pos = &new_ie[0]; | 197 | pos = &new_ie[0]; |
| 199 | 198 | ||
diff --git a/net/wireless/util.c b/net/wireless/util.c index e4b8db5e81ec..75899b62bdc9 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
| @@ -1220,9 +1220,11 @@ static u32 cfg80211_calculate_bitrate_he(struct rate_info *rate) | |||
| 1220 | else if (rate->bw == RATE_INFO_BW_HE_RU && | 1220 | else if (rate->bw == RATE_INFO_BW_HE_RU && |
| 1221 | rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26) | 1221 | rate->he_ru_alloc == NL80211_RATE_INFO_HE_RU_ALLOC_26) |
| 1222 | result = rates_26[rate->he_gi]; | 1222 | result = rates_26[rate->he_gi]; |
| 1223 | else if (WARN(1, "invalid HE MCS: bw:%d, ru:%d\n", | 1223 | else { |
| 1224 | rate->bw, rate->he_ru_alloc)) | 1224 | WARN(1, "invalid HE MCS: bw:%d, ru:%d\n", |
| 1225 | rate->bw, rate->he_ru_alloc); | ||
| 1225 | return 0; | 1226 | return 0; |
| 1227 | } | ||
| 1226 | 1228 | ||
| 1227 | /* now scale to the appropriate MCS */ | 1229 | /* now scale to the appropriate MCS */ |
| 1228 | tmp = result; | 1230 | tmp = result; |
