diff options
Diffstat (limited to 'net')
40 files changed, 352 insertions, 171 deletions
diff --git a/net/9p/trans_virtio.c b/net/9p/trans_virtio.c index d8e376a5f0f1..36a1a739ad68 100644 --- a/net/9p/trans_virtio.c +++ b/net/9p/trans_virtio.c | |||
| @@ -658,14 +658,30 @@ p9_virtio_create(struct p9_client *client, const char *devname, char *args) | |||
| 658 | static void p9_virtio_remove(struct virtio_device *vdev) | 658 | static void p9_virtio_remove(struct virtio_device *vdev) |
| 659 | { | 659 | { |
| 660 | struct virtio_chan *chan = vdev->priv; | 660 | struct virtio_chan *chan = vdev->priv; |
| 661 | 661 | unsigned long warning_time; | |
| 662 | if (chan->inuse) | ||
| 663 | p9_virtio_close(chan->client); | ||
| 664 | vdev->config->del_vqs(vdev); | ||
| 665 | 662 | ||
| 666 | mutex_lock(&virtio_9p_lock); | 663 | mutex_lock(&virtio_9p_lock); |
| 664 | |||
| 665 | /* Remove self from list so we don't get new users. */ | ||
| 667 | list_del(&chan->chan_list); | 666 | list_del(&chan->chan_list); |
| 667 | warning_time = jiffies; | ||
| 668 | |||
| 669 | /* Wait for existing users to close. */ | ||
| 670 | while (chan->inuse) { | ||
| 671 | mutex_unlock(&virtio_9p_lock); | ||
| 672 | msleep(250); | ||
| 673 | if (time_after(jiffies, warning_time + 10 * HZ)) { | ||
| 674 | dev_emerg(&vdev->dev, | ||
| 675 | "p9_virtio_remove: waiting for device in use.\n"); | ||
| 676 | warning_time = jiffies; | ||
| 677 | } | ||
| 678 | mutex_lock(&virtio_9p_lock); | ||
| 679 | } | ||
| 680 | |||
| 668 | mutex_unlock(&virtio_9p_lock); | 681 | mutex_unlock(&virtio_9p_lock); |
| 682 | |||
| 683 | vdev->config->del_vqs(vdev); | ||
| 684 | |||
| 669 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); | 685 | sysfs_remove_file(&(vdev->dev.kobj), &dev_attr_mount_tag.attr); |
| 670 | kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE); | 686 | kobject_uevent(&(vdev->dev.kobj), KOBJ_CHANGE); |
| 671 | kfree(chan->tag); | 687 | kfree(chan->tag); |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index b087d278c679..1849d96b3c91 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
| @@ -563,6 +563,8 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
| 563 | */ | 563 | */ |
| 564 | del_nbp(p); | 564 | del_nbp(p); |
| 565 | 565 | ||
| 566 | dev_set_mtu(br->dev, br_min_mtu(br)); | ||
| 567 | |||
| 566 | spin_lock_bh(&br->lock); | 568 | spin_lock_bh(&br->lock); |
| 567 | changed_addr = br_stp_recalculate_bridge_id(br); | 569 | changed_addr = br_stp_recalculate_bridge_id(br); |
| 568 | spin_unlock_bh(&br->lock); | 570 | spin_unlock_bh(&br->lock); |
diff --git a/net/caif/caif_socket.c b/net/caif/caif_socket.c index 769b185fefbd..a6e2da0bc718 100644 --- a/net/caif/caif_socket.c +++ b/net/caif/caif_socket.c | |||
| @@ -281,7 +281,7 @@ static int caif_seqpkt_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 281 | int copylen; | 281 | int copylen; |
| 282 | 282 | ||
| 283 | ret = -EOPNOTSUPP; | 283 | ret = -EOPNOTSUPP; |
| 284 | if (m->msg_flags&MSG_OOB) | 284 | if (flags & MSG_OOB) |
| 285 | goto read_error; | 285 | goto read_error; |
| 286 | 286 | ||
| 287 | skb = skb_recv_datagram(sk, flags, 0 , &ret); | 287 | skb = skb_recv_datagram(sk, flags, 0 , &ret); |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 66e08040ced7..32d710eaf1fc 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
| @@ -259,6 +259,9 @@ int can_send(struct sk_buff *skb, int loop) | |||
| 259 | goto inval_skb; | 259 | goto inval_skb; |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
| 263 | |||
| 264 | skb_reset_mac_header(skb); | ||
| 262 | skb_reset_network_header(skb); | 265 | skb_reset_network_header(skb); |
| 263 | skb_reset_transport_header(skb); | 266 | skb_reset_transport_header(skb); |
| 264 | 267 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 25b4b5d23485..ee0608bb3bc0 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
| @@ -2166,28 +2166,28 @@ replay: | |||
| 2166 | } | 2166 | } |
| 2167 | } | 2167 | } |
| 2168 | err = rtnl_configure_link(dev, ifm); | 2168 | err = rtnl_configure_link(dev, ifm); |
| 2169 | if (err < 0) { | 2169 | if (err < 0) |
| 2170 | if (ops->newlink) { | 2170 | goto out_unregister; |
| 2171 | LIST_HEAD(list_kill); | ||
| 2172 | |||
| 2173 | ops->dellink(dev, &list_kill); | ||
| 2174 | unregister_netdevice_many(&list_kill); | ||
| 2175 | } else { | ||
| 2176 | unregister_netdevice(dev); | ||
| 2177 | } | ||
| 2178 | goto out; | ||
| 2179 | } | ||
| 2180 | |||
| 2181 | if (link_net) { | 2171 | if (link_net) { |
| 2182 | err = dev_change_net_namespace(dev, dest_net, ifname); | 2172 | err = dev_change_net_namespace(dev, dest_net, ifname); |
| 2183 | if (err < 0) | 2173 | if (err < 0) |
| 2184 | unregister_netdevice(dev); | 2174 | goto out_unregister; |
| 2185 | } | 2175 | } |
| 2186 | out: | 2176 | out: |
| 2187 | if (link_net) | 2177 | if (link_net) |
| 2188 | put_net(link_net); | 2178 | put_net(link_net); |
| 2189 | put_net(dest_net); | 2179 | put_net(dest_net); |
| 2190 | return err; | 2180 | return err; |
| 2181 | out_unregister: | ||
| 2182 | if (ops->newlink) { | ||
| 2183 | LIST_HEAD(list_kill); | ||
| 2184 | |||
| 2185 | ops->dellink(dev, &list_kill); | ||
| 2186 | unregister_netdevice_many(&list_kill); | ||
| 2187 | } else { | ||
| 2188 | unregister_netdevice(dev); | ||
| 2189 | } | ||
| 2190 | goto out; | ||
| 2191 | } | 2191 | } |
| 2192 | } | 2192 | } |
| 2193 | 2193 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index f80507823531..8e4ac97c8477 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
| @@ -3733,9 +3733,13 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
| 3733 | struct sock *sk, int tstype) | 3733 | struct sock *sk, int tstype) |
| 3734 | { | 3734 | { |
| 3735 | struct sk_buff *skb; | 3735 | struct sk_buff *skb; |
| 3736 | bool tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | 3736 | bool tsonly; |
| 3737 | 3737 | ||
| 3738 | if (!sk || !skb_may_tx_timestamp(sk, tsonly)) | 3738 | if (!sk) |
| 3739 | return; | ||
| 3740 | |||
| 3741 | tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | ||
| 3742 | if (!skb_may_tx_timestamp(sk, tsonly)) | ||
| 3739 | return; | 3743 | return; |
| 3740 | 3744 | ||
| 3741 | if (tsonly) | 3745 | if (tsonly) |
| @@ -4173,7 +4177,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
| 4173 | skb->ignore_df = 0; | 4177 | skb->ignore_df = 0; |
| 4174 | skb_dst_drop(skb); | 4178 | skb_dst_drop(skb); |
| 4175 | skb->mark = 0; | 4179 | skb->mark = 0; |
| 4176 | skb->sender_cpu = 0; | 4180 | skb_sender_cpu_clear(skb); |
| 4177 | skb_init_secmark(skb); | 4181 | skb_init_secmark(skb); |
| 4178 | secpath_reset(skb); | 4182 | secpath_reset(skb); |
| 4179 | nf_reset(skb); | 4183 | nf_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index 93c8b20c91e4..78e89eb7eb70 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
| @@ -1655,6 +1655,10 @@ void sock_rfree(struct sk_buff *skb) | |||
| 1655 | } | 1655 | } |
| 1656 | EXPORT_SYMBOL(sock_rfree); | 1656 | EXPORT_SYMBOL(sock_rfree); |
| 1657 | 1657 | ||
| 1658 | /* | ||
| 1659 | * Buffer destructor for skbs that are not used directly in read or write | ||
| 1660 | * path, e.g. for error handler skbs. Automatically called from kfree_skb. | ||
| 1661 | */ | ||
| 1658 | void sock_efree(struct sk_buff *skb) | 1662 | void sock_efree(struct sk_buff *skb) |
| 1659 | { | 1663 | { |
| 1660 | sock_put(skb->sk); | 1664 | sock_put(skb->sk); |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index 433424804284..8ce351ffceb1 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
| @@ -25,6 +25,8 @@ | |||
| 25 | static int zero = 0; | 25 | static int zero = 0; |
| 26 | static int one = 1; | 26 | static int one = 1; |
| 27 | static int ushort_max = USHRT_MAX; | 27 | static int ushort_max = USHRT_MAX; |
| 28 | static int min_sndbuf = SOCK_MIN_SNDBUF; | ||
| 29 | static int min_rcvbuf = SOCK_MIN_RCVBUF; | ||
| 28 | 30 | ||
| 29 | static int net_msg_warn; /* Unused, but still a sysctl */ | 31 | static int net_msg_warn; /* Unused, but still a sysctl */ |
| 30 | 32 | ||
| @@ -237,7 +239,7 @@ static struct ctl_table net_core_table[] = { | |||
| 237 | .maxlen = sizeof(int), | 239 | .maxlen = sizeof(int), |
| 238 | .mode = 0644, | 240 | .mode = 0644, |
| 239 | .proc_handler = proc_dointvec_minmax, | 241 | .proc_handler = proc_dointvec_minmax, |
| 240 | .extra1 = &one, | 242 | .extra1 = &min_sndbuf, |
| 241 | }, | 243 | }, |
| 242 | { | 244 | { |
| 243 | .procname = "rmem_max", | 245 | .procname = "rmem_max", |
| @@ -245,7 +247,7 @@ static struct ctl_table net_core_table[] = { | |||
| 245 | .maxlen = sizeof(int), | 247 | .maxlen = sizeof(int), |
| 246 | .mode = 0644, | 248 | .mode = 0644, |
| 247 | .proc_handler = proc_dointvec_minmax, | 249 | .proc_handler = proc_dointvec_minmax, |
| 248 | .extra1 = &one, | 250 | .extra1 = &min_rcvbuf, |
| 249 | }, | 251 | }, |
| 250 | { | 252 | { |
| 251 | .procname = "wmem_default", | 253 | .procname = "wmem_default", |
| @@ -253,7 +255,7 @@ static struct ctl_table net_core_table[] = { | |||
| 253 | .maxlen = sizeof(int), | 255 | .maxlen = sizeof(int), |
| 254 | .mode = 0644, | 256 | .mode = 0644, |
| 255 | .proc_handler = proc_dointvec_minmax, | 257 | .proc_handler = proc_dointvec_minmax, |
| 256 | .extra1 = &one, | 258 | .extra1 = &min_sndbuf, |
| 257 | }, | 259 | }, |
| 258 | { | 260 | { |
| 259 | .procname = "rmem_default", | 261 | .procname = "rmem_default", |
| @@ -261,7 +263,7 @@ static struct ctl_table net_core_table[] = { | |||
| 261 | .maxlen = sizeof(int), | 263 | .maxlen = sizeof(int), |
| 262 | .mode = 0644, | 264 | .mode = 0644, |
| 263 | .proc_handler = proc_dointvec_minmax, | 265 | .proc_handler = proc_dointvec_minmax, |
| 264 | .extra1 = &one, | 266 | .extra1 = &min_rcvbuf, |
| 265 | }, | 267 | }, |
| 266 | { | 268 | { |
| 267 | .procname = "dev_weight", | 269 | .procname = "dev_weight", |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index 14d02ea905b6..3e44b9b0b78e 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
| @@ -268,6 +268,7 @@ static int inet_csk_wait_for_connect(struct sock *sk, long timeo) | |||
| 268 | release_sock(sk); | 268 | release_sock(sk); |
| 269 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) | 269 | if (reqsk_queue_empty(&icsk->icsk_accept_queue)) |
| 270 | timeo = schedule_timeout(timeo); | 270 | timeo = schedule_timeout(timeo); |
| 271 | sched_annotate_sleep(); | ||
| 271 | lock_sock(sk); | 272 | lock_sock(sk); |
| 272 | err = 0; | 273 | err = 0; |
| 273 | if (!reqsk_queue_empty(&icsk->icsk_accept_queue)) | 274 | if (!reqsk_queue_empty(&icsk->icsk_accept_queue)) |
diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 81751f12645f..592aff37366b 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c | |||
| @@ -71,6 +71,20 @@ static inline void inet_diag_unlock_handler( | |||
| 71 | mutex_unlock(&inet_diag_table_mutex); | 71 | mutex_unlock(&inet_diag_table_mutex); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | static size_t inet_sk_attr_size(void) | ||
| 75 | { | ||
| 76 | return nla_total_size(sizeof(struct tcp_info)) | ||
| 77 | + nla_total_size(1) /* INET_DIAG_SHUTDOWN */ | ||
| 78 | + nla_total_size(1) /* INET_DIAG_TOS */ | ||
| 79 | + nla_total_size(1) /* INET_DIAG_TCLASS */ | ||
| 80 | + nla_total_size(sizeof(struct inet_diag_meminfo)) | ||
| 81 | + nla_total_size(sizeof(struct inet_diag_msg)) | ||
| 82 | + nla_total_size(SK_MEMINFO_VARS * sizeof(u32)) | ||
| 83 | + nla_total_size(TCP_CA_NAME_MAX) | ||
| 84 | + nla_total_size(sizeof(struct tcpvegas_info)) | ||
| 85 | + 64; | ||
| 86 | } | ||
| 87 | |||
| 74 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, | 88 | int inet_sk_diag_fill(struct sock *sk, struct inet_connection_sock *icsk, |
| 75 | struct sk_buff *skb, struct inet_diag_req_v2 *req, | 89 | struct sk_buff *skb, struct inet_diag_req_v2 *req, |
| 76 | struct user_namespace *user_ns, | 90 | struct user_namespace *user_ns, |
| @@ -326,9 +340,7 @@ int inet_diag_dump_one_icsk(struct inet_hashinfo *hashinfo, struct sk_buff *in_s | |||
| 326 | if (err) | 340 | if (err) |
| 327 | goto out; | 341 | goto out; |
| 328 | 342 | ||
| 329 | rep = nlmsg_new(sizeof(struct inet_diag_msg) + | 343 | rep = nlmsg_new(inet_sk_attr_size(), GFP_KERNEL); |
| 330 | sizeof(struct inet_diag_meminfo) + | ||
| 331 | sizeof(struct tcp_info) + 64, GFP_KERNEL); | ||
| 332 | if (!rep) { | 344 | if (!rep) { |
| 333 | err = -ENOMEM; | 345 | err = -ENOMEM; |
| 334 | goto out; | 346 | goto out; |
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c index 787b3c294ce6..d9bc28ac5d1b 100644 --- a/net/ipv4/ip_forward.c +++ b/net/ipv4/ip_forward.c | |||
| @@ -67,6 +67,7 @@ static int ip_forward_finish(struct sk_buff *skb) | |||
| 67 | if (unlikely(opt->optlen)) | 67 | if (unlikely(opt->optlen)) |
| 68 | ip_forward_options(skb); | 68 | ip_forward_options(skb); |
| 69 | 69 | ||
| 70 | skb_sender_cpu_clear(skb); | ||
| 70 | return dst_output(skb); | 71 | return dst_output(skb); |
| 71 | } | 72 | } |
| 72 | 73 | ||
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 2c8d98e728c0..145a50c4d566 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
| @@ -659,27 +659,30 @@ EXPORT_SYMBOL(ip_defrag); | |||
| 659 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) | 659 | struct sk_buff *ip_check_defrag(struct sk_buff *skb, u32 user) |
| 660 | { | 660 | { |
| 661 | struct iphdr iph; | 661 | struct iphdr iph; |
| 662 | int netoff; | ||
| 662 | u32 len; | 663 | u32 len; |
| 663 | 664 | ||
| 664 | if (skb->protocol != htons(ETH_P_IP)) | 665 | if (skb->protocol != htons(ETH_P_IP)) |
| 665 | return skb; | 666 | return skb; |
| 666 | 667 | ||
| 667 | if (skb_copy_bits(skb, 0, &iph, sizeof(iph)) < 0) | 668 | netoff = skb_network_offset(skb); |
| 669 | |||
| 670 | if (skb_copy_bits(skb, netoff, &iph, sizeof(iph)) < 0) | ||
| 668 | return skb; | 671 | return skb; |
| 669 | 672 | ||
| 670 | if (iph.ihl < 5 || iph.version != 4) | 673 | if (iph.ihl < 5 || iph.version != 4) |
| 671 | return skb; | 674 | return skb; |
| 672 | 675 | ||
| 673 | len = ntohs(iph.tot_len); | 676 | len = ntohs(iph.tot_len); |
| 674 | if (skb->len < len || len < (iph.ihl * 4)) | 677 | if (skb->len < netoff + len || len < (iph.ihl * 4)) |
| 675 | return skb; | 678 | return skb; |
| 676 | 679 | ||
| 677 | if (ip_is_fragment(&iph)) { | 680 | if (ip_is_fragment(&iph)) { |
| 678 | skb = skb_share_check(skb, GFP_ATOMIC); | 681 | skb = skb_share_check(skb, GFP_ATOMIC); |
| 679 | if (skb) { | 682 | if (skb) { |
| 680 | if (!pskb_may_pull(skb, iph.ihl*4)) | 683 | if (!pskb_may_pull(skb, netoff + iph.ihl * 4)) |
| 681 | return skb; | 684 | return skb; |
| 682 | if (pskb_trim_rcsum(skb, len)) | 685 | if (pskb_trim_rcsum(skb, netoff + len)) |
| 683 | return skb; | 686 | return skb; |
| 684 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); | 687 | memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); |
| 685 | if (ip_defrag(skb, user)) | 688 | if (ip_defrag(skb, user)) |
diff --git a/net/ipv4/ip_sockglue.c b/net/ipv4/ip_sockglue.c index 31d8c71986b4..5cd99271d3a6 100644 --- a/net/ipv4/ip_sockglue.c +++ b/net/ipv4/ip_sockglue.c | |||
| @@ -432,17 +432,32 @@ void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 inf | |||
| 432 | kfree_skb(skb); | 432 | kfree_skb(skb); |
| 433 | } | 433 | } |
| 434 | 434 | ||
| 435 | static bool ipv4_pktinfo_prepare_errqueue(const struct sock *sk, | 435 | /* IPv4 supports cmsg on all imcp errors and some timestamps |
| 436 | const struct sk_buff *skb, | 436 | * |
| 437 | int ee_origin) | 437 | * Timestamp code paths do not initialize the fields expected by cmsg: |
| 438 | * the PKTINFO fields in skb->cb[]. Fill those in here. | ||
| 439 | */ | ||
| 440 | static bool ipv4_datagram_support_cmsg(const struct sock *sk, | ||
| 441 | struct sk_buff *skb, | ||
| 442 | int ee_origin) | ||
| 438 | { | 443 | { |
| 439 | struct in_pktinfo *info = PKTINFO_SKB_CB(skb); | 444 | struct in_pktinfo *info; |
| 445 | |||
| 446 | if (ee_origin == SO_EE_ORIGIN_ICMP) | ||
| 447 | return true; | ||
| 440 | 448 | ||
| 441 | if ((ee_origin != SO_EE_ORIGIN_TIMESTAMPING) || | 449 | if (ee_origin == SO_EE_ORIGIN_LOCAL) |
| 442 | (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || | 450 | return false; |
| 451 | |||
| 452 | /* Support IP_PKTINFO on tstamp packets if requested, to correlate | ||
| 453 | * timestamp with egress dev. Not possible for packets without dev | ||
| 454 | * or without payload (SOF_TIMESTAMPING_OPT_TSONLY). | ||
| 455 | */ | ||
| 456 | if ((!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG)) || | ||
| 443 | (!skb->dev)) | 457 | (!skb->dev)) |
| 444 | return false; | 458 | return false; |
| 445 | 459 | ||
| 460 | info = PKTINFO_SKB_CB(skb); | ||
| 446 | info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; | 461 | info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr; |
| 447 | info->ipi_ifindex = skb->dev->ifindex; | 462 | info->ipi_ifindex = skb->dev->ifindex; |
| 448 | return true; | 463 | return true; |
| @@ -483,7 +498,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 483 | 498 | ||
| 484 | serr = SKB_EXT_ERR(skb); | 499 | serr = SKB_EXT_ERR(skb); |
| 485 | 500 | ||
| 486 | if (sin && skb->len) { | 501 | if (sin && serr->port) { |
| 487 | sin->sin_family = AF_INET; | 502 | sin->sin_family = AF_INET; |
| 488 | sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + | 503 | sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) + |
| 489 | serr->addr_offset); | 504 | serr->addr_offset); |
| @@ -496,9 +511,7 @@ int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 496 | sin = &errhdr.offender; | 511 | sin = &errhdr.offender; |
| 497 | memset(sin, 0, sizeof(*sin)); | 512 | memset(sin, 0, sizeof(*sin)); |
| 498 | 513 | ||
| 499 | if (skb->len && | 514 | if (ipv4_datagram_support_cmsg(sk, skb, serr->ee.ee_origin)) { |
| 500 | (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || | ||
| 501 | ipv4_pktinfo_prepare_errqueue(sk, skb, serr->ee.ee_origin))) { | ||
| 502 | sin->sin_family = AF_INET; | 515 | sin->sin_family = AF_INET; |
| 503 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; | 516 | sin->sin_addr.s_addr = ip_hdr(skb)->saddr; |
| 504 | if (inet_sk(sk)->cmsg_flags) | 517 | if (inet_sk(sk)->cmsg_flags) |
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c index e9f66e1cda50..208d5439e59b 100644 --- a/net/ipv4/ping.c +++ b/net/ipv4/ping.c | |||
| @@ -259,6 +259,9 @@ int ping_init_sock(struct sock *sk) | |||
| 259 | kgid_t low, high; | 259 | kgid_t low, high; |
| 260 | int ret = 0; | 260 | int ret = 0; |
| 261 | 261 | ||
| 262 | if (sk->sk_family == AF_INET6) | ||
| 263 | sk->sk_ipv6only = 1; | ||
| 264 | |||
| 262 | inet_get_ping_group_range_net(net, &low, &high); | 265 | inet_get_ping_group_range_net(net, &low, &high); |
| 263 | if (gid_lte(low, group) && gid_lte(group, high)) | 266 | if (gid_lte(low, group) && gid_lte(group, high)) |
| 264 | return 0; | 267 | return 0; |
| @@ -305,6 +308,11 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, | |||
| 305 | if (addr_len < sizeof(*addr)) | 308 | if (addr_len < sizeof(*addr)) |
| 306 | return -EINVAL; | 309 | return -EINVAL; |
| 307 | 310 | ||
| 311 | if (addr->sin_family != AF_INET && | ||
| 312 | !(addr->sin_family == AF_UNSPEC && | ||
| 313 | addr->sin_addr.s_addr == htonl(INADDR_ANY))) | ||
| 314 | return -EAFNOSUPPORT; | ||
| 315 | |||
| 308 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n", | 316 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI4,port=%d)\n", |
| 309 | sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port)); | 317 | sk, &addr->sin_addr.s_addr, ntohs(addr->sin_port)); |
| 310 | 318 | ||
| @@ -330,7 +338,7 @@ static int ping_check_bind_addr(struct sock *sk, struct inet_sock *isk, | |||
| 330 | return -EINVAL; | 338 | return -EINVAL; |
| 331 | 339 | ||
| 332 | if (addr->sin6_family != AF_INET6) | 340 | if (addr->sin6_family != AF_INET6) |
| 333 | return -EINVAL; | 341 | return -EAFNOSUPPORT; |
| 334 | 342 | ||
| 335 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n", | 343 | pr_debug("ping_check_bind_addr(sk=%p,addr=%pI6c,port=%d)\n", |
| 336 | sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); | 344 | sk, addr->sin6_addr.s6_addr, ntohs(addr->sin6_port)); |
| @@ -716,7 +724,7 @@ static int ping_v4_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *m | |||
| 716 | if (msg->msg_namelen < sizeof(*usin)) | 724 | if (msg->msg_namelen < sizeof(*usin)) |
| 717 | return -EINVAL; | 725 | return -EINVAL; |
| 718 | if (usin->sin_family != AF_INET) | 726 | if (usin->sin_family != AF_INET) |
| 719 | return -EINVAL; | 727 | return -EAFNOSUPPORT; |
| 720 | daddr = usin->sin_addr.s_addr; | 728 | daddr = usin->sin_addr.s_addr; |
| 721 | /* no remote port */ | 729 | /* no remote port */ |
| 722 | } else { | 730 | } else { |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 9d72a0fcd928..995a2259bcfc 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
| @@ -835,17 +835,13 @@ static unsigned int tcp_xmit_size_goal(struct sock *sk, u32 mss_now, | |||
| 835 | int large_allowed) | 835 | int large_allowed) |
| 836 | { | 836 | { |
| 837 | struct tcp_sock *tp = tcp_sk(sk); | 837 | struct tcp_sock *tp = tcp_sk(sk); |
| 838 | u32 new_size_goal, size_goal, hlen; | 838 | u32 new_size_goal, size_goal; |
| 839 | 839 | ||
| 840 | if (!large_allowed || !sk_can_gso(sk)) | 840 | if (!large_allowed || !sk_can_gso(sk)) |
| 841 | return mss_now; | 841 | return mss_now; |
| 842 | 842 | ||
| 843 | /* Maybe we should/could use sk->sk_prot->max_header here ? */ | 843 | /* Note : tcp_tso_autosize() will eventually split this later */ |
| 844 | hlen = inet_csk(sk)->icsk_af_ops->net_header_len + | 844 | new_size_goal = sk->sk_gso_max_size - 1 - MAX_TCP_HEADER; |
| 845 | inet_csk(sk)->icsk_ext_hdr_len + | ||
| 846 | tp->tcp_header_len; | ||
| 847 | |||
| 848 | new_size_goal = sk->sk_gso_max_size - 1 - hlen; | ||
| 849 | new_size_goal = tcp_bound_to_half_wnd(tp, new_size_goal); | 845 | new_size_goal = tcp_bound_to_half_wnd(tp, new_size_goal); |
| 850 | 846 | ||
| 851 | /* We try hard to avoid divides here */ | 847 | /* We try hard to avoid divides here */ |
diff --git a/net/ipv4/tcp_cong.c b/net/ipv4/tcp_cong.c index d694088214cd..62856e185a93 100644 --- a/net/ipv4/tcp_cong.c +++ b/net/ipv4/tcp_cong.c | |||
| @@ -378,6 +378,12 @@ EXPORT_SYMBOL_GPL(tcp_slow_start); | |||
| 378 | */ | 378 | */ |
| 379 | void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked) | 379 | void tcp_cong_avoid_ai(struct tcp_sock *tp, u32 w, u32 acked) |
| 380 | { | 380 | { |
| 381 | /* If credits accumulated at a higher w, apply them gently now. */ | ||
| 382 | if (tp->snd_cwnd_cnt >= w) { | ||
| 383 | tp->snd_cwnd_cnt = 0; | ||
| 384 | tp->snd_cwnd++; | ||
| 385 | } | ||
| 386 | |||
| 381 | tp->snd_cwnd_cnt += acked; | 387 | tp->snd_cwnd_cnt += acked; |
| 382 | if (tp->snd_cwnd_cnt >= w) { | 388 | if (tp->snd_cwnd_cnt >= w) { |
| 383 | u32 delta = tp->snd_cwnd_cnt / w; | 389 | u32 delta = tp->snd_cwnd_cnt / w; |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 4b276d1ed980..06d3d665a9fd 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
| @@ -306,8 +306,10 @@ tcp_friendliness: | |||
| 306 | } | 306 | } |
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | if (ca->cnt == 0) /* cannot be zero */ | 309 | /* The maximum rate of cwnd increase CUBIC allows is 1 packet per |
| 310 | ca->cnt = 1; | 310 | * 2 packets ACKed, meaning cwnd grows at 1.5x per RTT. |
| 311 | */ | ||
| 312 | ca->cnt = max(ca->cnt, 2U); | ||
| 311 | } | 313 | } |
| 312 | 314 | ||
| 313 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked) | 315 | static void bictcp_cong_avoid(struct sock *sk, u32 ack, u32 acked) |
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index d5f6bd9a210a..dab73813cb92 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c | |||
| @@ -63,6 +63,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 63 | return err; | 63 | return err; |
| 64 | 64 | ||
| 65 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; | 65 | IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE; |
| 66 | skb->protocol = htons(ETH_P_IP); | ||
| 66 | 67 | ||
| 67 | return x->outer_mode->output2(x, skb); | 68 | return x->outer_mode->output2(x, skb); |
| 68 | } | 69 | } |
| @@ -71,7 +72,6 @@ EXPORT_SYMBOL(xfrm4_prepare_output); | |||
| 71 | int xfrm4_output_finish(struct sk_buff *skb) | 72 | int xfrm4_output_finish(struct sk_buff *skb) |
| 72 | { | 73 | { |
| 73 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | 74 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
| 74 | skb->protocol = htons(ETH_P_IP); | ||
| 75 | 75 | ||
| 76 | #ifdef CONFIG_NETFILTER | 76 | #ifdef CONFIG_NETFILTER |
| 77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; | 77 | IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; |
diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index c215be70cac0..ace8daca5c83 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c | |||
| @@ -325,14 +325,34 @@ void ipv6_local_rxpmtu(struct sock *sk, struct flowi6 *fl6, u32 mtu) | |||
| 325 | kfree_skb(skb); | 325 | kfree_skb(skb); |
| 326 | } | 326 | } |
| 327 | 327 | ||
| 328 | static void ip6_datagram_prepare_pktinfo_errqueue(struct sk_buff *skb) | 328 | /* IPv6 supports cmsg on all origins aside from SO_EE_ORIGIN_LOCAL. |
| 329 | * | ||
| 330 | * At one point, excluding local errors was a quick test to identify icmp/icmp6 | ||
| 331 | * errors. This is no longer true, but the test remained, so the v6 stack, | ||
| 332 | * unlike v4, also honors cmsg requests on all wifi and timestamp errors. | ||
| 333 | * | ||
| 334 | * Timestamp code paths do not initialize the fields expected by cmsg: | ||
| 335 | * the PKTINFO fields in skb->cb[]. Fill those in here. | ||
| 336 | */ | ||
| 337 | static bool ip6_datagram_support_cmsg(struct sk_buff *skb, | ||
| 338 | struct sock_exterr_skb *serr) | ||
| 329 | { | 339 | { |
| 330 | int ifindex = skb->dev ? skb->dev->ifindex : -1; | 340 | if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP || |
| 341 | serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) | ||
| 342 | return true; | ||
| 343 | |||
| 344 | if (serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL) | ||
| 345 | return false; | ||
| 346 | |||
| 347 | if (!skb->dev) | ||
| 348 | return false; | ||
| 331 | 349 | ||
| 332 | if (skb->protocol == htons(ETH_P_IPV6)) | 350 | if (skb->protocol == htons(ETH_P_IPV6)) |
| 333 | IP6CB(skb)->iif = ifindex; | 351 | IP6CB(skb)->iif = skb->dev->ifindex; |
| 334 | else | 352 | else |
| 335 | PKTINFO_SKB_CB(skb)->ipi_ifindex = ifindex; | 353 | PKTINFO_SKB_CB(skb)->ipi_ifindex = skb->dev->ifindex; |
| 354 | |||
| 355 | return true; | ||
| 336 | } | 356 | } |
| 337 | 357 | ||
| 338 | /* | 358 | /* |
| @@ -369,7 +389,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 369 | 389 | ||
| 370 | serr = SKB_EXT_ERR(skb); | 390 | serr = SKB_EXT_ERR(skb); |
| 371 | 391 | ||
| 372 | if (sin && skb->len) { | 392 | if (sin && serr->port) { |
| 373 | const unsigned char *nh = skb_network_header(skb); | 393 | const unsigned char *nh = skb_network_header(skb); |
| 374 | sin->sin6_family = AF_INET6; | 394 | sin->sin6_family = AF_INET6; |
| 375 | sin->sin6_flowinfo = 0; | 395 | sin->sin6_flowinfo = 0; |
| @@ -394,14 +414,11 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len) | |||
| 394 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); | 414 | memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err)); |
| 395 | sin = &errhdr.offender; | 415 | sin = &errhdr.offender; |
| 396 | memset(sin, 0, sizeof(*sin)); | 416 | memset(sin, 0, sizeof(*sin)); |
| 397 | if (serr->ee.ee_origin != SO_EE_ORIGIN_LOCAL && skb->len) { | 417 | |
| 418 | if (ip6_datagram_support_cmsg(skb, serr)) { | ||
| 398 | sin->sin6_family = AF_INET6; | 419 | sin->sin6_family = AF_INET6; |
| 399 | if (np->rxopt.all) { | 420 | if (np->rxopt.all) |
| 400 | if (serr->ee.ee_origin != SO_EE_ORIGIN_ICMP && | ||
| 401 | serr->ee.ee_origin != SO_EE_ORIGIN_ICMP6) | ||
| 402 | ip6_datagram_prepare_pktinfo_errqueue(skb); | ||
| 403 | ip6_datagram_recv_common_ctl(sk, msg, skb); | 421 | ip6_datagram_recv_common_ctl(sk, msg, skb); |
| 404 | } | ||
| 405 | if (skb->protocol == htons(ETH_P_IPV6)) { | 422 | if (skb->protocol == htons(ETH_P_IPV6)) { |
| 406 | sin->sin6_addr = ipv6_hdr(skb)->saddr; | 423 | sin->sin6_addr = ipv6_hdr(skb)->saddr; |
| 407 | if (np->rxopt.all) | 424 | if (np->rxopt.all) |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 0a04a37305d5..7e80b61b51ff 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
| @@ -318,6 +318,7 @@ static int ip6_forward_proxy_check(struct sk_buff *skb) | |||
| 318 | 318 | ||
| 319 | static inline int ip6_forward_finish(struct sk_buff *skb) | 319 | static inline int ip6_forward_finish(struct sk_buff *skb) |
| 320 | { | 320 | { |
| 321 | skb_sender_cpu_clear(skb); | ||
| 321 | return dst_output(skb); | 322 | return dst_output(skb); |
| 322 | } | 323 | } |
| 323 | 324 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index 266a264ec212..ddd94eca19b3 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
| @@ -314,7 +314,7 @@ out: | |||
| 314 | * Create tunnel matching given parameters. | 314 | * Create tunnel matching given parameters. |
| 315 | * | 315 | * |
| 316 | * Return: | 316 | * Return: |
| 317 | * created tunnel or NULL | 317 | * created tunnel or error pointer |
| 318 | **/ | 318 | **/ |
| 319 | 319 | ||
| 320 | static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | 320 | static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) |
| @@ -322,7 +322,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | |||
| 322 | struct net_device *dev; | 322 | struct net_device *dev; |
| 323 | struct ip6_tnl *t; | 323 | struct ip6_tnl *t; |
| 324 | char name[IFNAMSIZ]; | 324 | char name[IFNAMSIZ]; |
| 325 | int err; | 325 | int err = -ENOMEM; |
| 326 | 326 | ||
| 327 | if (p->name[0]) | 327 | if (p->name[0]) |
| 328 | strlcpy(name, p->name, IFNAMSIZ); | 328 | strlcpy(name, p->name, IFNAMSIZ); |
| @@ -348,7 +348,7 @@ static struct ip6_tnl *ip6_tnl_create(struct net *net, struct __ip6_tnl_parm *p) | |||
| 348 | failed_free: | 348 | failed_free: |
| 349 | ip6_dev_free(dev); | 349 | ip6_dev_free(dev); |
| 350 | failed: | 350 | failed: |
| 351 | return NULL; | 351 | return ERR_PTR(err); |
| 352 | } | 352 | } |
| 353 | 353 | ||
| 354 | /** | 354 | /** |
| @@ -362,7 +362,7 @@ failed: | |||
| 362 | * tunnel device is created and registered for use. | 362 | * tunnel device is created and registered for use. |
| 363 | * | 363 | * |
| 364 | * Return: | 364 | * Return: |
| 365 | * matching tunnel or NULL | 365 | * matching tunnel or error pointer |
| 366 | **/ | 366 | **/ |
| 367 | 367 | ||
| 368 | static struct ip6_tnl *ip6_tnl_locate(struct net *net, | 368 | static struct ip6_tnl *ip6_tnl_locate(struct net *net, |
| @@ -380,13 +380,13 @@ static struct ip6_tnl *ip6_tnl_locate(struct net *net, | |||
| 380 | if (ipv6_addr_equal(local, &t->parms.laddr) && | 380 | if (ipv6_addr_equal(local, &t->parms.laddr) && |
| 381 | ipv6_addr_equal(remote, &t->parms.raddr)) { | 381 | ipv6_addr_equal(remote, &t->parms.raddr)) { |
| 382 | if (create) | 382 | if (create) |
| 383 | return NULL; | 383 | return ERR_PTR(-EEXIST); |
| 384 | 384 | ||
| 385 | return t; | 385 | return t; |
| 386 | } | 386 | } |
| 387 | } | 387 | } |
| 388 | if (!create) | 388 | if (!create) |
| 389 | return NULL; | 389 | return ERR_PTR(-ENODEV); |
| 390 | return ip6_tnl_create(net, p); | 390 | return ip6_tnl_create(net, p); |
| 391 | } | 391 | } |
| 392 | 392 | ||
| @@ -1420,7 +1420,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1420 | } | 1420 | } |
| 1421 | ip6_tnl_parm_from_user(&p1, &p); | 1421 | ip6_tnl_parm_from_user(&p1, &p); |
| 1422 | t = ip6_tnl_locate(net, &p1, 0); | 1422 | t = ip6_tnl_locate(net, &p1, 0); |
| 1423 | if (t == NULL) | 1423 | if (IS_ERR(t)) |
| 1424 | t = netdev_priv(dev); | 1424 | t = netdev_priv(dev); |
| 1425 | } else { | 1425 | } else { |
| 1426 | memset(&p, 0, sizeof(p)); | 1426 | memset(&p, 0, sizeof(p)); |
| @@ -1445,7 +1445,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1445 | ip6_tnl_parm_from_user(&p1, &p); | 1445 | ip6_tnl_parm_from_user(&p1, &p); |
| 1446 | t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL); | 1446 | t = ip6_tnl_locate(net, &p1, cmd == SIOCADDTUNNEL); |
| 1447 | if (cmd == SIOCCHGTUNNEL) { | 1447 | if (cmd == SIOCCHGTUNNEL) { |
| 1448 | if (t != NULL) { | 1448 | if (!IS_ERR(t)) { |
| 1449 | if (t->dev != dev) { | 1449 | if (t->dev != dev) { |
| 1450 | err = -EEXIST; | 1450 | err = -EEXIST; |
| 1451 | break; | 1451 | break; |
| @@ -1457,14 +1457,15 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1457 | else | 1457 | else |
| 1458 | err = ip6_tnl_update(t, &p1); | 1458 | err = ip6_tnl_update(t, &p1); |
| 1459 | } | 1459 | } |
| 1460 | if (t) { | 1460 | if (!IS_ERR(t)) { |
| 1461 | err = 0; | 1461 | err = 0; |
| 1462 | ip6_tnl_parm_to_user(&p, &t->parms); | 1462 | ip6_tnl_parm_to_user(&p, &t->parms); |
| 1463 | if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) | 1463 | if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p))) |
| 1464 | err = -EFAULT; | 1464 | err = -EFAULT; |
| 1465 | 1465 | ||
| 1466 | } else | 1466 | } else { |
| 1467 | err = (cmd == SIOCADDTUNNEL ? -ENOBUFS : -ENOENT); | 1467 | err = PTR_ERR(t); |
| 1468 | } | ||
| 1468 | break; | 1469 | break; |
| 1469 | case SIOCDELTUNNEL: | 1470 | case SIOCDELTUNNEL: |
| 1470 | err = -EPERM; | 1471 | err = -EPERM; |
| @@ -1478,7 +1479,7 @@ ip6_tnl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | |||
| 1478 | err = -ENOENT; | 1479 | err = -ENOENT; |
| 1479 | ip6_tnl_parm_from_user(&p1, &p); | 1480 | ip6_tnl_parm_from_user(&p1, &p); |
| 1480 | t = ip6_tnl_locate(net, &p1, 0); | 1481 | t = ip6_tnl_locate(net, &p1, 0); |
| 1481 | if (t == NULL) | 1482 | if (IS_ERR(t)) |
| 1482 | break; | 1483 | break; |
| 1483 | err = -EPERM; | 1484 | err = -EPERM; |
| 1484 | if (t->dev == ip6n->fb_tnl_dev) | 1485 | if (t->dev == ip6n->fb_tnl_dev) |
| @@ -1672,12 +1673,13 @@ static int ip6_tnl_newlink(struct net *src_net, struct net_device *dev, | |||
| 1672 | struct nlattr *tb[], struct nlattr *data[]) | 1673 | struct nlattr *tb[], struct nlattr *data[]) |
| 1673 | { | 1674 | { |
| 1674 | struct net *net = dev_net(dev); | 1675 | struct net *net = dev_net(dev); |
| 1675 | struct ip6_tnl *nt; | 1676 | struct ip6_tnl *nt, *t; |
| 1676 | 1677 | ||
| 1677 | nt = netdev_priv(dev); | 1678 | nt = netdev_priv(dev); |
| 1678 | ip6_tnl_netlink_parms(data, &nt->parms); | 1679 | ip6_tnl_netlink_parms(data, &nt->parms); |
| 1679 | 1680 | ||
| 1680 | if (ip6_tnl_locate(net, &nt->parms, 0)) | 1681 | t = ip6_tnl_locate(net, &nt->parms, 0); |
| 1682 | if (!IS_ERR(t)) | ||
| 1681 | return -EEXIST; | 1683 | return -EEXIST; |
| 1682 | 1684 | ||
| 1683 | return ip6_tnl_create2(dev); | 1685 | return ip6_tnl_create2(dev); |
| @@ -1697,8 +1699,7 @@ static int ip6_tnl_changelink(struct net_device *dev, struct nlattr *tb[], | |||
| 1697 | ip6_tnl_netlink_parms(data, &p); | 1699 | ip6_tnl_netlink_parms(data, &p); |
| 1698 | 1700 | ||
| 1699 | t = ip6_tnl_locate(net, &p, 0); | 1701 | t = ip6_tnl_locate(net, &p, 0); |
| 1700 | 1702 | if (!IS_ERR(t)) { | |
| 1701 | if (t) { | ||
| 1702 | if (t->dev != dev) | 1703 | if (t->dev != dev) |
| 1703 | return -EEXIST; | 1704 | return -EEXIST; |
| 1704 | } else | 1705 | } else |
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c index bd46f736f61d..a2dfff6ff227 100644 --- a/net/ipv6/ping.c +++ b/net/ipv6/ping.c | |||
| @@ -102,9 +102,10 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg, | |||
| 102 | 102 | ||
| 103 | if (msg->msg_name) { | 103 | if (msg->msg_name) { |
| 104 | DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name); | 104 | DECLARE_SOCKADDR(struct sockaddr_in6 *, u, msg->msg_name); |
| 105 | if (msg->msg_namelen < sizeof(struct sockaddr_in6) || | 105 | if (msg->msg_namelen < sizeof(*u)) |
| 106 | u->sin6_family != AF_INET6) { | ||
| 107 | return -EINVAL; | 106 | return -EINVAL; |
| 107 | if (u->sin6_family != AF_INET6) { | ||
| 108 | return -EAFNOSUPPORT; | ||
| 108 | } | 109 | } |
| 109 | if (sk->sk_bound_dev_if && | 110 | if (sk->sk_bound_dev_if && |
| 110 | sk->sk_bound_dev_if != u->sin6_scope_id) { | 111 | sk->sk_bound_dev_if != u->sin6_scope_id) { |
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index ca3f29b98ae5..010f8bd2d577 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
| @@ -114,6 +114,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb) | |||
| 114 | return err; | 114 | return err; |
| 115 | 115 | ||
| 116 | skb->ignore_df = 1; | 116 | skb->ignore_df = 1; |
| 117 | skb->protocol = htons(ETH_P_IPV6); | ||
| 117 | 118 | ||
| 118 | return x->outer_mode->output2(x, skb); | 119 | return x->outer_mode->output2(x, skb); |
| 119 | } | 120 | } |
| @@ -122,7 +123,6 @@ EXPORT_SYMBOL(xfrm6_prepare_output); | |||
| 122 | int xfrm6_output_finish(struct sk_buff *skb) | 123 | int xfrm6_output_finish(struct sk_buff *skb) |
| 123 | { | 124 | { |
| 124 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); | 125 | memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); |
| 125 | skb->protocol = htons(ETH_P_IPV6); | ||
| 126 | 126 | ||
| 127 | #ifdef CONFIG_NETFILTER | 127 | #ifdef CONFIG_NETFILTER |
| 128 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; | 128 | IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 48bf5a06847b..8d2d01b4800a 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
| @@ -200,6 +200,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 200 | 200 | ||
| 201 | #if IS_ENABLED(CONFIG_IPV6_MIP6) | 201 | #if IS_ENABLED(CONFIG_IPV6_MIP6) |
| 202 | case IPPROTO_MH: | 202 | case IPPROTO_MH: |
| 203 | offset += ipv6_optlen(exthdr); | ||
| 203 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { | 204 | if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) { |
| 204 | struct ip6_mh *mh; | 205 | struct ip6_mh *mh; |
| 205 | 206 | ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h index 3afe36824703..8d53d65bd2ab 100644 --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h | |||
| @@ -58,13 +58,24 @@ struct ieee80211_local; | |||
| 58 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN | 58 | #define IEEE80211_UNSET_POWER_LEVEL INT_MIN |
| 59 | 59 | ||
| 60 | /* | 60 | /* |
| 61 | * Some APs experience problems when working with U-APSD. Decrease the | 61 | * Some APs experience problems when working with U-APSD. Decreasing the |
| 62 | * probability of that happening by using legacy mode for all ACs but VO. | 62 | * probability of that happening by using legacy mode for all ACs but VO isn't |
| 63 | * The AP that caused us trouble was a Cisco 4410N. It ignores our | 63 | * enough. |
| 64 | * setting, and always treats non-VO ACs as legacy. | 64 | * |
| 65 | * Cisco 4410N originally forced us to enable VO by default only because it | ||
| 66 | * treated non-VO ACs as legacy. | ||
| 67 | * | ||
| 68 | * However some APs (notably Netgear R7000) silently reclassify packets to | ||
| 69 | * different ACs. Since u-APSD ACs require trigger frames for frame retrieval | ||
| 70 | * clients would never see some frames (e.g. ARP responses) or would fetch them | ||
| 71 | * accidentally after a long time. | ||
| 72 | * | ||
| 73 | * It makes little sense to enable u-APSD queues by default because it needs | ||
| 74 | * userspace applications to be aware of it to actually take advantage of the | ||
| 75 | * possible additional powersavings. Implicitly depending on driver autotrigger | ||
| 76 | * frame support doesn't make much sense. | ||
| 65 | */ | 77 | */ |
| 66 | #define IEEE80211_DEFAULT_UAPSD_QUEUES \ | 78 | #define IEEE80211_DEFAULT_UAPSD_QUEUES 0 |
| 67 | IEEE80211_WMM_IE_STA_QOSINFO_AC_VO | ||
| 68 | 79 | ||
| 69 | #define IEEE80211_DEFAULT_MAX_SP_LEN \ | 80 | #define IEEE80211_DEFAULT_MAX_SP_LEN \ |
| 70 | IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL | 81 | IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL |
| @@ -453,6 +464,7 @@ struct ieee80211_if_managed { | |||
| 453 | unsigned int flags; | 464 | unsigned int flags; |
| 454 | 465 | ||
| 455 | bool csa_waiting_bcn; | 466 | bool csa_waiting_bcn; |
| 467 | bool csa_ignored_same_chan; | ||
| 456 | 468 | ||
| 457 | bool beacon_crc_valid; | 469 | bool beacon_crc_valid; |
| 458 | u32 beacon_crc; | 470 | u32 beacon_crc; |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 10ac6324c1d0..142f66aece18 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
| @@ -1150,6 +1150,17 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
| 1150 | return; | 1150 | return; |
| 1151 | } | 1151 | } |
| 1152 | 1152 | ||
| 1153 | if (cfg80211_chandef_identical(&csa_ie.chandef, | ||
| 1154 | &sdata->vif.bss_conf.chandef)) { | ||
| 1155 | if (ifmgd->csa_ignored_same_chan) | ||
| 1156 | return; | ||
| 1157 | sdata_info(sdata, | ||
| 1158 | "AP %pM tries to chanswitch to same channel, ignore\n", | ||
| 1159 | ifmgd->associated->bssid); | ||
| 1160 | ifmgd->csa_ignored_same_chan = true; | ||
| 1161 | return; | ||
| 1162 | } | ||
| 1163 | |||
| 1153 | mutex_lock(&local->mtx); | 1164 | mutex_lock(&local->mtx); |
| 1154 | mutex_lock(&local->chanctx_mtx); | 1165 | mutex_lock(&local->chanctx_mtx); |
| 1155 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, | 1166 | conf = rcu_dereference_protected(sdata->vif.chanctx_conf, |
| @@ -1210,6 +1221,7 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | |||
| 1210 | sdata->vif.csa_active = true; | 1221 | sdata->vif.csa_active = true; |
| 1211 | sdata->csa_chandef = csa_ie.chandef; | 1222 | sdata->csa_chandef = csa_ie.chandef; |
| 1212 | sdata->csa_block_tx = csa_ie.mode; | 1223 | sdata->csa_block_tx = csa_ie.mode; |
| 1224 | ifmgd->csa_ignored_same_chan = false; | ||
| 1213 | 1225 | ||
| 1214 | if (sdata->csa_block_tx) | 1226 | if (sdata->csa_block_tx) |
| 1215 | ieee80211_stop_vif_queues(local, sdata, | 1227 | ieee80211_stop_vif_queues(local, sdata, |
| @@ -2090,6 +2102,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, | |||
| 2090 | 2102 | ||
| 2091 | sdata->vif.csa_active = false; | 2103 | sdata->vif.csa_active = false; |
| 2092 | ifmgd->csa_waiting_bcn = false; | 2104 | ifmgd->csa_waiting_bcn = false; |
| 2105 | ifmgd->csa_ignored_same_chan = false; | ||
| 2093 | if (sdata->csa_block_tx) { | 2106 | if (sdata->csa_block_tx) { |
| 2094 | ieee80211_wake_vif_queues(local, sdata, | 2107 | ieee80211_wake_vif_queues(local, sdata, |
| 2095 | IEEE80211_QUEUE_STOP_REASON_CSA); | 2108 | IEEE80211_QUEUE_STOP_REASON_CSA); |
| @@ -3204,7 +3217,8 @@ static const u64 care_about_ies = | |||
| 3204 | (1ULL << WLAN_EID_CHANNEL_SWITCH) | | 3217 | (1ULL << WLAN_EID_CHANNEL_SWITCH) | |
| 3205 | (1ULL << WLAN_EID_PWR_CONSTRAINT) | | 3218 | (1ULL << WLAN_EID_PWR_CONSTRAINT) | |
| 3206 | (1ULL << WLAN_EID_HT_CAPABILITY) | | 3219 | (1ULL << WLAN_EID_HT_CAPABILITY) | |
| 3207 | (1ULL << WLAN_EID_HT_OPERATION); | 3220 | (1ULL << WLAN_EID_HT_OPERATION) | |
| 3221 | (1ULL << WLAN_EID_EXT_CHANSWITCH_ANN); | ||
| 3208 | 3222 | ||
| 3209 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, | 3223 | static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata, |
| 3210 | struct ieee80211_mgmt *mgmt, size_t len, | 3224 | struct ieee80211_mgmt *mgmt, size_t len, |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1101563357ea..944bdc04e913 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
| @@ -2214,6 +2214,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
| 2214 | hdr = (struct ieee80211_hdr *) skb->data; | 2214 | hdr = (struct ieee80211_hdr *) skb->data; |
| 2215 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 2215 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
| 2216 | 2216 | ||
| 2217 | if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) | ||
| 2218 | return RX_DROP_MONITOR; | ||
| 2219 | |||
| 2217 | /* frame is in RMC, don't forward */ | 2220 | /* frame is in RMC, don't forward */ |
| 2218 | if (ieee80211_is_data(hdr->frame_control) && | 2221 | if (ieee80211_is_data(hdr->frame_control) && |
| 2219 | is_multicast_ether_addr(hdr->addr1) && | 2222 | is_multicast_ether_addr(hdr->addr1) && |
diff --git a/net/mac80211/util.c b/net/mac80211/util.c index 8428f4a95479..747bdcf72e92 100644 --- a/net/mac80211/util.c +++ b/net/mac80211/util.c | |||
| @@ -3178,7 +3178,7 @@ int ieee80211_check_combinations(struct ieee80211_sub_if_data *sdata, | |||
| 3178 | wdev_iter = &sdata_iter->wdev; | 3178 | wdev_iter = &sdata_iter->wdev; |
| 3179 | 3179 | ||
| 3180 | if (sdata_iter == sdata || | 3180 | if (sdata_iter == sdata || |
| 3181 | rcu_access_pointer(sdata_iter->vif.chanctx_conf) == NULL || | 3181 | !ieee80211_sdata_running(sdata_iter) || |
| 3182 | local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) | 3182 | local->hw.wiphy->software_iftypes & BIT(wdev_iter->iftype)) |
| 3183 | continue; | 3183 | continue; |
| 3184 | 3184 | ||
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index c47ffd7a0a70..d93ceeb3ef04 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
| @@ -896,6 +896,8 @@ static void ip_vs_proc_conn(struct net *net, struct ip_vs_conn_param *param, | |||
| 896 | IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); | 896 | IP_VS_DBG(2, "BACKUP, add new conn. failed\n"); |
| 897 | return; | 897 | return; |
| 898 | } | 898 | } |
| 899 | if (!(flags & IP_VS_CONN_F_TEMPLATE)) | ||
| 900 | kfree(param->pe_data); | ||
| 899 | } | 901 | } |
| 900 | 902 | ||
| 901 | if (opt) | 903 | if (opt) |
| @@ -1169,6 +1171,7 @@ static inline int ip_vs_proc_sync_conn(struct net *net, __u8 *p, __u8 *msg_end) | |||
| 1169 | (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL) | 1171 | (opt_flags & IPVS_OPT_F_SEQ_DATA ? &opt : NULL) |
| 1170 | ); | 1172 | ); |
| 1171 | #endif | 1173 | #endif |
| 1174 | ip_vs_pe_put(param.pe); | ||
| 1172 | return 0; | 1175 | return 0; |
| 1173 | /* Error exit */ | 1176 | /* Error exit */ |
| 1174 | out: | 1177 | out: |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 199fd0f27b0e..6ab777912237 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
| @@ -227,7 +227,7 @@ nft_rule_deactivate_next(struct net *net, struct nft_rule *rule) | |||
| 227 | 227 | ||
| 228 | static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) | 228 | static inline void nft_rule_clear(struct net *net, struct nft_rule *rule) |
| 229 | { | 229 | { |
| 230 | rule->genmask = 0; | 230 | rule->genmask &= ~(1 << gencursor_next(net)); |
| 231 | } | 231 | } |
| 232 | 232 | ||
| 233 | static int | 233 | static int |
| @@ -1711,9 +1711,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, | |||
| 1711 | } | 1711 | } |
| 1712 | nla_nest_end(skb, list); | 1712 | nla_nest_end(skb, list); |
| 1713 | 1713 | ||
| 1714 | if (rule->ulen && | 1714 | if (rule->udata) { |
| 1715 | nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule))) | 1715 | struct nft_userdata *udata = nft_userdata(rule); |
| 1716 | goto nla_put_failure; | 1716 | if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1, |
| 1717 | udata->data) < 0) | ||
| 1718 | goto nla_put_failure; | ||
| 1719 | } | ||
| 1717 | 1720 | ||
| 1718 | nlmsg_end(skb, nlh); | 1721 | nlmsg_end(skb, nlh); |
| 1719 | return 0; | 1722 | return 0; |
| @@ -1896,11 +1899,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1896 | struct nft_table *table; | 1899 | struct nft_table *table; |
| 1897 | struct nft_chain *chain; | 1900 | struct nft_chain *chain; |
| 1898 | struct nft_rule *rule, *old_rule = NULL; | 1901 | struct nft_rule *rule, *old_rule = NULL; |
| 1902 | struct nft_userdata *udata; | ||
| 1899 | struct nft_trans *trans = NULL; | 1903 | struct nft_trans *trans = NULL; |
| 1900 | struct nft_expr *expr; | 1904 | struct nft_expr *expr; |
| 1901 | struct nft_ctx ctx; | 1905 | struct nft_ctx ctx; |
| 1902 | struct nlattr *tmp; | 1906 | struct nlattr *tmp; |
| 1903 | unsigned int size, i, n, ulen = 0; | 1907 | unsigned int size, i, n, ulen = 0, usize = 0; |
| 1904 | int err, rem; | 1908 | int err, rem; |
| 1905 | bool create; | 1909 | bool create; |
| 1906 | u64 handle, pos_handle; | 1910 | u64 handle, pos_handle; |
| @@ -1968,12 +1972,19 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1968 | n++; | 1972 | n++; |
| 1969 | } | 1973 | } |
| 1970 | } | 1974 | } |
| 1975 | /* Check for overflow of dlen field */ | ||
| 1976 | err = -EFBIG; | ||
| 1977 | if (size >= 1 << 12) | ||
| 1978 | goto err1; | ||
| 1971 | 1979 | ||
| 1972 | if (nla[NFTA_RULE_USERDATA]) | 1980 | if (nla[NFTA_RULE_USERDATA]) { |
| 1973 | ulen = nla_len(nla[NFTA_RULE_USERDATA]); | 1981 | ulen = nla_len(nla[NFTA_RULE_USERDATA]); |
| 1982 | if (ulen > 0) | ||
| 1983 | usize = sizeof(struct nft_userdata) + ulen; | ||
| 1984 | } | ||
| 1974 | 1985 | ||
| 1975 | err = -ENOMEM; | 1986 | err = -ENOMEM; |
| 1976 | rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL); | 1987 | rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL); |
| 1977 | if (rule == NULL) | 1988 | if (rule == NULL) |
| 1978 | goto err1; | 1989 | goto err1; |
| 1979 | 1990 | ||
| @@ -1981,10 +1992,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 1981 | 1992 | ||
| 1982 | rule->handle = handle; | 1993 | rule->handle = handle; |
| 1983 | rule->dlen = size; | 1994 | rule->dlen = size; |
| 1984 | rule->ulen = ulen; | 1995 | rule->udata = ulen ? 1 : 0; |
| 1985 | 1996 | ||
| 1986 | if (ulen) | 1997 | if (ulen) { |
| 1987 | nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen); | 1998 | udata = nft_userdata(rule); |
| 1999 | udata->len = ulen - 1; | ||
| 2000 | nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen); | ||
| 2001 | } | ||
| 1988 | 2002 | ||
| 1989 | expr = nft_expr_first(rule); | 2003 | expr = nft_expr_first(rule); |
| 1990 | for (i = 0; i < n; i++) { | 2004 | for (i = 0; i < n; i++) { |
| @@ -2031,12 +2045,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
| 2031 | 2045 | ||
| 2032 | err3: | 2046 | err3: |
| 2033 | list_del_rcu(&rule->list); | 2047 | list_del_rcu(&rule->list); |
| 2034 | if (trans) { | ||
| 2035 | list_del_rcu(&nft_trans_rule(trans)->list); | ||
| 2036 | nft_rule_clear(net, nft_trans_rule(trans)); | ||
| 2037 | nft_trans_destroy(trans); | ||
| 2038 | chain->use++; | ||
| 2039 | } | ||
| 2040 | err2: | 2048 | err2: |
| 2041 | nf_tables_rule_destroy(&ctx, rule); | 2049 | nf_tables_rule_destroy(&ctx, rule); |
| 2042 | err1: | 2050 | err1: |
| @@ -3612,12 +3620,11 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
| 3612 | &te->elem, | 3620 | &te->elem, |
| 3613 | NFT_MSG_DELSETELEM, 0); | 3621 | NFT_MSG_DELSETELEM, 0); |
| 3614 | te->set->ops->get(te->set, &te->elem); | 3622 | te->set->ops->get(te->set, &te->elem); |
| 3615 | te->set->ops->remove(te->set, &te->elem); | ||
| 3616 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); | 3623 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); |
| 3617 | if (te->elem.flags & NFT_SET_MAP) { | 3624 | if (te->set->flags & NFT_SET_MAP && |
| 3618 | nft_data_uninit(&te->elem.data, | 3625 | !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) |
| 3619 | te->set->dtype); | 3626 | nft_data_uninit(&te->elem.data, te->set->dtype); |
| 3620 | } | 3627 | te->set->ops->remove(te->set, &te->elem); |
| 3621 | nft_trans_destroy(trans); | 3628 | nft_trans_destroy(trans); |
| 3622 | break; | 3629 | break; |
| 3623 | } | 3630 | } |
| @@ -3658,7 +3665,7 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
| 3658 | { | 3665 | { |
| 3659 | struct net *net = sock_net(skb->sk); | 3666 | struct net *net = sock_net(skb->sk); |
| 3660 | struct nft_trans *trans, *next; | 3667 | struct nft_trans *trans, *next; |
| 3661 | struct nft_set *set; | 3668 | struct nft_trans_elem *te; |
| 3662 | 3669 | ||
| 3663 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { | 3670 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { |
| 3664 | switch (trans->msg_type) { | 3671 | switch (trans->msg_type) { |
| @@ -3719,9 +3726,13 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
| 3719 | break; | 3726 | break; |
| 3720 | case NFT_MSG_NEWSETELEM: | 3727 | case NFT_MSG_NEWSETELEM: |
| 3721 | nft_trans_elem_set(trans)->nelems--; | 3728 | nft_trans_elem_set(trans)->nelems--; |
| 3722 | set = nft_trans_elem_set(trans); | 3729 | te = (struct nft_trans_elem *)trans->data; |
| 3723 | set->ops->get(set, &nft_trans_elem(trans)); | 3730 | te->set->ops->get(te->set, &te->elem); |
| 3724 | set->ops->remove(set, &nft_trans_elem(trans)); | 3731 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); |
| 3732 | if (te->set->flags & NFT_SET_MAP && | ||
| 3733 | !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) | ||
| 3734 | nft_data_uninit(&te->elem.data, te->set->dtype); | ||
| 3735 | te->set->ops->remove(te->set, &te->elem); | ||
| 3725 | nft_trans_destroy(trans); | 3736 | nft_trans_destroy(trans); |
| 3726 | break; | 3737 | break; |
| 3727 | case NFT_MSG_DELSETELEM: | 3738 | case NFT_MSG_DELSETELEM: |
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index 1279cd85663e..213584cf04b3 100644 --- a/net/netfilter/nft_compat.c +++ b/net/netfilter/nft_compat.c | |||
| @@ -123,7 +123,7 @@ static void | |||
| 123 | nft_target_set_tgchk_param(struct xt_tgchk_param *par, | 123 | nft_target_set_tgchk_param(struct xt_tgchk_param *par, |
| 124 | const struct nft_ctx *ctx, | 124 | const struct nft_ctx *ctx, |
| 125 | struct xt_target *target, void *info, | 125 | struct xt_target *target, void *info, |
| 126 | union nft_entry *entry, u8 proto, bool inv) | 126 | union nft_entry *entry, u16 proto, bool inv) |
| 127 | { | 127 | { |
| 128 | par->net = ctx->net; | 128 | par->net = ctx->net; |
| 129 | par->table = ctx->table->name; | 129 | par->table = ctx->table->name; |
| @@ -137,7 +137,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, | |||
| 137 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; | 137 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
| 138 | break; | 138 | break; |
| 139 | case NFPROTO_BRIDGE: | 139 | case NFPROTO_BRIDGE: |
| 140 | entry->ebt.ethproto = proto; | 140 | entry->ebt.ethproto = (__force __be16)proto; |
| 141 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; | 141 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
| 142 | break; | 142 | break; |
| 143 | } | 143 | } |
| @@ -171,7 +171,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] | |||
| 171 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, | 171 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, |
| 172 | }; | 172 | }; |
| 173 | 173 | ||
| 174 | static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv) | 174 | static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) |
| 175 | { | 175 | { |
| 176 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; | 176 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; |
| 177 | u32 flags; | 177 | u32 flags; |
| @@ -203,7 +203,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 203 | struct xt_target *target = expr->ops->data; | 203 | struct xt_target *target = expr->ops->data; |
| 204 | struct xt_tgchk_param par; | 204 | struct xt_tgchk_param par; |
| 205 | size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); | 205 | size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); |
| 206 | u8 proto = 0; | 206 | u16 proto = 0; |
| 207 | bool inv = false; | 207 | bool inv = false; |
| 208 | union nft_entry e = {}; | 208 | union nft_entry e = {}; |
| 209 | int ret; | 209 | int ret; |
| @@ -334,7 +334,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { | |||
| 334 | static void | 334 | static void |
| 335 | nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, | 335 | nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, |
| 336 | struct xt_match *match, void *info, | 336 | struct xt_match *match, void *info, |
| 337 | union nft_entry *entry, u8 proto, bool inv) | 337 | union nft_entry *entry, u16 proto, bool inv) |
| 338 | { | 338 | { |
| 339 | par->net = ctx->net; | 339 | par->net = ctx->net; |
| 340 | par->table = ctx->table->name; | 340 | par->table = ctx->table->name; |
| @@ -348,7 +348,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, | |||
| 348 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; | 348 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
| 349 | break; | 349 | break; |
| 350 | case NFPROTO_BRIDGE: | 350 | case NFPROTO_BRIDGE: |
| 351 | entry->ebt.ethproto = proto; | 351 | entry->ebt.ethproto = (__force __be16)proto; |
| 352 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; | 352 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
| 353 | break; | 353 | break; |
| 354 | } | 354 | } |
| @@ -385,7 +385,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
| 385 | struct xt_match *match = expr->ops->data; | 385 | struct xt_match *match = expr->ops->data; |
| 386 | struct xt_mtchk_param par; | 386 | struct xt_mtchk_param par; |
| 387 | size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); | 387 | size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); |
| 388 | u8 proto = 0; | 388 | u16 proto = 0; |
| 389 | bool inv = false; | 389 | bool inv = false; |
| 390 | union nft_entry e = {}; | 390 | union nft_entry e = {}; |
| 391 | int ret; | 391 | int ret; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 5bf1e968a728..f8db7064d81c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -3123,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
| 3123 | return 0; | 3123 | return 0; |
| 3124 | } | 3124 | } |
| 3125 | 3125 | ||
| 3126 | static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) | 3126 | static void packet_dev_mclist_delete(struct net_device *dev, |
| 3127 | struct packet_mclist **mlp) | ||
| 3127 | { | 3128 | { |
| 3128 | for ( ; i; i = i->next) { | 3129 | struct packet_mclist *ml; |
| 3129 | if (i->ifindex == dev->ifindex) | 3130 | |
| 3130 | packet_dev_mc(dev, i, what); | 3131 | while ((ml = *mlp) != NULL) { |
| 3132 | if (ml->ifindex == dev->ifindex) { | ||
| 3133 | packet_dev_mc(dev, ml, -1); | ||
| 3134 | *mlp = ml->next; | ||
| 3135 | kfree(ml); | ||
| 3136 | } else | ||
| 3137 | mlp = &ml->next; | ||
| 3131 | } | 3138 | } |
| 3132 | } | 3139 | } |
| 3133 | 3140 | ||
| @@ -3204,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) | |||
| 3204 | packet_dev_mc(dev, ml, -1); | 3211 | packet_dev_mc(dev, ml, -1); |
| 3205 | kfree(ml); | 3212 | kfree(ml); |
| 3206 | } | 3213 | } |
| 3207 | rtnl_unlock(); | 3214 | break; |
| 3208 | return 0; | ||
| 3209 | } | 3215 | } |
| 3210 | } | 3216 | } |
| 3211 | rtnl_unlock(); | 3217 | rtnl_unlock(); |
| 3212 | return -EADDRNOTAVAIL; | 3218 | return 0; |
| 3213 | } | 3219 | } |
| 3214 | 3220 | ||
| 3215 | static void packet_flush_mclist(struct sock *sk) | 3221 | static void packet_flush_mclist(struct sock *sk) |
| @@ -3559,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this, | |||
| 3559 | switch (msg) { | 3565 | switch (msg) { |
| 3560 | case NETDEV_UNREGISTER: | 3566 | case NETDEV_UNREGISTER: |
| 3561 | if (po->mclist) | 3567 | if (po->mclist) |
| 3562 | packet_dev_mclist(dev, po->mclist, -1); | 3568 | packet_dev_mclist_delete(dev, &po->mclist); |
| 3563 | /* fallthrough */ | 3569 | /* fallthrough */ |
| 3564 | 3570 | ||
| 3565 | case NETDEV_DOWN: | 3571 | case NETDEV_DOWN: |
diff --git a/net/rds/iw_rdma.c b/net/rds/iw_rdma.c index a817705ce2d0..dba8d0864f18 100644 --- a/net/rds/iw_rdma.c +++ b/net/rds/iw_rdma.c | |||
| @@ -88,7 +88,9 @@ static unsigned int rds_iw_unmap_fastreg_list(struct rds_iw_mr_pool *pool, | |||
| 88 | int *unpinned); | 88 | int *unpinned); |
| 89 | static void rds_iw_destroy_fastreg(struct rds_iw_mr_pool *pool, struct rds_iw_mr *ibmr); | 89 | static void rds_iw_destroy_fastreg(struct rds_iw_mr_pool *pool, struct rds_iw_mr *ibmr); |
| 90 | 90 | ||
| 91 | static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwdev, struct rdma_cm_id **cm_id) | 91 | static int rds_iw_get_device(struct sockaddr_in *src, struct sockaddr_in *dst, |
| 92 | struct rds_iw_device **rds_iwdev, | ||
| 93 | struct rdma_cm_id **cm_id) | ||
| 92 | { | 94 | { |
| 93 | struct rds_iw_device *iwdev; | 95 | struct rds_iw_device *iwdev; |
| 94 | struct rds_iw_cm_id *i_cm_id; | 96 | struct rds_iw_cm_id *i_cm_id; |
| @@ -112,15 +114,15 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd | |||
| 112 | src_addr->sin_port, | 114 | src_addr->sin_port, |
| 113 | dst_addr->sin_addr.s_addr, | 115 | dst_addr->sin_addr.s_addr, |
| 114 | dst_addr->sin_port, | 116 | dst_addr->sin_port, |
| 115 | rs->rs_bound_addr, | 117 | src->sin_addr.s_addr, |
| 116 | rs->rs_bound_port, | 118 | src->sin_port, |
| 117 | rs->rs_conn_addr, | 119 | dst->sin_addr.s_addr, |
| 118 | rs->rs_conn_port); | 120 | dst->sin_port); |
| 119 | #ifdef WORKING_TUPLE_DETECTION | 121 | #ifdef WORKING_TUPLE_DETECTION |
| 120 | if (src_addr->sin_addr.s_addr == rs->rs_bound_addr && | 122 | if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr && |
| 121 | src_addr->sin_port == rs->rs_bound_port && | 123 | src_addr->sin_port == src->sin_port && |
| 122 | dst_addr->sin_addr.s_addr == rs->rs_conn_addr && | 124 | dst_addr->sin_addr.s_addr == dst->sin_addr.s_addr && |
| 123 | dst_addr->sin_port == rs->rs_conn_port) { | 125 | dst_addr->sin_port == dst->sin_port) { |
| 124 | #else | 126 | #else |
| 125 | /* FIXME - needs to compare the local and remote | 127 | /* FIXME - needs to compare the local and remote |
| 126 | * ipaddr/port tuple, but the ipaddr is the only | 128 | * ipaddr/port tuple, but the ipaddr is the only |
| @@ -128,7 +130,7 @@ static int rds_iw_get_device(struct rds_sock *rs, struct rds_iw_device **rds_iwd | |||
| 128 | * zero'ed. It doesn't appear to be properly populated | 130 | * zero'ed. It doesn't appear to be properly populated |
| 129 | * during connection setup... | 131 | * during connection setup... |
| 130 | */ | 132 | */ |
| 131 | if (src_addr->sin_addr.s_addr == rs->rs_bound_addr) { | 133 | if (src_addr->sin_addr.s_addr == src->sin_addr.s_addr) { |
| 132 | #endif | 134 | #endif |
| 133 | spin_unlock_irq(&iwdev->spinlock); | 135 | spin_unlock_irq(&iwdev->spinlock); |
| 134 | *rds_iwdev = iwdev; | 136 | *rds_iwdev = iwdev; |
| @@ -180,19 +182,13 @@ int rds_iw_update_cm_id(struct rds_iw_device *rds_iwdev, struct rdma_cm_id *cm_i | |||
| 180 | { | 182 | { |
| 181 | struct sockaddr_in *src_addr, *dst_addr; | 183 | struct sockaddr_in *src_addr, *dst_addr; |
| 182 | struct rds_iw_device *rds_iwdev_old; | 184 | struct rds_iw_device *rds_iwdev_old; |
| 183 | struct rds_sock rs; | ||
| 184 | struct rdma_cm_id *pcm_id; | 185 | struct rdma_cm_id *pcm_id; |
| 185 | int rc; | 186 | int rc; |
| 186 | 187 | ||
| 187 | src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr; | 188 | src_addr = (struct sockaddr_in *)&cm_id->route.addr.src_addr; |
| 188 | dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr; | 189 | dst_addr = (struct sockaddr_in *)&cm_id->route.addr.dst_addr; |
| 189 | 190 | ||
| 190 | rs.rs_bound_addr = src_addr->sin_addr.s_addr; | 191 | rc = rds_iw_get_device(src_addr, dst_addr, &rds_iwdev_old, &pcm_id); |
| 191 | rs.rs_bound_port = src_addr->sin_port; | ||
| 192 | rs.rs_conn_addr = dst_addr->sin_addr.s_addr; | ||
| 193 | rs.rs_conn_port = dst_addr->sin_port; | ||
| 194 | |||
| 195 | rc = rds_iw_get_device(&rs, &rds_iwdev_old, &pcm_id); | ||
| 196 | if (rc) | 192 | if (rc) |
| 197 | rds_iw_remove_cm_id(rds_iwdev, cm_id); | 193 | rds_iw_remove_cm_id(rds_iwdev, cm_id); |
| 198 | 194 | ||
| @@ -598,9 +594,17 @@ void *rds_iw_get_mr(struct scatterlist *sg, unsigned long nents, | |||
| 598 | struct rds_iw_device *rds_iwdev; | 594 | struct rds_iw_device *rds_iwdev; |
| 599 | struct rds_iw_mr *ibmr = NULL; | 595 | struct rds_iw_mr *ibmr = NULL; |
| 600 | struct rdma_cm_id *cm_id; | 596 | struct rdma_cm_id *cm_id; |
| 597 | struct sockaddr_in src = { | ||
| 598 | .sin_addr.s_addr = rs->rs_bound_addr, | ||
| 599 | .sin_port = rs->rs_bound_port, | ||
| 600 | }; | ||
| 601 | struct sockaddr_in dst = { | ||
| 602 | .sin_addr.s_addr = rs->rs_conn_addr, | ||
| 603 | .sin_port = rs->rs_conn_port, | ||
| 604 | }; | ||
| 601 | int ret; | 605 | int ret; |
| 602 | 606 | ||
| 603 | ret = rds_iw_get_device(rs, &rds_iwdev, &cm_id); | 607 | ret = rds_iw_get_device(&src, &dst, &rds_iwdev, &cm_id); |
| 604 | if (ret || !cm_id) { | 608 | if (ret || !cm_id) { |
| 605 | ret = -ENODEV; | 609 | ret = -ENODEV; |
| 606 | goto out; | 610 | goto out; |
diff --git a/net/rxrpc/ar-error.c b/net/rxrpc/ar-error.c index 5394b6be46ec..0610efa83d72 100644 --- a/net/rxrpc/ar-error.c +++ b/net/rxrpc/ar-error.c | |||
| @@ -42,7 +42,8 @@ void rxrpc_UDP_error_report(struct sock *sk) | |||
| 42 | _leave("UDP socket errqueue empty"); | 42 | _leave("UDP socket errqueue empty"); |
| 43 | return; | 43 | return; |
| 44 | } | 44 | } |
| 45 | if (!skb->len) { | 45 | serr = SKB_EXT_ERR(skb); |
| 46 | if (!skb->len && serr->ee.ee_origin == SO_EE_ORIGIN_TIMESTAMPING) { | ||
| 46 | _leave("UDP empty message"); | 47 | _leave("UDP empty message"); |
| 47 | kfree_skb(skb); | 48 | kfree_skb(skb); |
| 48 | return; | 49 | return; |
| @@ -50,7 +51,6 @@ void rxrpc_UDP_error_report(struct sock *sk) | |||
| 50 | 51 | ||
| 51 | rxrpc_new_skb(skb); | 52 | rxrpc_new_skb(skb); |
| 52 | 53 | ||
| 53 | serr = SKB_EXT_ERR(skb); | ||
| 54 | addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset); | 54 | addr = *(__be32 *)(skb_network_header(skb) + serr->addr_offset); |
| 55 | port = serr->port; | 55 | port = serr->port; |
| 56 | 56 | ||
diff --git a/net/rxrpc/ar-recvmsg.c b/net/rxrpc/ar-recvmsg.c index 4575485ad1b4..19a560626dc4 100644 --- a/net/rxrpc/ar-recvmsg.c +++ b/net/rxrpc/ar-recvmsg.c | |||
| @@ -87,7 +87,7 @@ int rxrpc_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
| 87 | if (!skb) { | 87 | if (!skb) { |
| 88 | /* nothing remains on the queue */ | 88 | /* nothing remains on the queue */ |
| 89 | if (copied && | 89 | if (copied && |
| 90 | (msg->msg_flags & MSG_PEEK || timeo == 0)) | 90 | (flags & MSG_PEEK || timeo == 0)) |
| 91 | goto out; | 91 | goto out; |
| 92 | 92 | ||
| 93 | /* wait for a message to turn up */ | 93 | /* wait for a message to turn up */ |
diff --git a/net/sched/act_bpf.c b/net/sched/act_bpf.c index 82c5d7fc1988..5f6288fa3f12 100644 --- a/net/sched/act_bpf.c +++ b/net/sched/act_bpf.c | |||
| @@ -25,21 +25,41 @@ static int tcf_bpf(struct sk_buff *skb, const struct tc_action *a, | |||
| 25 | struct tcf_result *res) | 25 | struct tcf_result *res) |
| 26 | { | 26 | { |
| 27 | struct tcf_bpf *b = a->priv; | 27 | struct tcf_bpf *b = a->priv; |
| 28 | int action; | 28 | int action, filter_res; |
| 29 | int filter_res; | ||
| 30 | 29 | ||
| 31 | spin_lock(&b->tcf_lock); | 30 | spin_lock(&b->tcf_lock); |
| 31 | |||
| 32 | b->tcf_tm.lastuse = jiffies; | 32 | b->tcf_tm.lastuse = jiffies; |
| 33 | bstats_update(&b->tcf_bstats, skb); | 33 | bstats_update(&b->tcf_bstats, skb); |
| 34 | action = b->tcf_action; | ||
| 35 | 34 | ||
| 36 | filter_res = BPF_PROG_RUN(b->filter, skb); | 35 | filter_res = BPF_PROG_RUN(b->filter, skb); |
| 37 | if (filter_res == 0) { | 36 | |
| 38 | /* Return code 0 from the BPF program | 37 | /* A BPF program may overwrite the default action opcode. |
| 39 | * is being interpreted as a drop here. | 38 | * Similarly as in cls_bpf, if filter_res == -1 we use the |
| 40 | */ | 39 | * default action specified from tc. |
| 41 | action = TC_ACT_SHOT; | 40 | * |
| 41 | * In case a different well-known TC_ACT opcode has been | ||
| 42 | * returned, it will overwrite the default one. | ||
| 43 | * | ||
| 44 | * For everything else that is unkown, TC_ACT_UNSPEC is | ||
| 45 | * returned. | ||
| 46 | */ | ||
| 47 | switch (filter_res) { | ||
| 48 | case TC_ACT_PIPE: | ||
| 49 | case TC_ACT_RECLASSIFY: | ||
| 50 | case TC_ACT_OK: | ||
| 51 | action = filter_res; | ||
| 52 | break; | ||
| 53 | case TC_ACT_SHOT: | ||
| 54 | action = filter_res; | ||
| 42 | b->tcf_qstats.drops++; | 55 | b->tcf_qstats.drops++; |
| 56 | break; | ||
| 57 | case TC_ACT_UNSPEC: | ||
| 58 | action = b->tcf_action; | ||
| 59 | break; | ||
| 60 | default: | ||
| 61 | action = TC_ACT_UNSPEC; | ||
| 62 | break; | ||
| 43 | } | 63 | } |
| 44 | 64 | ||
| 45 | spin_unlock(&b->tcf_lock); | 65 | spin_unlock(&b->tcf_lock); |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index 09487afbfd51..95fdf4e40051 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
| @@ -78,8 +78,11 @@ struct tc_u_hnode { | |||
| 78 | struct tc_u_common *tp_c; | 78 | struct tc_u_common *tp_c; |
| 79 | int refcnt; | 79 | int refcnt; |
| 80 | unsigned int divisor; | 80 | unsigned int divisor; |
| 81 | struct tc_u_knode __rcu *ht[1]; | ||
| 82 | struct rcu_head rcu; | 81 | struct rcu_head rcu; |
| 82 | /* The 'ht' field MUST be the last field in structure to allow for | ||
| 83 | * more entries allocated at end of structure. | ||
| 84 | */ | ||
| 85 | struct tc_u_knode __rcu *ht[1]; | ||
| 83 | }; | 86 | }; |
| 84 | 87 | ||
| 85 | struct tc_u_common { | 88 | struct tc_u_common { |
diff --git a/net/tipc/link.c b/net/tipc/link.c index a4cf364316de..14f09b3cb87c 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c | |||
| @@ -464,10 +464,11 @@ void tipc_link_reset(struct tipc_link *l_ptr) | |||
| 464 | /* Clean up all queues, except inputq: */ | 464 | /* Clean up all queues, except inputq: */ |
| 465 | __skb_queue_purge(&l_ptr->outqueue); | 465 | __skb_queue_purge(&l_ptr->outqueue); |
| 466 | __skb_queue_purge(&l_ptr->deferred_queue); | 466 | __skb_queue_purge(&l_ptr->deferred_queue); |
| 467 | skb_queue_splice_init(&l_ptr->wakeupq, &l_ptr->inputq); | 467 | if (!owner->inputq) |
| 468 | if (!skb_queue_empty(&l_ptr->inputq)) | 468 | owner->inputq = &l_ptr->inputq; |
| 469 | skb_queue_splice_init(&l_ptr->wakeupq, owner->inputq); | ||
| 470 | if (!skb_queue_empty(owner->inputq)) | ||
| 469 | owner->action_flags |= TIPC_MSG_EVT; | 471 | owner->action_flags |= TIPC_MSG_EVT; |
| 470 | owner->inputq = &l_ptr->inputq; | ||
| 471 | l_ptr->next_out = NULL; | 472 | l_ptr->next_out = NULL; |
| 472 | l_ptr->unacked_window = 0; | 473 | l_ptr->unacked_window = 0; |
| 473 | l_ptr->checkpoint = 1; | 474 | l_ptr->checkpoint = 1; |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index be2501538011..b6f84f6a2a09 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
| @@ -4400,6 +4400,16 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info) | |||
| 4400 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) | 4400 | if (parse_station_flags(info, dev->ieee80211_ptr->iftype, ¶ms)) |
| 4401 | return -EINVAL; | 4401 | return -EINVAL; |
| 4402 | 4402 | ||
| 4403 | /* HT/VHT requires QoS, but if we don't have that just ignore HT/VHT | ||
| 4404 | * as userspace might just pass through the capabilities from the IEs | ||
| 4405 | * directly, rather than enforcing this restriction and returning an | ||
| 4406 | * error in this case. | ||
| 4407 | */ | ||
| 4408 | if (!(params.sta_flags_set & BIT(NL80211_STA_FLAG_WME))) { | ||
| 4409 | params.ht_capa = NULL; | ||
| 4410 | params.vht_capa = NULL; | ||
| 4411 | } | ||
| 4412 | |||
| 4403 | /* When you run into this, adjust the code below for the new flag */ | 4413 | /* When you run into this, adjust the code below for the new flag */ |
| 4404 | BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); | 4414 | BUILD_BUG_ON(NL80211_STA_FLAG_MAX != 7); |
| 4405 | 4415 | ||
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index cee479bc655c..638af0655aaf 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -2269,11 +2269,9 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
| 2269 | * have the xfrm_state's. We need to wait for KM to | 2269 | * have the xfrm_state's. We need to wait for KM to |
| 2270 | * negotiate new SA's or bail out with error.*/ | 2270 | * negotiate new SA's or bail out with error.*/ |
| 2271 | if (net->xfrm.sysctl_larval_drop) { | 2271 | if (net->xfrm.sysctl_larval_drop) { |
| 2272 | dst_release(dst); | ||
| 2273 | xfrm_pols_put(pols, drop_pols); | ||
| 2274 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); | 2272 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); |
| 2275 | 2273 | err = -EREMOTE; | |
| 2276 | return ERR_PTR(-EREMOTE); | 2274 | goto error; |
| 2277 | } | 2275 | } |
| 2278 | 2276 | ||
| 2279 | err = -EAGAIN; | 2277 | err = -EAGAIN; |
| @@ -2324,7 +2322,8 @@ nopol: | |||
| 2324 | error: | 2322 | error: |
| 2325 | dst_release(dst); | 2323 | dst_release(dst); |
| 2326 | dropdst: | 2324 | dropdst: |
| 2327 | dst_release(dst_orig); | 2325 | if (!(flags & XFRM_LOOKUP_KEEP_DST_REF)) |
| 2326 | dst_release(dst_orig); | ||
| 2328 | xfrm_pols_put(pols, drop_pols); | 2327 | xfrm_pols_put(pols, drop_pols); |
| 2329 | return ERR_PTR(err); | 2328 | return ERR_PTR(err); |
| 2330 | } | 2329 | } |
| @@ -2338,7 +2337,8 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig, | |||
| 2338 | struct sock *sk, int flags) | 2337 | struct sock *sk, int flags) |
| 2339 | { | 2338 | { |
| 2340 | struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk, | 2339 | struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk, |
| 2341 | flags | XFRM_LOOKUP_QUEUE); | 2340 | flags | XFRM_LOOKUP_QUEUE | |
| 2341 | XFRM_LOOKUP_KEEP_DST_REF); | ||
| 2342 | 2342 | ||
| 2343 | if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) | 2343 | if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE) |
| 2344 | return make_blackhole(net, dst_orig->ops->family, dst_orig); | 2344 | return make_blackhole(net, dst_orig->ops->family, dst_orig); |
