diff options
Diffstat (limited to 'net')
108 files changed, 745 insertions, 361 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.c b/net/bridge/br.c index fb57ab6b24f9..02c24cf63c34 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c | |||
@@ -190,6 +190,8 @@ static int __init br_init(void) | |||
190 | { | 190 | { |
191 | int err; | 191 | int err; |
192 | 192 | ||
193 | BUILD_BUG_ON(sizeof(struct br_input_skb_cb) > FIELD_SIZEOF(struct sk_buff, cb)); | ||
194 | |||
193 | err = stp_proto_register(&br_stp_proto); | 195 | err = stp_proto_register(&br_stp_proto); |
194 | if (err < 0) { | 196 | if (err < 0) { |
195 | pr_err("bridge: can't register sap for STP\n"); | 197 | pr_err("bridge: can't register sap for STP\n"); |
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/caif/cffrml.c b/net/caif/cffrml.c index 8bc7caa28e64..434ba8557826 100644 --- a/net/caif/cffrml.c +++ b/net/caif/cffrml.c | |||
@@ -84,7 +84,7 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt) | |||
84 | u16 tmp; | 84 | u16 tmp; |
85 | u16 len; | 85 | u16 len; |
86 | u16 hdrchks; | 86 | u16 hdrchks; |
87 | u16 pktchks; | 87 | int pktchks; |
88 | struct cffrml *this; | 88 | struct cffrml *this; |
89 | this = container_obj(layr); | 89 | this = container_obj(layr); |
90 | 90 | ||
diff --git a/net/caif/cfpkt_skbuff.c b/net/caif/cfpkt_skbuff.c index 1be0b521ac49..f6c3b2137eea 100644 --- a/net/caif/cfpkt_skbuff.c +++ b/net/caif/cfpkt_skbuff.c | |||
@@ -255,9 +255,9 @@ inline u16 cfpkt_getlen(struct cfpkt *pkt) | |||
255 | return skb->len; | 255 | return skb->len; |
256 | } | 256 | } |
257 | 257 | ||
258 | inline u16 cfpkt_iterate(struct cfpkt *pkt, | 258 | int cfpkt_iterate(struct cfpkt *pkt, |
259 | u16 (*iter_func)(u16, void *, u16), | 259 | u16 (*iter_func)(u16, void *, u16), |
260 | u16 data) | 260 | u16 data) |
261 | { | 261 | { |
262 | /* | 262 | /* |
263 | * Don't care about the performance hit of linearizing, | 263 | * Don't care about the performance hit of linearizing, |
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/compat.c b/net/compat.c index 3236b4167a32..f7bd286a8280 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -49,6 +49,13 @@ ssize_t get_compat_msghdr(struct msghdr *kmsg, | |||
49 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || | 49 | __get_user(kmsg->msg_controllen, &umsg->msg_controllen) || |
50 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) | 50 | __get_user(kmsg->msg_flags, &umsg->msg_flags)) |
51 | return -EFAULT; | 51 | return -EFAULT; |
52 | |||
53 | if (!uaddr) | ||
54 | kmsg->msg_namelen = 0; | ||
55 | |||
56 | if (kmsg->msg_namelen < 0) | ||
57 | return -EINVAL; | ||
58 | |||
52 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) | 59 | if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
53 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); | 60 | kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
54 | kmsg->msg_control = compat_ptr(tmp3); | 61 | kmsg->msg_control = compat_ptr(tmp3); |
@@ -711,24 +718,18 @@ static unsigned char nas[21] = { | |||
711 | 718 | ||
712 | COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) | 719 | COMPAT_SYSCALL_DEFINE3(sendmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) |
713 | { | 720 | { |
714 | if (flags & MSG_CMSG_COMPAT) | ||
715 | return -EINVAL; | ||
716 | return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 721 | return __sys_sendmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
717 | } | 722 | } |
718 | 723 | ||
719 | COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, | 724 | COMPAT_SYSCALL_DEFINE4(sendmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, |
720 | unsigned int, vlen, unsigned int, flags) | 725 | unsigned int, vlen, unsigned int, flags) |
721 | { | 726 | { |
722 | if (flags & MSG_CMSG_COMPAT) | ||
723 | return -EINVAL; | ||
724 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, | 727 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
725 | flags | MSG_CMSG_COMPAT); | 728 | flags | MSG_CMSG_COMPAT); |
726 | } | 729 | } |
727 | 730 | ||
728 | COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) | 731 | COMPAT_SYSCALL_DEFINE3(recvmsg, int, fd, struct compat_msghdr __user *, msg, unsigned int, flags) |
729 | { | 732 | { |
730 | if (flags & MSG_CMSG_COMPAT) | ||
731 | return -EINVAL; | ||
732 | return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 733 | return __sys_recvmsg(fd, (struct user_msghdr __user *)msg, flags | MSG_CMSG_COMPAT); |
733 | } | 734 | } |
734 | 735 | ||
@@ -751,9 +752,6 @@ COMPAT_SYSCALL_DEFINE5(recvmmsg, int, fd, struct compat_mmsghdr __user *, mmsg, | |||
751 | int datagrams; | 752 | int datagrams; |
752 | struct timespec ktspec; | 753 | struct timespec ktspec; |
753 | 754 | ||
754 | if (flags & MSG_CMSG_COMPAT) | ||
755 | return -EINVAL; | ||
756 | |||
757 | if (timeout == NULL) | 755 | if (timeout == NULL) |
758 | return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, | 756 | return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
759 | flags | MSG_CMSG_COMPAT, NULL); | 757 | flags | MSG_CMSG_COMPAT, NULL); |
diff --git a/net/core/dev.c b/net/core/dev.c index 8f9710c62e20..45109b70664e 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -946,7 +946,7 @@ bool dev_valid_name(const char *name) | |||
946 | return false; | 946 | return false; |
947 | 947 | ||
948 | while (*name) { | 948 | while (*name) { |
949 | if (*name == '/' || isspace(*name)) | 949 | if (*name == '/' || *name == ':' || isspace(*name)) |
950 | return false; | 950 | return false; |
951 | name++; | 951 | name++; |
952 | } | 952 | } |
@@ -2848,7 +2848,9 @@ static void skb_update_prio(struct sk_buff *skb) | |||
2848 | #define skb_update_prio(skb) | 2848 | #define skb_update_prio(skb) |
2849 | #endif | 2849 | #endif |
2850 | 2850 | ||
2851 | static DEFINE_PER_CPU(int, xmit_recursion); | 2851 | DEFINE_PER_CPU(int, xmit_recursion); |
2852 | EXPORT_SYMBOL(xmit_recursion); | ||
2853 | |||
2852 | #define RECURSION_LIMIT 10 | 2854 | #define RECURSION_LIMIT 10 |
2853 | 2855 | ||
2854 | /** | 2856 | /** |
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 91f74f3eb204..aa378ecef186 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -98,6 +98,7 @@ static const char netdev_features_strings[NETDEV_FEATURE_COUNT][ETH_GSTRING_LEN] | |||
98 | [NETIF_F_RXALL_BIT] = "rx-all", | 98 | [NETIF_F_RXALL_BIT] = "rx-all", |
99 | [NETIF_F_HW_L2FW_DOFFLOAD_BIT] = "l2-fwd-offload", | 99 | [NETIF_F_HW_L2FW_DOFFLOAD_BIT] = "l2-fwd-offload", |
100 | [NETIF_F_BUSY_POLL_BIT] = "busy-poll", | 100 | [NETIF_F_BUSY_POLL_BIT] = "busy-poll", |
101 | [NETIF_F_HW_SWITCH_OFFLOAD_BIT] = "hw-switch-offload", | ||
101 | }; | 102 | }; |
102 | 103 | ||
103 | static const char | 104 | static const char |
diff --git a/net/core/fib_rules.c b/net/core/fib_rules.c index 44706e81b2e0..e4fdc9dfb2c7 100644 --- a/net/core/fib_rules.c +++ b/net/core/fib_rules.c | |||
@@ -175,9 +175,9 @@ void fib_rules_unregister(struct fib_rules_ops *ops) | |||
175 | 175 | ||
176 | spin_lock(&net->rules_mod_lock); | 176 | spin_lock(&net->rules_mod_lock); |
177 | list_del_rcu(&ops->list); | 177 | list_del_rcu(&ops->list); |
178 | fib_rules_cleanup_ops(ops); | ||
179 | spin_unlock(&net->rules_mod_lock); | 178 | spin_unlock(&net->rules_mod_lock); |
180 | 179 | ||
180 | fib_rules_cleanup_ops(ops); | ||
181 | call_rcu(&ops->rcu, fib_rules_put_rcu); | 181 | call_rcu(&ops->rcu, fib_rules_put_rcu); |
182 | } | 182 | } |
183 | EXPORT_SYMBOL_GPL(fib_rules_unregister); | 183 | EXPORT_SYMBOL_GPL(fib_rules_unregister); |
diff --git a/net/core/gen_stats.c b/net/core/gen_stats.c index 0c08062d1796..1e2f46a69d50 100644 --- a/net/core/gen_stats.c +++ b/net/core/gen_stats.c | |||
@@ -32,6 +32,9 @@ gnet_stats_copy(struct gnet_dump *d, int type, void *buf, int size) | |||
32 | return 0; | 32 | return 0; |
33 | 33 | ||
34 | nla_put_failure: | 34 | nla_put_failure: |
35 | kfree(d->xstats); | ||
36 | d->xstats = NULL; | ||
37 | d->xstats_len = 0; | ||
35 | spin_unlock_bh(d->lock); | 38 | spin_unlock_bh(d->lock); |
36 | return -1; | 39 | return -1; |
37 | } | 40 | } |
@@ -305,7 +308,9 @@ int | |||
305 | gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) | 308 | gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) |
306 | { | 309 | { |
307 | if (d->compat_xstats) { | 310 | if (d->compat_xstats) { |
308 | d->xstats = st; | 311 | d->xstats = kmemdup(st, len, GFP_ATOMIC); |
312 | if (!d->xstats) | ||
313 | goto err_out; | ||
309 | d->xstats_len = len; | 314 | d->xstats_len = len; |
310 | } | 315 | } |
311 | 316 | ||
@@ -313,6 +318,11 @@ gnet_stats_copy_app(struct gnet_dump *d, void *st, int len) | |||
313 | return gnet_stats_copy(d, TCA_STATS_APP, st, len); | 318 | return gnet_stats_copy(d, TCA_STATS_APP, st, len); |
314 | 319 | ||
315 | return 0; | 320 | return 0; |
321 | |||
322 | err_out: | ||
323 | d->xstats_len = 0; | ||
324 | spin_unlock_bh(d->lock); | ||
325 | return -1; | ||
316 | } | 326 | } |
317 | EXPORT_SYMBOL(gnet_stats_copy_app); | 327 | EXPORT_SYMBOL(gnet_stats_copy_app); |
318 | 328 | ||
@@ -345,6 +355,9 @@ gnet_stats_finish_copy(struct gnet_dump *d) | |||
345 | return -1; | 355 | return -1; |
346 | } | 356 | } |
347 | 357 | ||
358 | kfree(d->xstats); | ||
359 | d->xstats = NULL; | ||
360 | d->xstats_len = 0; | ||
348 | spin_unlock_bh(d->lock); | 361 | spin_unlock_bh(d->lock); |
349 | return 0; | 362 | return 0; |
350 | } | 363 | } |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index cb5290b8c428..70d3450588b2 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -198,8 +198,10 @@ static int __peernet2id(struct net *net, struct net *peer, bool alloc) | |||
198 | */ | 198 | */ |
199 | int peernet2id(struct net *net, struct net *peer) | 199 | int peernet2id(struct net *net, struct net *peer) |
200 | { | 200 | { |
201 | int id = __peernet2id(net, peer, true); | 201 | bool alloc = atomic_read(&peer->count) == 0 ? false : true; |
202 | int id; | ||
202 | 203 | ||
204 | id = __peernet2id(net, peer, alloc); | ||
203 | return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; | 205 | return id >= 0 ? id : NETNSA_NSID_NOT_ASSIGNED; |
204 | } | 206 | } |
205 | EXPORT_SYMBOL(peernet2id); | 207 | EXPORT_SYMBOL(peernet2id); |
diff --git a/net/core/pktgen.c b/net/core/pktgen.c index b4899f5b7388..508155b283dd 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c | |||
@@ -1134,6 +1134,9 @@ static ssize_t pktgen_if_write(struct file *file, | |||
1134 | return len; | 1134 | return len; |
1135 | 1135 | ||
1136 | i += len; | 1136 | i += len; |
1137 | if ((value > 1) && | ||
1138 | (!(pkt_dev->odev->priv_flags & IFF_TX_SKB_SHARING))) | ||
1139 | return -ENOTSUPP; | ||
1137 | pkt_dev->burst = value < 1 ? 1 : value; | 1140 | pkt_dev->burst = value < 1 ? 1 : value; |
1138 | sprintf(pg_result, "OK: burst=%d", pkt_dev->burst); | 1141 | sprintf(pg_result, "OK: burst=%d", pkt_dev->burst); |
1139 | return count; | 1142 | return count; |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index ab293a3066b3..7ebed55b5f7d 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1300,7 +1300,6 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1300 | s_h = cb->args[0]; | 1300 | s_h = cb->args[0]; |
1301 | s_idx = cb->args[1]; | 1301 | s_idx = cb->args[1]; |
1302 | 1302 | ||
1303 | rcu_read_lock(); | ||
1304 | cb->seq = net->dev_base_seq; | 1303 | cb->seq = net->dev_base_seq; |
1305 | 1304 | ||
1306 | /* A hack to preserve kernel<->userspace interface. | 1305 | /* A hack to preserve kernel<->userspace interface. |
@@ -1322,7 +1321,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1322 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { | 1321 | for (h = s_h; h < NETDEV_HASHENTRIES; h++, s_idx = 0) { |
1323 | idx = 0; | 1322 | idx = 0; |
1324 | head = &net->dev_index_head[h]; | 1323 | head = &net->dev_index_head[h]; |
1325 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | 1324 | hlist_for_each_entry(dev, head, index_hlist) { |
1326 | if (idx < s_idx) | 1325 | if (idx < s_idx) |
1327 | goto cont; | 1326 | goto cont; |
1328 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1327 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
@@ -1344,7 +1343,6 @@ cont: | |||
1344 | } | 1343 | } |
1345 | } | 1344 | } |
1346 | out: | 1345 | out: |
1347 | rcu_read_unlock(); | ||
1348 | cb->args[1] = idx; | 1346 | cb->args[1] = idx; |
1349 | cb->args[0] = h; | 1347 | cb->args[0] = h; |
1350 | 1348 | ||
@@ -1934,10 +1932,10 @@ static int rtnl_group_changelink(const struct sk_buff *skb, | |||
1934 | struct ifinfomsg *ifm, | 1932 | struct ifinfomsg *ifm, |
1935 | struct nlattr **tb) | 1933 | struct nlattr **tb) |
1936 | { | 1934 | { |
1937 | struct net_device *dev; | 1935 | struct net_device *dev, *aux; |
1938 | int err; | 1936 | int err; |
1939 | 1937 | ||
1940 | for_each_netdev(net, dev) { | 1938 | for_each_netdev_safe(net, dev, aux) { |
1941 | if (dev->group == group) { | 1939 | if (dev->group == group) { |
1942 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); | 1940 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); |
1943 | if (err < 0) | 1941 | if (err < 0) |
@@ -2012,8 +2010,8 @@ replay: | |||
2012 | } | 2010 | } |
2013 | 2011 | ||
2014 | if (1) { | 2012 | if (1) { |
2015 | struct nlattr *attr[ops ? ops->maxtype + 1 : 0]; | 2013 | struct nlattr *attr[ops ? ops->maxtype + 1 : 1]; |
2016 | struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 0]; | 2014 | struct nlattr *slave_attr[m_ops ? m_ops->slave_maxtype + 1 : 1]; |
2017 | struct nlattr **data = NULL; | 2015 | struct nlattr **data = NULL; |
2018 | struct nlattr **slave_data = NULL; | 2016 | struct nlattr **slave_data = NULL; |
2019 | struct net *dest_net, *link_net = NULL; | 2017 | struct net *dest_net, *link_net = NULL; |
@@ -2122,6 +2120,10 @@ replay: | |||
2122 | if (IS_ERR(dest_net)) | 2120 | if (IS_ERR(dest_net)) |
2123 | return PTR_ERR(dest_net); | 2121 | return PTR_ERR(dest_net); |
2124 | 2122 | ||
2123 | err = -EPERM; | ||
2124 | if (!netlink_ns_capable(skb, dest_net->user_ns, CAP_NET_ADMIN)) | ||
2125 | goto out; | ||
2126 | |||
2125 | if (tb[IFLA_LINK_NETNSID]) { | 2127 | if (tb[IFLA_LINK_NETNSID]) { |
2126 | int id = nla_get_s32(tb[IFLA_LINK_NETNSID]); | 2128 | int id = nla_get_s32(tb[IFLA_LINK_NETNSID]); |
2127 | 2129 | ||
@@ -2130,6 +2132,9 @@ replay: | |||
2130 | err = -EINVAL; | 2132 | err = -EINVAL; |
2131 | goto out; | 2133 | goto out; |
2132 | } | 2134 | } |
2135 | err = -EPERM; | ||
2136 | if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN)) | ||
2137 | goto out; | ||
2133 | } | 2138 | } |
2134 | 2139 | ||
2135 | dev = rtnl_create_link(link_net ? : dest_net, ifname, | 2140 | dev = rtnl_create_link(link_net ? : dest_net, ifname, |
@@ -2161,28 +2166,28 @@ replay: | |||
2161 | } | 2166 | } |
2162 | } | 2167 | } |
2163 | err = rtnl_configure_link(dev, ifm); | 2168 | err = rtnl_configure_link(dev, ifm); |
2164 | if (err < 0) { | 2169 | if (err < 0) |
2165 | if (ops->newlink) { | 2170 | goto out_unregister; |
2166 | LIST_HEAD(list_kill); | ||
2167 | |||
2168 | ops->dellink(dev, &list_kill); | ||
2169 | unregister_netdevice_many(&list_kill); | ||
2170 | } else { | ||
2171 | unregister_netdevice(dev); | ||
2172 | } | ||
2173 | goto out; | ||
2174 | } | ||
2175 | |||
2176 | if (link_net) { | 2171 | if (link_net) { |
2177 | err = dev_change_net_namespace(dev, dest_net, ifname); | 2172 | err = dev_change_net_namespace(dev, dest_net, ifname); |
2178 | if (err < 0) | 2173 | if (err < 0) |
2179 | unregister_netdevice(dev); | 2174 | goto out_unregister; |
2180 | } | 2175 | } |
2181 | out: | 2176 | out: |
2182 | if (link_net) | 2177 | if (link_net) |
2183 | put_net(link_net); | 2178 | put_net(link_net); |
2184 | put_net(dest_net); | 2179 | put_net(dest_net); |
2185 | 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; | ||
2186 | } | 2191 | } |
2187 | } | 2192 | } |
2188 | 2193 | ||
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 88c613eab142..8e4ac97c8477 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -3621,13 +3621,14 @@ struct sk_buff *sock_dequeue_err_skb(struct sock *sk) | |||
3621 | { | 3621 | { |
3622 | struct sk_buff_head *q = &sk->sk_error_queue; | 3622 | struct sk_buff_head *q = &sk->sk_error_queue; |
3623 | struct sk_buff *skb, *skb_next; | 3623 | struct sk_buff *skb, *skb_next; |
3624 | unsigned long flags; | ||
3624 | int err = 0; | 3625 | int err = 0; |
3625 | 3626 | ||
3626 | spin_lock_bh(&q->lock); | 3627 | spin_lock_irqsave(&q->lock, flags); |
3627 | skb = __skb_dequeue(q); | 3628 | skb = __skb_dequeue(q); |
3628 | if (skb && (skb_next = skb_peek(q))) | 3629 | if (skb && (skb_next = skb_peek(q))) |
3629 | err = SKB_EXT_ERR(skb_next)->ee.ee_errno; | 3630 | err = SKB_EXT_ERR(skb_next)->ee.ee_errno; |
3630 | spin_unlock_bh(&q->lock); | 3631 | spin_unlock_irqrestore(&q->lock, flags); |
3631 | 3632 | ||
3632 | sk->sk_err = err; | 3633 | sk->sk_err = err; |
3633 | if (err) | 3634 | if (err) |
@@ -3732,9 +3733,13 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, | |||
3732 | struct sock *sk, int tstype) | 3733 | struct sock *sk, int tstype) |
3733 | { | 3734 | { |
3734 | struct sk_buff *skb; | 3735 | struct sk_buff *skb; |
3735 | bool tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; | 3736 | bool tsonly; |
3737 | |||
3738 | if (!sk) | ||
3739 | return; | ||
3736 | 3740 | ||
3737 | if (!sk || !skb_may_tx_timestamp(sk, tsonly)) | 3741 | tsonly = sk->sk_tsflags & SOF_TIMESTAMPING_OPT_TSONLY; |
3742 | if (!skb_may_tx_timestamp(sk, tsonly)) | ||
3738 | return; | 3743 | return; |
3739 | 3744 | ||
3740 | if (tsonly) | 3745 | if (tsonly) |
@@ -4172,7 +4177,7 @@ void skb_scrub_packet(struct sk_buff *skb, bool xnet) | |||
4172 | skb->ignore_df = 0; | 4177 | skb->ignore_df = 0; |
4173 | skb_dst_drop(skb); | 4178 | skb_dst_drop(skb); |
4174 | skb->mark = 0; | 4179 | skb->mark = 0; |
4175 | skb->sender_cpu = 0; | 4180 | skb_sender_cpu_clear(skb); |
4176 | skb_init_secmark(skb); | 4181 | skb_init_secmark(skb); |
4177 | secpath_reset(skb); | 4182 | secpath_reset(skb); |
4178 | nf_reset(skb); | 4183 | nf_reset(skb); |
diff --git a/net/core/sock.c b/net/core/sock.c index 93c8b20c91e4..71e3e5f1eaa0 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -653,6 +653,25 @@ static inline void sock_valbool_flag(struct sock *sk, int bit, int valbool) | |||
653 | sock_reset_flag(sk, bit); | 653 | sock_reset_flag(sk, bit); |
654 | } | 654 | } |
655 | 655 | ||
656 | bool sk_mc_loop(struct sock *sk) | ||
657 | { | ||
658 | if (dev_recursion_level()) | ||
659 | return false; | ||
660 | if (!sk) | ||
661 | return true; | ||
662 | switch (sk->sk_family) { | ||
663 | case AF_INET: | ||
664 | return inet_sk(sk)->mc_loop; | ||
665 | #if IS_ENABLED(CONFIG_IPV6) | ||
666 | case AF_INET6: | ||
667 | return inet6_sk(sk)->mc_loop; | ||
668 | #endif | ||
669 | } | ||
670 | WARN_ON(1); | ||
671 | return true; | ||
672 | } | ||
673 | EXPORT_SYMBOL(sk_mc_loop); | ||
674 | |||
656 | /* | 675 | /* |
657 | * This is meant for all protocols to use and covers goings on | 676 | * This is meant for all protocols to use and covers goings on |
658 | * at the socket level. Everything here is generic. | 677 | * at the socket level. Everything here is generic. |
@@ -1655,6 +1674,10 @@ void sock_rfree(struct sk_buff *skb) | |||
1655 | } | 1674 | } |
1656 | EXPORT_SYMBOL(sock_rfree); | 1675 | EXPORT_SYMBOL(sock_rfree); |
1657 | 1676 | ||
1677 | /* | ||
1678 | * Buffer destructor for skbs that are not used directly in read or write | ||
1679 | * path, e.g. for error handler skbs. Automatically called from kfree_skb. | ||
1680 | */ | ||
1658 | void sock_efree(struct sk_buff *skb) | 1681 | void sock_efree(struct sk_buff *skb) |
1659 | { | 1682 | { |
1660 | sock_put(skb->sk); | 1683 | 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/decnet/dn_route.c b/net/decnet/dn_route.c index 1d7c1256e845..3b81092771f8 100644 --- a/net/decnet/dn_route.c +++ b/net/decnet/dn_route.c | |||
@@ -1062,7 +1062,7 @@ source_ok: | |||
1062 | if (decnet_debug_level & 16) | 1062 | if (decnet_debug_level & 16) |
1063 | printk(KERN_DEBUG | 1063 | printk(KERN_DEBUG |
1064 | "dn_route_output_slow: initial checks complete." | 1064 | "dn_route_output_slow: initial checks complete." |
1065 | " dst=%o4x src=%04x oif=%d try_hard=%d\n", | 1065 | " dst=%04x src=%04x oif=%d try_hard=%d\n", |
1066 | le16_to_cpu(fld.daddr), le16_to_cpu(fld.saddr), | 1066 | le16_to_cpu(fld.daddr), le16_to_cpu(fld.saddr), |
1067 | fld.flowidn_oif, try_hard); | 1067 | fld.flowidn_oif, try_hard); |
1068 | 1068 | ||
diff --git a/net/decnet/dn_rules.c b/net/decnet/dn_rules.c index faf7cc3483fe..9d66a0f72f90 100644 --- a/net/decnet/dn_rules.c +++ b/net/decnet/dn_rules.c | |||
@@ -248,7 +248,9 @@ void __init dn_fib_rules_init(void) | |||
248 | 248 | ||
249 | void __exit dn_fib_rules_cleanup(void) | 249 | void __exit dn_fib_rules_cleanup(void) |
250 | { | 250 | { |
251 | rtnl_lock(); | ||
251 | fib_rules_unregister(dn_fib_rules_ops); | 252 | fib_rules_unregister(dn_fib_rules_ops); |
253 | rtnl_unlock(); | ||
252 | rcu_barrier(); | 254 | rcu_barrier(); |
253 | } | 255 | } |
254 | 256 | ||
diff --git a/net/dsa/dsa.c b/net/dsa/dsa.c index 2173402d87e0..4dea2e0681d1 100644 --- a/net/dsa/dsa.c +++ b/net/dsa/dsa.c | |||
@@ -501,12 +501,10 @@ static struct net_device *dev_to_net_device(struct device *dev) | |||
501 | #ifdef CONFIG_OF | 501 | #ifdef CONFIG_OF |
502 | static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | 502 | static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, |
503 | struct dsa_chip_data *cd, | 503 | struct dsa_chip_data *cd, |
504 | int chip_index, | 504 | int chip_index, int port_index, |
505 | struct device_node *link) | 505 | struct device_node *link) |
506 | { | 506 | { |
507 | int ret; | ||
508 | const __be32 *reg; | 507 | const __be32 *reg; |
509 | int link_port_addr; | ||
510 | int link_sw_addr; | 508 | int link_sw_addr; |
511 | struct device_node *parent_sw; | 509 | struct device_node *parent_sw; |
512 | int len; | 510 | int len; |
@@ -519,6 +517,10 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | |||
519 | if (!reg || (len != sizeof(*reg) * 2)) | 517 | if (!reg || (len != sizeof(*reg) * 2)) |
520 | return -EINVAL; | 518 | return -EINVAL; |
521 | 519 | ||
520 | /* | ||
521 | * Get the destination switch number from the second field of its 'reg' | ||
522 | * property, i.e. for "reg = <0x19 1>" sw_addr is '1'. | ||
523 | */ | ||
522 | link_sw_addr = be32_to_cpup(reg + 1); | 524 | link_sw_addr = be32_to_cpup(reg + 1); |
523 | 525 | ||
524 | if (link_sw_addr >= pd->nr_chips) | 526 | if (link_sw_addr >= pd->nr_chips) |
@@ -535,20 +537,9 @@ static int dsa_of_setup_routing_table(struct dsa_platform_data *pd, | |||
535 | memset(cd->rtable, -1, pd->nr_chips * sizeof(s8)); | 537 | memset(cd->rtable, -1, pd->nr_chips * sizeof(s8)); |
536 | } | 538 | } |
537 | 539 | ||
538 | reg = of_get_property(link, "reg", NULL); | 540 | cd->rtable[link_sw_addr] = port_index; |
539 | if (!reg) { | ||
540 | ret = -EINVAL; | ||
541 | goto out; | ||
542 | } | ||
543 | |||
544 | link_port_addr = be32_to_cpup(reg); | ||
545 | |||
546 | cd->rtable[link_sw_addr] = link_port_addr; | ||
547 | 541 | ||
548 | return 0; | 542 | return 0; |
549 | out: | ||
550 | kfree(cd->rtable); | ||
551 | return ret; | ||
552 | } | 543 | } |
553 | 544 | ||
554 | static void dsa_of_free_platform_data(struct dsa_platform_data *pd) | 545 | static void dsa_of_free_platform_data(struct dsa_platform_data *pd) |
@@ -658,7 +649,7 @@ static int dsa_of_probe(struct platform_device *pdev) | |||
658 | if (!strcmp(port_name, "dsa") && link && | 649 | if (!strcmp(port_name, "dsa") && link && |
659 | pd->nr_chips > 1) { | 650 | pd->nr_chips > 1) { |
660 | ret = dsa_of_setup_routing_table(pd, cd, | 651 | ret = dsa_of_setup_routing_table(pd, cd, |
661 | chip_index, link); | 652 | chip_index, port_index, link); |
662 | if (ret) | 653 | if (ret) |
663 | goto out_free_chip; | 654 | goto out_free_chip; |
664 | } | 655 | } |
diff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index a138d75751df..44d27469ae55 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c | |||
@@ -359,8 +359,11 @@ static void hsr_dev_destroy(struct net_device *hsr_dev) | |||
359 | struct hsr_port *port; | 359 | struct hsr_port *port; |
360 | 360 | ||
361 | hsr = netdev_priv(hsr_dev); | 361 | hsr = netdev_priv(hsr_dev); |
362 | |||
363 | rtnl_lock(); | ||
362 | hsr_for_each_port(hsr, port) | 364 | hsr_for_each_port(hsr, port) |
363 | hsr_del_port(port); | 365 | hsr_del_port(port); |
366 | rtnl_unlock(); | ||
364 | 367 | ||
365 | del_timer_sync(&hsr->prune_timer); | 368 | del_timer_sync(&hsr->prune_timer); |
366 | del_timer_sync(&hsr->announce_timer); | 369 | del_timer_sync(&hsr->announce_timer); |
diff --git a/net/hsr/hsr_main.c b/net/hsr/hsr_main.c index 779d28b65417..cd37d0011b42 100644 --- a/net/hsr/hsr_main.c +++ b/net/hsr/hsr_main.c | |||
@@ -36,6 +36,10 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event, | |||
36 | return NOTIFY_DONE; /* Not an HSR device */ | 36 | return NOTIFY_DONE; /* Not an HSR device */ |
37 | hsr = netdev_priv(dev); | 37 | hsr = netdev_priv(dev); |
38 | port = hsr_port_get_hsr(hsr, HSR_PT_MASTER); | 38 | port = hsr_port_get_hsr(hsr, HSR_PT_MASTER); |
39 | if (port == NULL) { | ||
40 | /* Resend of notification concerning removed device? */ | ||
41 | return NOTIFY_DONE; | ||
42 | } | ||
39 | } else { | 43 | } else { |
40 | hsr = port->hsr; | 44 | hsr = port->hsr; |
41 | } | 45 | } |
diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c index a348dcbcd683..7d37366cc695 100644 --- a/net/hsr/hsr_slave.c +++ b/net/hsr/hsr_slave.c | |||
@@ -181,8 +181,10 @@ void hsr_del_port(struct hsr_port *port) | |||
181 | list_del_rcu(&port->port_list); | 181 | list_del_rcu(&port->port_list); |
182 | 182 | ||
183 | if (port != master) { | 183 | if (port != master) { |
184 | netdev_update_features(master->dev); | 184 | if (master != NULL) { |
185 | dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); | 185 | netdev_update_features(master->dev); |
186 | dev_set_mtu(master->dev, hsr_get_max_mtu(hsr)); | ||
187 | } | ||
186 | netdev_rx_handler_unregister(port->dev); | 188 | netdev_rx_handler_unregister(port->dev); |
187 | dev_set_promiscuity(port->dev, -1); | 189 | dev_set_promiscuity(port->dev, -1); |
188 | } | 190 | } |
@@ -192,5 +194,7 @@ void hsr_del_port(struct hsr_port *port) | |||
192 | */ | 194 | */ |
193 | 195 | ||
194 | synchronize_rcu(); | 196 | synchronize_rcu(); |
195 | dev_put(port->dev); | 197 | |
198 | if (port != master) | ||
199 | dev_put(port->dev); | ||
196 | } | 200 | } |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index 57be71dd6a9e..23b9b3e86f4c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -1111,11 +1111,10 @@ static void ip_fib_net_exit(struct net *net) | |||
1111 | { | 1111 | { |
1112 | unsigned int i; | 1112 | unsigned int i; |
1113 | 1113 | ||
1114 | rtnl_lock(); | ||
1114 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1115 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1115 | fib4_rules_exit(net); | 1116 | fib4_rules_exit(net); |
1116 | #endif | 1117 | #endif |
1117 | |||
1118 | rtnl_lock(); | ||
1119 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { | 1118 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { |
1120 | struct fib_table *tb; | 1119 | struct fib_table *tb; |
1121 | struct hlist_head *head; | 1120 | struct hlist_head *head; |
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 e5b6d0ddcb58..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))) | 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_output.c b/net/ipv4/ip_output.c index d68199d9b2b0..a7aea2048a0d 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -888,7 +888,8 @@ static int __ip_append_data(struct sock *sk, | |||
888 | cork->length += length; | 888 | cork->length += length; |
889 | if (((length > mtu) || (skb && skb_is_gso(skb))) && | 889 | if (((length > mtu) || (skb && skb_is_gso(skb))) && |
890 | (sk->sk_protocol == IPPROTO_UDP) && | 890 | (sk->sk_protocol == IPPROTO_UDP) && |
891 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len) { | 891 | (rt->dst.dev->features & NETIF_F_UFO) && !rt->dst.header_len && |
892 | (sk->sk_type == SOCK_DGRAM)) { | ||
892 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, | 893 | err = ip_ufo_append_data(sk, queue, getfrag, from, length, |
893 | hh_len, fragheaderlen, transhdrlen, | 894 | hh_len, fragheaderlen, transhdrlen, |
894 | maxfraglen, flags); | 895 | maxfraglen, flags); |
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/ipmr.c b/net/ipv4/ipmr.c index 9d78427652d2..fe54eba6d00d 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
@@ -268,7 +268,7 @@ static int __net_init ipmr_rules_init(struct net *net) | |||
268 | return 0; | 268 | return 0; |
269 | 269 | ||
270 | err2: | 270 | err2: |
271 | kfree(mrt); | 271 | ipmr_free_table(mrt); |
272 | err1: | 272 | err1: |
273 | fib_rules_unregister(ops); | 273 | fib_rules_unregister(ops); |
274 | return err; | 274 | return err; |
@@ -278,11 +278,13 @@ static void __net_exit ipmr_rules_exit(struct net *net) | |||
278 | { | 278 | { |
279 | struct mr_table *mrt, *next; | 279 | struct mr_table *mrt, *next; |
280 | 280 | ||
281 | rtnl_lock(); | ||
281 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { | 282 | list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { |
282 | list_del(&mrt->list); | 283 | list_del(&mrt->list); |
283 | ipmr_free_table(mrt); | 284 | ipmr_free_table(mrt); |
284 | } | 285 | } |
285 | fib_rules_unregister(net->ipv4.mr_rules_ops); | 286 | fib_rules_unregister(net->ipv4.mr_rules_ops); |
287 | rtnl_unlock(); | ||
286 | } | 288 | } |
287 | #else | 289 | #else |
288 | #define ipmr_for_each_table(mrt, net) \ | 290 | #define ipmr_for_each_table(mrt, net) \ |
@@ -308,7 +310,10 @@ static int __net_init ipmr_rules_init(struct net *net) | |||
308 | 310 | ||
309 | static void __net_exit ipmr_rules_exit(struct net *net) | 311 | static void __net_exit ipmr_rules_exit(struct net *net) |
310 | { | 312 | { |
313 | rtnl_lock(); | ||
311 | ipmr_free_table(net->ipv4.mrt); | 314 | ipmr_free_table(net->ipv4.mrt); |
315 | net->ipv4.mrt = NULL; | ||
316 | rtnl_unlock(); | ||
312 | } | 317 | } |
313 | #endif | 318 | #endif |
314 | 319 | ||
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 99e810f84671..cf5e82f39d3b 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -272,9 +272,9 @@ static void trace_packet(const struct sk_buff *skb, | |||
272 | &chainname, &comment, &rulenum) != 0) | 272 | &chainname, &comment, &rulenum) != 0) |
273 | break; | 273 | break; |
274 | 274 | ||
275 | nf_log_packet(net, AF_INET, hook, skb, in, out, &trace_loginfo, | 275 | nf_log_trace(net, AF_INET, hook, skb, in, out, &trace_loginfo, |
276 | "TRACE: %s:%s:%s:%u ", | 276 | "TRACE: %s:%s:%s:%u ", |
277 | tablename, chainname, comment, rulenum); | 277 | tablename, chainname, comment, rulenum); |
278 | } | 278 | } |
279 | #endif | 279 | #endif |
280 | 280 | ||
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/tcp_input.c b/net/ipv4/tcp_input.c index 8fdd27b17306..f501ac048366 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3105,10 +3105,11 @@ static int tcp_clean_rtx_queue(struct sock *sk, int prior_fackets, | |||
3105 | if (!first_ackt.v64) | 3105 | if (!first_ackt.v64) |
3106 | first_ackt = last_ackt; | 3106 | first_ackt = last_ackt; |
3107 | 3107 | ||
3108 | if (!(sacked & TCPCB_SACKED_ACKED)) | 3108 | if (!(sacked & TCPCB_SACKED_ACKED)) { |
3109 | reord = min(pkts_acked, reord); | 3109 | reord = min(pkts_acked, reord); |
3110 | if (!after(scb->end_seq, tp->high_seq)) | 3110 | if (!after(scb->end_seq, tp->high_seq)) |
3111 | flag |= FLAG_ORIG_SACK_ACKED; | 3111 | flag |= FLAG_ORIG_SACK_ACKED; |
3112 | } | ||
3112 | } | 3113 | } |
3113 | 3114 | ||
3114 | if (sacked & TCPCB_SACKED_ACKED) | 3115 | if (sacked & TCPCB_SACKED_ACKED) |
@@ -4770,7 +4771,7 @@ static bool tcp_should_expand_sndbuf(const struct sock *sk) | |||
4770 | return false; | 4771 | return false; |
4771 | 4772 | ||
4772 | /* If we filled the congestion window, do not expand. */ | 4773 | /* If we filled the congestion window, do not expand. */ |
4773 | if (tp->packets_out >= tp->snd_cwnd) | 4774 | if (tcp_packets_in_flight(tp) >= tp->snd_cwnd) |
4774 | return false; | 4775 | return false; |
4775 | 4776 | ||
4776 | return true; | 4777 | return true; |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 5a2dfed4783b..f1756ee02207 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -1518,7 +1518,7 @@ void tcp_v4_early_demux(struct sk_buff *skb) | |||
1518 | skb->sk = sk; | 1518 | skb->sk = sk; |
1519 | skb->destructor = sock_edemux; | 1519 | skb->destructor = sock_edemux; |
1520 | if (sk->sk_state != TCP_TIME_WAIT) { | 1520 | if (sk->sk_state != TCP_TIME_WAIT) { |
1521 | struct dst_entry *dst = sk->sk_rx_dst; | 1521 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
1522 | 1522 | ||
1523 | if (dst) | 1523 | if (dst) |
1524 | dst = dst_check(dst, 0); | 1524 | dst = dst_check(dst, 0); |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a2a796c5536b..1db253e36045 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2773,15 +2773,11 @@ void tcp_send_fin(struct sock *sk) | |||
2773 | } else { | 2773 | } else { |
2774 | /* Socket is locked, keep trying until memory is available. */ | 2774 | /* Socket is locked, keep trying until memory is available. */ |
2775 | for (;;) { | 2775 | for (;;) { |
2776 | skb = alloc_skb_fclone(MAX_TCP_HEADER, | 2776 | skb = sk_stream_alloc_skb(sk, 0, sk->sk_allocation); |
2777 | sk->sk_allocation); | ||
2778 | if (skb) | 2777 | if (skb) |
2779 | break; | 2778 | break; |
2780 | yield(); | 2779 | yield(); |
2781 | } | 2780 | } |
2782 | |||
2783 | /* Reserve space for headers and prepare control bits. */ | ||
2784 | skb_reserve(skb, MAX_TCP_HEADER); | ||
2785 | /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ | 2781 | /* FIN eats a sequence byte, write_seq advanced by tcp_queue_skb(). */ |
2786 | tcp_init_nondata_skb(skb, tp->write_seq, | 2782 | tcp_init_nondata_skb(skb, tp->write_seq, |
2787 | TCPHDR_ACK | TCPHDR_FIN); | 2783 | TCPHDR_ACK | TCPHDR_FIN); |
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/addrconf.c b/net/ipv6/addrconf.c index 98e4a63d72bb..b6030025f411 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -4903,6 +4903,21 @@ int addrconf_sysctl_forward(struct ctl_table *ctl, int write, | |||
4903 | return ret; | 4903 | return ret; |
4904 | } | 4904 | } |
4905 | 4905 | ||
4906 | static | ||
4907 | int addrconf_sysctl_mtu(struct ctl_table *ctl, int write, | ||
4908 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
4909 | { | ||
4910 | struct inet6_dev *idev = ctl->extra1; | ||
4911 | int min_mtu = IPV6_MIN_MTU; | ||
4912 | struct ctl_table lctl; | ||
4913 | |||
4914 | lctl = *ctl; | ||
4915 | lctl.extra1 = &min_mtu; | ||
4916 | lctl.extra2 = idev ? &idev->dev->mtu : NULL; | ||
4917 | |||
4918 | return proc_dointvec_minmax(&lctl, write, buffer, lenp, ppos); | ||
4919 | } | ||
4920 | |||
4906 | static void dev_disable_change(struct inet6_dev *idev) | 4921 | static void dev_disable_change(struct inet6_dev *idev) |
4907 | { | 4922 | { |
4908 | struct netdev_notifier_info info; | 4923 | struct netdev_notifier_info info; |
@@ -5054,7 +5069,7 @@ static struct addrconf_sysctl_table | |||
5054 | .data = &ipv6_devconf.mtu6, | 5069 | .data = &ipv6_devconf.mtu6, |
5055 | .maxlen = sizeof(int), | 5070 | .maxlen = sizeof(int), |
5056 | .mode = 0644, | 5071 | .mode = 0644, |
5057 | .proc_handler = proc_dointvec, | 5072 | .proc_handler = addrconf_sysctl_mtu, |
5058 | }, | 5073 | }, |
5059 | { | 5074 | { |
5060 | .procname = "accept_ra", | 5075 | .procname = "accept_ra", |
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/fib6_rules.c b/net/ipv6/fib6_rules.c index b4d5e1d97c1b..70bc6abc0639 100644 --- a/net/ipv6/fib6_rules.c +++ b/net/ipv6/fib6_rules.c | |||
@@ -104,6 +104,7 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, | |||
104 | goto again; | 104 | goto again; |
105 | flp6->saddr = saddr; | 105 | flp6->saddr = saddr; |
106 | } | 106 | } |
107 | err = rt->dst.error; | ||
107 | goto out; | 108 | goto out; |
108 | } | 109 | } |
109 | again: | 110 | again: |
@@ -321,7 +322,9 @@ out_fib6_rules_ops: | |||
321 | 322 | ||
322 | static void __net_exit fib6_rules_net_exit(struct net *net) | 323 | static void __net_exit fib6_rules_net_exit(struct net *net) |
323 | { | 324 | { |
325 | rtnl_lock(); | ||
324 | fib_rules_unregister(net->ipv6.fib6_rules_ops); | 326 | fib_rules_unregister(net->ipv6.fib6_rules_ops); |
327 | rtnl_unlock(); | ||
325 | } | 328 | } |
326 | 329 | ||
327 | static struct pernet_operations fib6_rules_net_ops = { | 330 | static struct pernet_operations fib6_rules_net_ops = { |
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 7deebf102cba..36cf0ab685a0 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 | ||
@@ -541,7 +542,8 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
541 | { | 542 | { |
542 | struct sk_buff *frag; | 543 | struct sk_buff *frag; |
543 | struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); | 544 | struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); |
544 | struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; | 545 | struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ? |
546 | inet6_sk(skb->sk) : NULL; | ||
545 | struct ipv6hdr *tmp_hdr; | 547 | struct ipv6hdr *tmp_hdr; |
546 | struct frag_hdr *fh; | 548 | struct frag_hdr *fh; |
547 | unsigned int mtu, hlen, left, len; | 549 | unsigned int mtu, hlen, left, len; |
@@ -1298,7 +1300,8 @@ emsgsize: | |||
1298 | if (((length > mtu) || | 1300 | if (((length > mtu) || |
1299 | (skb && skb_is_gso(skb))) && | 1301 | (skb && skb_is_gso(skb))) && |
1300 | (sk->sk_protocol == IPPROTO_UDP) && | 1302 | (sk->sk_protocol == IPPROTO_UDP) && |
1301 | (rt->dst.dev->features & NETIF_F_UFO)) { | 1303 | (rt->dst.dev->features & NETIF_F_UFO) && |
1304 | (sk->sk_type == SOCK_DGRAM)) { | ||
1302 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, | 1305 | err = ip6_ufo_append_data(sk, queue, getfrag, from, length, |
1303 | hh_len, fragheaderlen, | 1306 | hh_len, fragheaderlen, |
1304 | transhdrlen, mtu, flags, rt); | 1307 | transhdrlen, mtu, flags, rt); |
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/ip6mr.c b/net/ipv6/ip6mr.c index 34b682617f50..312e0ff47339 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -252,7 +252,7 @@ static int __net_init ip6mr_rules_init(struct net *net) | |||
252 | return 0; | 252 | return 0; |
253 | 253 | ||
254 | err2: | 254 | err2: |
255 | kfree(mrt); | 255 | ip6mr_free_table(mrt); |
256 | err1: | 256 | err1: |
257 | fib_rules_unregister(ops); | 257 | fib_rules_unregister(ops); |
258 | return err; | 258 | return err; |
@@ -267,8 +267,8 @@ static void __net_exit ip6mr_rules_exit(struct net *net) | |||
267 | list_del(&mrt->list); | 267 | list_del(&mrt->list); |
268 | ip6mr_free_table(mrt); | 268 | ip6mr_free_table(mrt); |
269 | } | 269 | } |
270 | rtnl_unlock(); | ||
271 | fib_rules_unregister(net->ipv6.mr6_rules_ops); | 270 | fib_rules_unregister(net->ipv6.mr6_rules_ops); |
271 | rtnl_unlock(); | ||
272 | } | 272 | } |
273 | #else | 273 | #else |
274 | #define ip6mr_for_each_table(mrt, net) \ | 274 | #define ip6mr_for_each_table(mrt, net) \ |
@@ -336,7 +336,7 @@ static struct mr6_table *ip6mr_new_table(struct net *net, u32 id) | |||
336 | 336 | ||
337 | static void ip6mr_free_table(struct mr6_table *mrt) | 337 | static void ip6mr_free_table(struct mr6_table *mrt) |
338 | { | 338 | { |
339 | del_timer(&mrt->ipmr_expire_timer); | 339 | del_timer_sync(&mrt->ipmr_expire_timer); |
340 | mroute_clean_tables(mrt); | 340 | mroute_clean_tables(mrt); |
341 | kfree(mrt); | 341 | kfree(mrt); |
342 | } | 342 | } |
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c index 471ed24aabae..14ecdaf06bf7 100644 --- a/net/ipv6/ndisc.c +++ b/net/ipv6/ndisc.c | |||
@@ -1218,7 +1218,14 @@ static void ndisc_router_discovery(struct sk_buff *skb) | |||
1218 | if (rt) | 1218 | if (rt) |
1219 | rt6_set_expires(rt, jiffies + (HZ * lifetime)); | 1219 | rt6_set_expires(rt, jiffies + (HZ * lifetime)); |
1220 | if (ra_msg->icmph.icmp6_hop_limit) { | 1220 | if (ra_msg->icmph.icmp6_hop_limit) { |
1221 | in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; | 1221 | /* Only set hop_limit on the interface if it is higher than |
1222 | * the current hop_limit. | ||
1223 | */ | ||
1224 | if (in6_dev->cnf.hop_limit < ra_msg->icmph.icmp6_hop_limit) { | ||
1225 | in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit; | ||
1226 | } else { | ||
1227 | ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than current\n"); | ||
1228 | } | ||
1222 | if (rt) | 1229 | if (rt) |
1223 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, | 1230 | dst_metric_set(&rt->dst, RTAX_HOPLIMIT, |
1224 | ra_msg->icmph.icmp6_hop_limit); | 1231 | ra_msg->icmph.icmp6_hop_limit); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index e080fbbbc0e5..bb00c6f2a885 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -298,9 +298,9 @@ static void trace_packet(const struct sk_buff *skb, | |||
298 | &chainname, &comment, &rulenum) != 0) | 298 | &chainname, &comment, &rulenum) != 0) |
299 | break; | 299 | break; |
300 | 300 | ||
301 | nf_log_packet(net, AF_INET6, hook, skb, in, out, &trace_loginfo, | 301 | nf_log_trace(net, AF_INET6, hook, skb, in, out, &trace_loginfo, |
302 | "TRACE: %s:%s:%s:%u ", | 302 | "TRACE: %s:%s:%s:%u ", |
303 | tablename, chainname, comment, rulenum); | 303 | tablename, chainname, comment, rulenum); |
304 | } | 304 | } |
305 | #endif | 305 | #endif |
306 | 306 | ||
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/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 5d46832c6f72..1f5e62229aaa 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -1411,6 +1411,15 @@ static void tcp_v6_fill_cb(struct sk_buff *skb, const struct ipv6hdr *hdr, | |||
1411 | TCP_SKB_CB(skb)->sacked = 0; | 1411 | TCP_SKB_CB(skb)->sacked = 0; |
1412 | } | 1412 | } |
1413 | 1413 | ||
1414 | static void tcp_v6_restore_cb(struct sk_buff *skb) | ||
1415 | { | ||
1416 | /* We need to move header back to the beginning if xfrm6_policy_check() | ||
1417 | * and tcp_v6_fill_cb() are going to be called again. | ||
1418 | */ | ||
1419 | memmove(IP6CB(skb), &TCP_SKB_CB(skb)->header.h6, | ||
1420 | sizeof(struct inet6_skb_parm)); | ||
1421 | } | ||
1422 | |||
1414 | static int tcp_v6_rcv(struct sk_buff *skb) | 1423 | static int tcp_v6_rcv(struct sk_buff *skb) |
1415 | { | 1424 | { |
1416 | const struct tcphdr *th; | 1425 | const struct tcphdr *th; |
@@ -1543,6 +1552,7 @@ do_time_wait: | |||
1543 | inet_twsk_deschedule(tw, &tcp_death_row); | 1552 | inet_twsk_deschedule(tw, &tcp_death_row); |
1544 | inet_twsk_put(tw); | 1553 | inet_twsk_put(tw); |
1545 | sk = sk2; | 1554 | sk = sk2; |
1555 | tcp_v6_restore_cb(skb); | ||
1546 | goto process; | 1556 | goto process; |
1547 | } | 1557 | } |
1548 | /* Fall through to ACK */ | 1558 | /* Fall through to ACK */ |
@@ -1551,6 +1561,7 @@ do_time_wait: | |||
1551 | tcp_v6_timewait_ack(sk, skb); | 1561 | tcp_v6_timewait_ack(sk, skb); |
1552 | break; | 1562 | break; |
1553 | case TCP_TW_RST: | 1563 | case TCP_TW_RST: |
1564 | tcp_v6_restore_cb(skb); | ||
1554 | goto no_tcp_socket; | 1565 | goto no_tcp_socket; |
1555 | case TCP_TW_SUCCESS: | 1566 | case TCP_TW_SUCCESS: |
1556 | ; | 1567 | ; |
@@ -1585,7 +1596,7 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1585 | skb->sk = sk; | 1596 | skb->sk = sk; |
1586 | skb->destructor = sock_edemux; | 1597 | skb->destructor = sock_edemux; |
1587 | if (sk->sk_state != TCP_TIME_WAIT) { | 1598 | if (sk->sk_state != TCP_TIME_WAIT) { |
1588 | struct dst_entry *dst = sk->sk_rx_dst; | 1599 | struct dst_entry *dst = READ_ONCE(sk->sk_rx_dst); |
1589 | 1600 | ||
1590 | if (dst) | 1601 | if (dst) |
1591 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); | 1602 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index ab889bb16b3c..be2c0ba82c85 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -112,11 +112,9 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
112 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); | 112 | fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen); |
113 | fptr->nexthdr = nexthdr; | 113 | fptr->nexthdr = nexthdr; |
114 | fptr->reserved = 0; | 114 | fptr->reserved = 0; |
115 | if (skb_shinfo(skb)->ip6_frag_id) | 115 | if (!skb_shinfo(skb)->ip6_frag_id) |
116 | fptr->identification = skb_shinfo(skb)->ip6_frag_id; | 116 | ipv6_proxy_select_ident(skb); |
117 | else | 117 | fptr->identification = skb_shinfo(skb)->ip6_frag_id; |
118 | ipv6_select_ident(fptr, | ||
119 | (struct rt6_info *)skb_dst(skb)); | ||
120 | 118 | ||
121 | /* Fragment the skb. ipv6 header and the remaining fields of the | 119 | /* Fragment the skb. ipv6 header and the remaining fields of the |
122 | * fragment header are updated in ipv6_gso_segment() | 120 | * fragment header are updated in ipv6_gso_segment() |
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/irda/ircomm/ircomm_tty.c b/net/irda/ircomm/ircomm_tty.c index 40695b9751c1..683346d2d633 100644 --- a/net/irda/ircomm/ircomm_tty.c +++ b/net/irda/ircomm/ircomm_tty.c | |||
@@ -798,7 +798,9 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) | |||
798 | orig_jiffies = jiffies; | 798 | orig_jiffies = jiffies; |
799 | 799 | ||
800 | /* Set poll time to 200 ms */ | 800 | /* Set poll time to 200 ms */ |
801 | poll_time = IRDA_MIN(timeout, msecs_to_jiffies(200)); | 801 | poll_time = msecs_to_jiffies(200); |
802 | if (timeout) | ||
803 | poll_time = min_t(unsigned long, timeout, poll_time); | ||
802 | 804 | ||
803 | spin_lock_irqsave(&self->spinlock, flags); | 805 | spin_lock_irqsave(&self->spinlock, flags); |
804 | while (self->tx_skb && self->tx_skb->len) { | 806 | while (self->tx_skb && self->tx_skb->len) { |
@@ -811,7 +813,7 @@ static void ircomm_tty_wait_until_sent(struct tty_struct *tty, int timeout) | |||
811 | break; | 813 | break; |
812 | } | 814 | } |
813 | spin_unlock_irqrestore(&self->spinlock, flags); | 815 | spin_unlock_irqrestore(&self->spinlock, flags); |
814 | current->state = TASK_RUNNING; | 816 | __set_current_state(TASK_RUNNING); |
815 | } | 817 | } |
816 | 818 | ||
817 | /* | 819 | /* |
diff --git a/net/irda/irnet/irnet_ppp.c b/net/irda/irnet/irnet_ppp.c index 3c83a1e5ab03..1215693fdd22 100644 --- a/net/irda/irnet/irnet_ppp.c +++ b/net/irda/irnet/irnet_ppp.c | |||
@@ -305,7 +305,7 @@ irnet_ctrl_read(irnet_socket * ap, | |||
305 | 305 | ||
306 | /* Put ourselves on the wait queue to be woken up */ | 306 | /* Put ourselves on the wait queue to be woken up */ |
307 | add_wait_queue(&irnet_events.rwait, &wait); | 307 | add_wait_queue(&irnet_events.rwait, &wait); |
308 | current->state = TASK_INTERRUPTIBLE; | 308 | set_current_state(TASK_INTERRUPTIBLE); |
309 | for(;;) | 309 | for(;;) |
310 | { | 310 | { |
311 | /* If there is unread events */ | 311 | /* If there is unread events */ |
@@ -321,7 +321,7 @@ irnet_ctrl_read(irnet_socket * ap, | |||
321 | /* Yield and wait to be woken up */ | 321 | /* Yield and wait to be woken up */ |
322 | schedule(); | 322 | schedule(); |
323 | } | 323 | } |
324 | current->state = TASK_RUNNING; | 324 | __set_current_state(TASK_RUNNING); |
325 | remove_wait_queue(&irnet_events.rwait, &wait); | 325 | remove_wait_queue(&irnet_events.rwait, &wait); |
326 | 326 | ||
327 | /* Did we got it ? */ | 327 | /* Did we got it ? */ |
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index 2e9953b2db84..53d931172088 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -1114,10 +1114,8 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1114 | noblock, &err); | 1114 | noblock, &err); |
1115 | else | 1115 | else |
1116 | skb = sock_alloc_send_skb(sk, len, noblock, &err); | 1116 | skb = sock_alloc_send_skb(sk, len, noblock, &err); |
1117 | if (!skb) { | 1117 | if (!skb) |
1118 | err = -ENOMEM; | ||
1119 | goto out; | 1118 | goto out; |
1120 | } | ||
1121 | if (iucv->transport == AF_IUCV_TRANS_HIPER) | 1119 | if (iucv->transport == AF_IUCV_TRANS_HIPER) |
1122 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); | 1120 | skb_reserve(skb, sizeof(struct af_iucv_trans_hdr) + ETH_HLEN); |
1123 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { | 1121 | if (memcpy_from_msg(skb_put(skb, len), msg, len)) { |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index 895348e44c7d..a29a504492af 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
@@ -1871,6 +1871,7 @@ static int __init l2tp_init(void) | |||
1871 | l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0); | 1871 | l2tp_wq = alloc_workqueue("l2tp", WQ_UNBOUND, 0); |
1872 | if (!l2tp_wq) { | 1872 | if (!l2tp_wq) { |
1873 | pr_err("alloc_workqueue failed\n"); | 1873 | pr_err("alloc_workqueue failed\n"); |
1874 | unregister_pernet_device(&l2tp_net_ops); | ||
1874 | rc = -ENOMEM; | 1875 | rc = -ENOMEM; |
1875 | goto out; | 1876 | goto out; |
1876 | } | 1877 | } |
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c index a48bad468880..7702978a4c99 100644 --- a/net/mac80211/agg-rx.c +++ b/net/mac80211/agg-rx.c | |||
@@ -49,8 +49,6 @@ static void ieee80211_free_tid_rx(struct rcu_head *h) | |||
49 | container_of(h, struct tid_ampdu_rx, rcu_head); | 49 | container_of(h, struct tid_ampdu_rx, rcu_head); |
50 | int i; | 50 | int i; |
51 | 51 | ||
52 | del_timer_sync(&tid_rx->reorder_timer); | ||
53 | |||
54 | for (i = 0; i < tid_rx->buf_size; i++) | 52 | for (i = 0; i < tid_rx->buf_size; i++) |
55 | __skb_queue_purge(&tid_rx->reorder_buf[i]); | 53 | __skb_queue_purge(&tid_rx->reorder_buf[i]); |
56 | kfree(tid_rx->reorder_buf); | 54 | kfree(tid_rx->reorder_buf); |
@@ -93,6 +91,12 @@ void ___ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid, | |||
93 | 91 | ||
94 | del_timer_sync(&tid_rx->session_timer); | 92 | del_timer_sync(&tid_rx->session_timer); |
95 | 93 | ||
94 | /* make sure ieee80211_sta_reorder_release() doesn't re-arm the timer */ | ||
95 | spin_lock_bh(&tid_rx->reorder_lock); | ||
96 | tid_rx->removed = true; | ||
97 | spin_unlock_bh(&tid_rx->reorder_lock); | ||
98 | del_timer_sync(&tid_rx->reorder_timer); | ||
99 | |||
96 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); | 100 | call_rcu(&tid_rx->rcu_head, ieee80211_free_tid_rx); |
97 | } | 101 | } |
98 | 102 | ||
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c index ff0d2db09df9..5bcd4e5589d3 100644 --- a/net/mac80211/chan.c +++ b/net/mac80211/chan.c | |||
@@ -1508,6 +1508,8 @@ static void __ieee80211_vif_release_channel(struct ieee80211_sub_if_data *sdata) | |||
1508 | if (ieee80211_chanctx_refcount(local, ctx) == 0) | 1508 | if (ieee80211_chanctx_refcount(local, ctx) == 0) |
1509 | ieee80211_free_chanctx(local, ctx); | 1509 | ieee80211_free_chanctx(local, ctx); |
1510 | 1510 | ||
1511 | sdata->radar_required = false; | ||
1512 | |||
1511 | /* Unreserving may ready an in-place reservation. */ | 1513 | /* Unreserving may ready an in-place reservation. */ |
1512 | if (use_reserved_switch) | 1514 | if (use_reserved_switch) |
1513 | ieee80211_vif_use_reserved_switch(local); | 1515 | ieee80211_vif_use_reserved_switch(local); |
@@ -1566,6 +1568,9 @@ int ieee80211_vif_use_channel(struct ieee80211_sub_if_data *sdata, | |||
1566 | ieee80211_recalc_smps_chanctx(local, ctx); | 1568 | ieee80211_recalc_smps_chanctx(local, ctx); |
1567 | ieee80211_recalc_radar_chanctx(local, ctx); | 1569 | ieee80211_recalc_radar_chanctx(local, ctx); |
1568 | out: | 1570 | out: |
1571 | if (ret) | ||
1572 | sdata->radar_required = false; | ||
1573 | |||
1569 | mutex_unlock(&local->chanctx_mtx); | 1574 | mutex_unlock(&local->chanctx_mtx); |
1570 | return ret; | 1575 | return ret; |
1571 | } | 1576 | } |
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/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c index 7c86a002df95..ef6e8a6c4253 100644 --- a/net/mac80211/rc80211_minstrel.c +++ b/net/mac80211/rc80211_minstrel.c | |||
@@ -373,7 +373,7 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta, | |||
373 | rate++; | 373 | rate++; |
374 | mi->sample_deferred++; | 374 | mi->sample_deferred++; |
375 | } else { | 375 | } else { |
376 | if (!msr->sample_limit != 0) | 376 | if (!msr->sample_limit) |
377 | return; | 377 | return; |
378 | 378 | ||
379 | mi->sample_packets++; | 379 | mi->sample_packets++; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 1101563357ea..1eb730bf8752 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -873,9 +873,10 @@ static void ieee80211_sta_reorder_release(struct ieee80211_sub_if_data *sdata, | |||
873 | 873 | ||
874 | set_release_timer: | 874 | set_release_timer: |
875 | 875 | ||
876 | mod_timer(&tid_agg_rx->reorder_timer, | 876 | if (!tid_agg_rx->removed) |
877 | tid_agg_rx->reorder_time[j] + 1 + | 877 | mod_timer(&tid_agg_rx->reorder_timer, |
878 | HT_RX_REORDER_BUF_TIMEOUT); | 878 | tid_agg_rx->reorder_time[j] + 1 + |
879 | HT_RX_REORDER_BUF_TIMEOUT); | ||
879 | } else { | 880 | } else { |
880 | del_timer(&tid_agg_rx->reorder_timer); | 881 | del_timer(&tid_agg_rx->reorder_timer); |
881 | } | 882 | } |
@@ -2214,6 +2215,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx) | |||
2214 | hdr = (struct ieee80211_hdr *) skb->data; | 2215 | hdr = (struct ieee80211_hdr *) skb->data; |
2215 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); | 2216 | mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); |
2216 | 2217 | ||
2218 | if (ieee80211_drop_unencrypted(rx, hdr->frame_control)) | ||
2219 | return RX_DROP_MONITOR; | ||
2220 | |||
2217 | /* frame is in RMC, don't forward */ | 2221 | /* frame is in RMC, don't forward */ |
2218 | if (ieee80211_is_data(hdr->frame_control) && | 2222 | if (ieee80211_is_data(hdr->frame_control) && |
2219 | is_multicast_ether_addr(hdr->addr1) && | 2223 | is_multicast_ether_addr(hdr->addr1) && |
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h index 925e68fe64c7..fb0fc1302a58 100644 --- a/net/mac80211/sta_info.h +++ b/net/mac80211/sta_info.h | |||
@@ -175,6 +175,7 @@ struct tid_ampdu_tx { | |||
175 | * @reorder_lock: serializes access to reorder buffer, see below. | 175 | * @reorder_lock: serializes access to reorder buffer, see below. |
176 | * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and | 176 | * @auto_seq: used for offloaded BA sessions to automatically pick head_seq_and |
177 | * and ssn. | 177 | * and ssn. |
178 | * @removed: this session is removed (but might have been found due to RCU) | ||
178 | * | 179 | * |
179 | * This structure's lifetime is managed by RCU, assignments to | 180 | * This structure's lifetime is managed by RCU, assignments to |
180 | * the array holding it must hold the aggregation mutex. | 181 | * the array holding it must hold the aggregation mutex. |
@@ -199,6 +200,7 @@ struct tid_ampdu_rx { | |||
199 | u16 timeout; | 200 | u16 timeout; |
200 | u8 dialog_token; | 201 | u8 dialog_token; |
201 | bool auto_seq; | 202 | bool auto_seq; |
203 | bool removed; | ||
202 | }; | 204 | }; |
203 | 205 | ||
204 | /** | 206 | /** |
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 88a18ffe2975..07bd8db00af8 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c | |||
@@ -566,6 +566,7 @@ ieee80211_tx_h_check_control_port_protocol(struct ieee80211_tx_data *tx) | |||
566 | if (tx->sdata->control_port_no_encrypt) | 566 | if (tx->sdata->control_port_no_encrypt) |
567 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; | 567 | info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; |
568 | info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; | 568 | info->control.flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; |
569 | info->flags |= IEEE80211_TX_CTL_USE_MINRATE; | ||
569 | } | 570 | } |
570 | 571 | ||
571 | return TX_CONTINUE; | 572 | return TX_CONTINUE; |
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_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index e55759056361..ed99448671c3 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -3402,7 +3402,7 @@ static int ip_vs_genl_set_cmd(struct sk_buff *skb, struct genl_info *info) | |||
3402 | if (udest.af == 0) | 3402 | if (udest.af == 0) |
3403 | udest.af = svc->af; | 3403 | udest.af = svc->af; |
3404 | 3404 | ||
3405 | if (udest.af != svc->af) { | 3405 | if (udest.af != svc->af && cmd != IPVS_CMD_DEL_DEST) { |
3406 | /* The synchronization protocol is incompatible | 3406 | /* The synchronization protocol is incompatible |
3407 | * with mixed family services | 3407 | * with mixed family services |
3408 | */ | 3408 | */ |
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_log.c b/net/netfilter/nf_log.c index 0d8448f19dfe..675d12c69e32 100644 --- a/net/netfilter/nf_log.c +++ b/net/netfilter/nf_log.c | |||
@@ -212,6 +212,30 @@ void nf_log_packet(struct net *net, | |||
212 | } | 212 | } |
213 | EXPORT_SYMBOL(nf_log_packet); | 213 | EXPORT_SYMBOL(nf_log_packet); |
214 | 214 | ||
215 | void nf_log_trace(struct net *net, | ||
216 | u_int8_t pf, | ||
217 | unsigned int hooknum, | ||
218 | const struct sk_buff *skb, | ||
219 | const struct net_device *in, | ||
220 | const struct net_device *out, | ||
221 | const struct nf_loginfo *loginfo, const char *fmt, ...) | ||
222 | { | ||
223 | va_list args; | ||
224 | char prefix[NF_LOG_PREFIXLEN]; | ||
225 | const struct nf_logger *logger; | ||
226 | |||
227 | rcu_read_lock(); | ||
228 | logger = rcu_dereference(net->nf.nf_loggers[pf]); | ||
229 | if (logger) { | ||
230 | va_start(args, fmt); | ||
231 | vsnprintf(prefix, sizeof(prefix), fmt, args); | ||
232 | va_end(args); | ||
233 | logger->logfn(net, pf, hooknum, skb, in, out, loginfo, prefix); | ||
234 | } | ||
235 | rcu_read_unlock(); | ||
236 | } | ||
237 | EXPORT_SYMBOL(nf_log_trace); | ||
238 | |||
215 | #define S_SIZE (1024 - (sizeof(unsigned int) + 1)) | 239 | #define S_SIZE (1024 - (sizeof(unsigned int) + 1)) |
216 | 240 | ||
217 | struct nf_log_buf { | 241 | struct nf_log_buf { |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index 199fd0f27b0e..ac1a9528dbf2 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 |
@@ -1225,7 +1225,10 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb, | |||
1225 | 1225 | ||
1226 | if (nla[NFTA_CHAIN_POLICY]) { | 1226 | if (nla[NFTA_CHAIN_POLICY]) { |
1227 | if ((chain != NULL && | 1227 | if ((chain != NULL && |
1228 | !(chain->flags & NFT_BASE_CHAIN)) || | 1228 | !(chain->flags & NFT_BASE_CHAIN))) |
1229 | return -EOPNOTSUPP; | ||
1230 | |||
1231 | if (chain == NULL && | ||
1229 | nla[NFTA_CHAIN_HOOK] == NULL) | 1232 | nla[NFTA_CHAIN_HOOK] == NULL) |
1230 | return -EOPNOTSUPP; | 1233 | return -EOPNOTSUPP; |
1231 | 1234 | ||
@@ -1711,9 +1714,12 @@ static int nf_tables_fill_rule_info(struct sk_buff *skb, struct net *net, | |||
1711 | } | 1714 | } |
1712 | nla_nest_end(skb, list); | 1715 | nla_nest_end(skb, list); |
1713 | 1716 | ||
1714 | if (rule->ulen && | 1717 | if (rule->udata) { |
1715 | nla_put(skb, NFTA_RULE_USERDATA, rule->ulen, nft_userdata(rule))) | 1718 | struct nft_userdata *udata = nft_userdata(rule); |
1716 | goto nla_put_failure; | 1719 | if (nla_put(skb, NFTA_RULE_USERDATA, udata->len + 1, |
1720 | udata->data) < 0) | ||
1721 | goto nla_put_failure; | ||
1722 | } | ||
1717 | 1723 | ||
1718 | nlmsg_end(skb, nlh); | 1724 | nlmsg_end(skb, nlh); |
1719 | return 0; | 1725 | return 0; |
@@ -1896,11 +1902,12 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
1896 | struct nft_table *table; | 1902 | struct nft_table *table; |
1897 | struct nft_chain *chain; | 1903 | struct nft_chain *chain; |
1898 | struct nft_rule *rule, *old_rule = NULL; | 1904 | struct nft_rule *rule, *old_rule = NULL; |
1905 | struct nft_userdata *udata; | ||
1899 | struct nft_trans *trans = NULL; | 1906 | struct nft_trans *trans = NULL; |
1900 | struct nft_expr *expr; | 1907 | struct nft_expr *expr; |
1901 | struct nft_ctx ctx; | 1908 | struct nft_ctx ctx; |
1902 | struct nlattr *tmp; | 1909 | struct nlattr *tmp; |
1903 | unsigned int size, i, n, ulen = 0; | 1910 | unsigned int size, i, n, ulen = 0, usize = 0; |
1904 | int err, rem; | 1911 | int err, rem; |
1905 | bool create; | 1912 | bool create; |
1906 | u64 handle, pos_handle; | 1913 | u64 handle, pos_handle; |
@@ -1968,12 +1975,19 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
1968 | n++; | 1975 | n++; |
1969 | } | 1976 | } |
1970 | } | 1977 | } |
1978 | /* Check for overflow of dlen field */ | ||
1979 | err = -EFBIG; | ||
1980 | if (size >= 1 << 12) | ||
1981 | goto err1; | ||
1971 | 1982 | ||
1972 | if (nla[NFTA_RULE_USERDATA]) | 1983 | if (nla[NFTA_RULE_USERDATA]) { |
1973 | ulen = nla_len(nla[NFTA_RULE_USERDATA]); | 1984 | ulen = nla_len(nla[NFTA_RULE_USERDATA]); |
1985 | if (ulen > 0) | ||
1986 | usize = sizeof(struct nft_userdata) + ulen; | ||
1987 | } | ||
1974 | 1988 | ||
1975 | err = -ENOMEM; | 1989 | err = -ENOMEM; |
1976 | rule = kzalloc(sizeof(*rule) + size + ulen, GFP_KERNEL); | 1990 | rule = kzalloc(sizeof(*rule) + size + usize, GFP_KERNEL); |
1977 | if (rule == NULL) | 1991 | if (rule == NULL) |
1978 | goto err1; | 1992 | goto err1; |
1979 | 1993 | ||
@@ -1981,10 +1995,13 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
1981 | 1995 | ||
1982 | rule->handle = handle; | 1996 | rule->handle = handle; |
1983 | rule->dlen = size; | 1997 | rule->dlen = size; |
1984 | rule->ulen = ulen; | 1998 | rule->udata = ulen ? 1 : 0; |
1985 | 1999 | ||
1986 | if (ulen) | 2000 | if (ulen) { |
1987 | nla_memcpy(nft_userdata(rule), nla[NFTA_RULE_USERDATA], ulen); | 2001 | udata = nft_userdata(rule); |
2002 | udata->len = ulen - 1; | ||
2003 | nla_memcpy(udata->data, nla[NFTA_RULE_USERDATA], ulen); | ||
2004 | } | ||
1988 | 2005 | ||
1989 | expr = nft_expr_first(rule); | 2006 | expr = nft_expr_first(rule); |
1990 | for (i = 0; i < n; i++) { | 2007 | for (i = 0; i < n; i++) { |
@@ -2031,12 +2048,6 @@ static int nf_tables_newrule(struct sock *nlsk, struct sk_buff *skb, | |||
2031 | 2048 | ||
2032 | err3: | 2049 | err3: |
2033 | list_del_rcu(&rule->list); | 2050 | 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: | 2051 | err2: |
2041 | nf_tables_rule_destroy(&ctx, rule); | 2052 | nf_tables_rule_destroy(&ctx, rule); |
2042 | err1: | 2053 | err1: |
@@ -3612,12 +3623,11 @@ static int nf_tables_commit(struct sk_buff *skb) | |||
3612 | &te->elem, | 3623 | &te->elem, |
3613 | NFT_MSG_DELSETELEM, 0); | 3624 | NFT_MSG_DELSETELEM, 0); |
3614 | te->set->ops->get(te->set, &te->elem); | 3625 | 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); | 3626 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); |
3617 | if (te->elem.flags & NFT_SET_MAP) { | 3627 | if (te->set->flags & NFT_SET_MAP && |
3618 | nft_data_uninit(&te->elem.data, | 3628 | !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) |
3619 | te->set->dtype); | 3629 | nft_data_uninit(&te->elem.data, te->set->dtype); |
3620 | } | 3630 | te->set->ops->remove(te->set, &te->elem); |
3621 | nft_trans_destroy(trans); | 3631 | nft_trans_destroy(trans); |
3622 | break; | 3632 | break; |
3623 | } | 3633 | } |
@@ -3658,7 +3668,7 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3658 | { | 3668 | { |
3659 | struct net *net = sock_net(skb->sk); | 3669 | struct net *net = sock_net(skb->sk); |
3660 | struct nft_trans *trans, *next; | 3670 | struct nft_trans *trans, *next; |
3661 | struct nft_set *set; | 3671 | struct nft_trans_elem *te; |
3662 | 3672 | ||
3663 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { | 3673 | list_for_each_entry_safe(trans, next, &net->nft.commit_list, list) { |
3664 | switch (trans->msg_type) { | 3674 | switch (trans->msg_type) { |
@@ -3719,9 +3729,13 @@ static int nf_tables_abort(struct sk_buff *skb) | |||
3719 | break; | 3729 | break; |
3720 | case NFT_MSG_NEWSETELEM: | 3730 | case NFT_MSG_NEWSETELEM: |
3721 | nft_trans_elem_set(trans)->nelems--; | 3731 | nft_trans_elem_set(trans)->nelems--; |
3722 | set = nft_trans_elem_set(trans); | 3732 | te = (struct nft_trans_elem *)trans->data; |
3723 | set->ops->get(set, &nft_trans_elem(trans)); | 3733 | te->set->ops->get(te->set, &te->elem); |
3724 | set->ops->remove(set, &nft_trans_elem(trans)); | 3734 | nft_data_uninit(&te->elem.key, NFT_DATA_VALUE); |
3735 | if (te->set->flags & NFT_SET_MAP && | ||
3736 | !(te->elem.flags & NFT_SET_ELEM_INTERVAL_END)) | ||
3737 | nft_data_uninit(&te->elem.data, te->set->dtype); | ||
3738 | te->set->ops->remove(te->set, &te->elem); | ||
3725 | nft_trans_destroy(trans); | 3739 | nft_trans_destroy(trans); |
3726 | break; | 3740 | break; |
3727 | case NFT_MSG_DELSETELEM: | 3741 | case NFT_MSG_DELSETELEM: |
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c index 3b90eb2b2c55..2d298dccb6dd 100644 --- a/net/netfilter/nf_tables_core.c +++ b/net/netfilter/nf_tables_core.c | |||
@@ -94,10 +94,10 @@ static void nft_trace_packet(const struct nft_pktinfo *pkt, | |||
94 | { | 94 | { |
95 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); | 95 | struct net *net = dev_net(pkt->in ? pkt->in : pkt->out); |
96 | 96 | ||
97 | nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in, | 97 | nf_log_trace(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in, |
98 | pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", | 98 | pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ", |
99 | chain->table->name, chain->name, comments[type], | 99 | chain->table->name, chain->name, comments[type], |
100 | rulenum); | 100 | rulenum); |
101 | } | 101 | } |
102 | 102 | ||
103 | unsigned int | 103 | unsigned int |
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index a5599fc51a6f..54330fb5efaf 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c | |||
@@ -77,6 +77,9 @@ nfnl_cthelper_parse_tuple(struct nf_conntrack_tuple *tuple, | |||
77 | if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) | 77 | if (!tb[NFCTH_TUPLE_L3PROTONUM] || !tb[NFCTH_TUPLE_L4PROTONUM]) |
78 | return -EINVAL; | 78 | return -EINVAL; |
79 | 79 | ||
80 | /* Not all fields are initialized so first zero the tuple */ | ||
81 | memset(tuple, 0, sizeof(struct nf_conntrack_tuple)); | ||
82 | |||
80 | tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); | 83 | tuple->src.l3num = ntohs(nla_get_be16(tb[NFCTH_TUPLE_L3PROTONUM])); |
81 | tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); | 84 | tuple->dst.protonum = nla_get_u8(tb[NFCTH_TUPLE_L4PROTONUM]); |
82 | 85 | ||
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c index c598f74063a1..65f3e2b6be44 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; |
@@ -133,11 +133,14 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par, | |||
133 | entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; | 133 | entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; |
134 | break; | 134 | break; |
135 | case AF_INET6: | 135 | case AF_INET6: |
136 | if (proto) | ||
137 | entry->e6.ipv6.flags |= IP6T_F_PROTO; | ||
138 | |||
136 | entry->e6.ipv6.proto = proto; | 139 | entry->e6.ipv6.proto = proto; |
137 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; | 140 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
138 | break; | 141 | break; |
139 | case NFPROTO_BRIDGE: | 142 | case NFPROTO_BRIDGE: |
140 | entry->ebt.ethproto = proto; | 143 | entry->ebt.ethproto = (__force __be16)proto; |
141 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; | 144 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
142 | break; | 145 | break; |
143 | } | 146 | } |
@@ -171,7 +174,7 @@ static const struct nla_policy nft_rule_compat_policy[NFTA_RULE_COMPAT_MAX + 1] | |||
171 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, | 174 | [NFTA_RULE_COMPAT_FLAGS] = { .type = NLA_U32 }, |
172 | }; | 175 | }; |
173 | 176 | ||
174 | static int nft_parse_compat(const struct nlattr *attr, u8 *proto, bool *inv) | 177 | static int nft_parse_compat(const struct nlattr *attr, u16 *proto, bool *inv) |
175 | { | 178 | { |
176 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; | 179 | struct nlattr *tb[NFTA_RULE_COMPAT_MAX+1]; |
177 | u32 flags; | 180 | u32 flags; |
@@ -203,7 +206,7 @@ nft_target_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
203 | struct xt_target *target = expr->ops->data; | 206 | struct xt_target *target = expr->ops->data; |
204 | struct xt_tgchk_param par; | 207 | struct xt_tgchk_param par; |
205 | size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); | 208 | size_t size = XT_ALIGN(nla_len(tb[NFTA_TARGET_INFO])); |
206 | u8 proto = 0; | 209 | u16 proto = 0; |
207 | bool inv = false; | 210 | bool inv = false; |
208 | union nft_entry e = {}; | 211 | union nft_entry e = {}; |
209 | int ret; | 212 | int ret; |
@@ -334,7 +337,7 @@ static const struct nla_policy nft_match_policy[NFTA_MATCH_MAX + 1] = { | |||
334 | static void | 337 | static void |
335 | nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, | 338 | nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, |
336 | struct xt_match *match, void *info, | 339 | struct xt_match *match, void *info, |
337 | union nft_entry *entry, u8 proto, bool inv) | 340 | union nft_entry *entry, u16 proto, bool inv) |
338 | { | 341 | { |
339 | par->net = ctx->net; | 342 | par->net = ctx->net; |
340 | par->table = ctx->table->name; | 343 | par->table = ctx->table->name; |
@@ -344,11 +347,14 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx, | |||
344 | entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; | 347 | entry->e4.ip.invflags = inv ? IPT_INV_PROTO : 0; |
345 | break; | 348 | break; |
346 | case AF_INET6: | 349 | case AF_INET6: |
350 | if (proto) | ||
351 | entry->e6.ipv6.flags |= IP6T_F_PROTO; | ||
352 | |||
347 | entry->e6.ipv6.proto = proto; | 353 | entry->e6.ipv6.proto = proto; |
348 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; | 354 | entry->e6.ipv6.invflags = inv ? IP6T_INV_PROTO : 0; |
349 | break; | 355 | break; |
350 | case NFPROTO_BRIDGE: | 356 | case NFPROTO_BRIDGE: |
351 | entry->ebt.ethproto = proto; | 357 | entry->ebt.ethproto = (__force __be16)proto; |
352 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; | 358 | entry->ebt.invflags = inv ? EBT_IPROTO : 0; |
353 | break; | 359 | break; |
354 | } | 360 | } |
@@ -385,7 +391,7 @@ nft_match_init(const struct nft_ctx *ctx, const struct nft_expr *expr, | |||
385 | struct xt_match *match = expr->ops->data; | 391 | struct xt_match *match = expr->ops->data; |
386 | struct xt_mtchk_param par; | 392 | struct xt_mtchk_param par; |
387 | size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); | 393 | size_t size = XT_ALIGN(nla_len(tb[NFTA_MATCH_INFO])); |
388 | u8 proto = 0; | 394 | u16 proto = 0; |
389 | bool inv = false; | 395 | bool inv = false; |
390 | union nft_entry e = {}; | 396 | union nft_entry e = {}; |
391 | int ret; | 397 | int ret; |
@@ -625,8 +631,12 @@ nft_match_select_ops(const struct nft_ctx *ctx, | |||
625 | struct xt_match *match = nft_match->ops.data; | 631 | struct xt_match *match = nft_match->ops.data; |
626 | 632 | ||
627 | if (strcmp(match->name, mt_name) == 0 && | 633 | if (strcmp(match->name, mt_name) == 0 && |
628 | match->revision == rev && match->family == family) | 634 | match->revision == rev && match->family == family) { |
635 | if (!try_module_get(match->me)) | ||
636 | return ERR_PTR(-ENOENT); | ||
637 | |||
629 | return &nft_match->ops; | 638 | return &nft_match->ops; |
639 | } | ||
630 | } | 640 | } |
631 | 641 | ||
632 | match = xt_request_find_match(family, mt_name, rev); | 642 | match = xt_request_find_match(family, mt_name, rev); |
@@ -695,8 +705,12 @@ nft_target_select_ops(const struct nft_ctx *ctx, | |||
695 | struct xt_target *target = nft_target->ops.data; | 705 | struct xt_target *target = nft_target->ops.data; |
696 | 706 | ||
697 | if (strcmp(target->name, tg_name) == 0 && | 707 | if (strcmp(target->name, tg_name) == 0 && |
698 | target->revision == rev && target->family == family) | 708 | target->revision == rev && target->family == family) { |
709 | if (!try_module_get(target->me)) | ||
710 | return ERR_PTR(-ENOENT); | ||
711 | |||
699 | return &nft_target->ops; | 712 | return &nft_target->ops; |
713 | } | ||
700 | } | 714 | } |
701 | 715 | ||
702 | target = xt_request_find_target(family, tg_name, rev); | 716 | target = xt_request_find_target(family, tg_name, rev); |
diff --git a/net/netfilter/nft_hash.c b/net/netfilter/nft_hash.c index 61e6c407476a..37c15e674884 100644 --- a/net/netfilter/nft_hash.c +++ b/net/netfilter/nft_hash.c | |||
@@ -153,6 +153,8 @@ static void nft_hash_walk(const struct nft_ctx *ctx, const struct nft_set *set, | |||
153 | iter->err = err; | 153 | iter->err = err; |
154 | goto out; | 154 | goto out; |
155 | } | 155 | } |
156 | |||
157 | continue; | ||
156 | } | 158 | } |
157 | 159 | ||
158 | if (iter->count < iter->skip) | 160 | if (iter->count < iter->skip) |
@@ -192,8 +194,6 @@ static int nft_hash_init(const struct nft_set *set, | |||
192 | .key_offset = offsetof(struct nft_hash_elem, key), | 194 | .key_offset = offsetof(struct nft_hash_elem, key), |
193 | .key_len = set->klen, | 195 | .key_len = set->klen, |
194 | .hashfn = jhash, | 196 | .hashfn = jhash, |
195 | .grow_decision = rht_grow_above_75, | ||
196 | .shrink_decision = rht_shrink_below_30, | ||
197 | }; | 197 | }; |
198 | 198 | ||
199 | return rhashtable_init(priv, ¶ms); | 199 | return rhashtable_init(priv, ¶ms); |
diff --git a/net/netfilter/xt_TPROXY.c b/net/netfilter/xt_TPROXY.c index ef8a926752a9..50e1e5aaf4ce 100644 --- a/net/netfilter/xt_TPROXY.c +++ b/net/netfilter/xt_TPROXY.c | |||
@@ -513,8 +513,8 @@ static int tproxy_tg6_check(const struct xt_tgchk_param *par) | |||
513 | { | 513 | { |
514 | const struct ip6t_ip6 *i = par->entryinfo; | 514 | const struct ip6t_ip6 *i = par->entryinfo; |
515 | 515 | ||
516 | if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) | 516 | if ((i->proto == IPPROTO_TCP || i->proto == IPPROTO_UDP) && |
517 | && !(i->flags & IP6T_INV_PROTO)) | 517 | !(i->invflags & IP6T_INV_PROTO)) |
518 | return 0; | 518 | return 0; |
519 | 519 | ||
520 | pr_info("Can be used only in combination with " | 520 | pr_info("Can be used only in combination with " |
diff --git a/net/netfilter/xt_recent.c b/net/netfilter/xt_recent.c index 30dbe34915ae..45e1b30e4fb2 100644 --- a/net/netfilter/xt_recent.c +++ b/net/netfilter/xt_recent.c | |||
@@ -378,12 +378,11 @@ static int recent_mt_check(const struct xt_mtchk_param *par, | |||
378 | mutex_lock(&recent_mutex); | 378 | mutex_lock(&recent_mutex); |
379 | t = recent_table_lookup(recent_net, info->name); | 379 | t = recent_table_lookup(recent_net, info->name); |
380 | if (t != NULL) { | 380 | if (t != NULL) { |
381 | if (info->hit_count > t->nstamps_max_mask) { | 381 | if (nstamp_mask > t->nstamps_max_mask) { |
382 | pr_info("hitcount (%u) is larger than packets to be remembered (%u) for table %s\n", | 382 | spin_lock_bh(&recent_lock); |
383 | info->hit_count, t->nstamps_max_mask + 1, | 383 | recent_table_flush(t); |
384 | info->name); | 384 | t->nstamps_max_mask = nstamp_mask; |
385 | ret = -EINVAL; | 385 | spin_unlock_bh(&recent_lock); |
386 | goto out; | ||
387 | } | 386 | } |
388 | 387 | ||
389 | t->refcnt++; | 388 | t->refcnt++; |
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c index 1ba67931eb1b..13332dbf291d 100644 --- a/net/netfilter/xt_socket.c +++ b/net/netfilter/xt_socket.c | |||
@@ -243,12 +243,13 @@ static int | |||
243 | extract_icmp6_fields(const struct sk_buff *skb, | 243 | extract_icmp6_fields(const struct sk_buff *skb, |
244 | unsigned int outside_hdrlen, | 244 | unsigned int outside_hdrlen, |
245 | int *protocol, | 245 | int *protocol, |
246 | struct in6_addr **raddr, | 246 | const struct in6_addr **raddr, |
247 | struct in6_addr **laddr, | 247 | const struct in6_addr **laddr, |
248 | __be16 *rport, | 248 | __be16 *rport, |
249 | __be16 *lport) | 249 | __be16 *lport, |
250 | struct ipv6hdr *ipv6_var) | ||
250 | { | 251 | { |
251 | struct ipv6hdr *inside_iph, _inside_iph; | 252 | const struct ipv6hdr *inside_iph; |
252 | struct icmp6hdr *icmph, _icmph; | 253 | struct icmp6hdr *icmph, _icmph; |
253 | __be16 *ports, _ports[2]; | 254 | __be16 *ports, _ports[2]; |
254 | u8 inside_nexthdr; | 255 | u8 inside_nexthdr; |
@@ -263,12 +264,14 @@ extract_icmp6_fields(const struct sk_buff *skb, | |||
263 | if (icmph->icmp6_type & ICMPV6_INFOMSG_MASK) | 264 | if (icmph->icmp6_type & ICMPV6_INFOMSG_MASK) |
264 | return 1; | 265 | return 1; |
265 | 266 | ||
266 | inside_iph = skb_header_pointer(skb, outside_hdrlen + sizeof(_icmph), sizeof(_inside_iph), &_inside_iph); | 267 | inside_iph = skb_header_pointer(skb, outside_hdrlen + sizeof(_icmph), |
268 | sizeof(*ipv6_var), ipv6_var); | ||
267 | if (inside_iph == NULL) | 269 | if (inside_iph == NULL) |
268 | return 1; | 270 | return 1; |
269 | inside_nexthdr = inside_iph->nexthdr; | 271 | inside_nexthdr = inside_iph->nexthdr; |
270 | 272 | ||
271 | inside_hdrlen = ipv6_skip_exthdr(skb, outside_hdrlen + sizeof(_icmph) + sizeof(_inside_iph), | 273 | inside_hdrlen = ipv6_skip_exthdr(skb, outside_hdrlen + sizeof(_icmph) + |
274 | sizeof(*ipv6_var), | ||
272 | &inside_nexthdr, &inside_fragoff); | 275 | &inside_nexthdr, &inside_fragoff); |
273 | if (inside_hdrlen < 0) | 276 | if (inside_hdrlen < 0) |
274 | return 1; /* hjm: Packet has no/incomplete transport layer headers. */ | 277 | return 1; /* hjm: Packet has no/incomplete transport layer headers. */ |
@@ -315,10 +318,10 @@ xt_socket_get_sock_v6(struct net *net, const u8 protocol, | |||
315 | static bool | 318 | static bool |
316 | socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par) | 319 | socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par) |
317 | { | 320 | { |
318 | struct ipv6hdr *iph = ipv6_hdr(skb); | 321 | struct ipv6hdr ipv6_var, *iph = ipv6_hdr(skb); |
319 | struct udphdr _hdr, *hp = NULL; | 322 | struct udphdr _hdr, *hp = NULL; |
320 | struct sock *sk = skb->sk; | 323 | struct sock *sk = skb->sk; |
321 | struct in6_addr *daddr = NULL, *saddr = NULL; | 324 | const struct in6_addr *daddr = NULL, *saddr = NULL; |
322 | __be16 uninitialized_var(dport), uninitialized_var(sport); | 325 | __be16 uninitialized_var(dport), uninitialized_var(sport); |
323 | int thoff = 0, uninitialized_var(tproto); | 326 | int thoff = 0, uninitialized_var(tproto); |
324 | const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; | 327 | const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo; |
@@ -342,7 +345,7 @@ socket_mt6_v1_v2(const struct sk_buff *skb, struct xt_action_param *par) | |||
342 | 345 | ||
343 | } else if (tproto == IPPROTO_ICMPV6) { | 346 | } else if (tproto == IPPROTO_ICMPV6) { |
344 | if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr, | 347 | if (extract_icmp6_fields(skb, thoff, &tproto, &saddr, &daddr, |
345 | &sport, &dport)) | 348 | &sport, &dport, &ipv6_var)) |
346 | return false; | 349 | return false; |
347 | } else { | 350 | } else { |
348 | return false; | 351 | return false; |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 2702673f0f23..05919bf3f670 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -3126,8 +3126,6 @@ static int __init netlink_proto_init(void) | |||
3126 | .key_len = sizeof(u32), /* portid */ | 3126 | .key_len = sizeof(u32), /* portid */ |
3127 | .hashfn = jhash, | 3127 | .hashfn = jhash, |
3128 | .max_shift = 16, /* 64K */ | 3128 | .max_shift = 16, /* 64K */ |
3129 | .grow_decision = rht_grow_above_75, | ||
3130 | .shrink_decision = rht_shrink_below_30, | ||
3131 | }; | 3129 | }; |
3132 | 3130 | ||
3133 | if (err != 0) | 3131 | if (err != 0) |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index ae5e77cdc0ca..5bae7243c577 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -2194,14 +2194,55 @@ static int __net_init ovs_init_net(struct net *net) | |||
2194 | return 0; | 2194 | return 0; |
2195 | } | 2195 | } |
2196 | 2196 | ||
2197 | static void __net_exit ovs_exit_net(struct net *net) | 2197 | static void __net_exit list_vports_from_net(struct net *net, struct net *dnet, |
2198 | struct list_head *head) | ||
2198 | { | 2199 | { |
2199 | struct datapath *dp, *dp_next; | ||
2200 | struct ovs_net *ovs_net = net_generic(net, ovs_net_id); | 2200 | struct ovs_net *ovs_net = net_generic(net, ovs_net_id); |
2201 | struct datapath *dp; | ||
2202 | |||
2203 | list_for_each_entry(dp, &ovs_net->dps, list_node) { | ||
2204 | int i; | ||
2205 | |||
2206 | for (i = 0; i < DP_VPORT_HASH_BUCKETS; i++) { | ||
2207 | struct vport *vport; | ||
2208 | |||
2209 | hlist_for_each_entry(vport, &dp->ports[i], dp_hash_node) { | ||
2210 | struct netdev_vport *netdev_vport; | ||
2211 | |||
2212 | if (vport->ops->type != OVS_VPORT_TYPE_INTERNAL) | ||
2213 | continue; | ||
2214 | |||
2215 | netdev_vport = netdev_vport_priv(vport); | ||
2216 | if (dev_net(netdev_vport->dev) == dnet) | ||
2217 | list_add(&vport->detach_list, head); | ||
2218 | } | ||
2219 | } | ||
2220 | } | ||
2221 | } | ||
2222 | |||
2223 | static void __net_exit ovs_exit_net(struct net *dnet) | ||
2224 | { | ||
2225 | struct datapath *dp, *dp_next; | ||
2226 | struct ovs_net *ovs_net = net_generic(dnet, ovs_net_id); | ||
2227 | struct vport *vport, *vport_next; | ||
2228 | struct net *net; | ||
2229 | LIST_HEAD(head); | ||
2201 | 2230 | ||
2202 | ovs_lock(); | 2231 | ovs_lock(); |
2203 | list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node) | 2232 | list_for_each_entry_safe(dp, dp_next, &ovs_net->dps, list_node) |
2204 | __dp_destroy(dp); | 2233 | __dp_destroy(dp); |
2234 | |||
2235 | rtnl_lock(); | ||
2236 | for_each_net(net) | ||
2237 | list_vports_from_net(net, dnet, &head); | ||
2238 | rtnl_unlock(); | ||
2239 | |||
2240 | /* Detach all vports from given namespace. */ | ||
2241 | list_for_each_entry_safe(vport, vport_next, &head, detach_list) { | ||
2242 | list_del(&vport->detach_list); | ||
2243 | ovs_dp_detach_port(vport); | ||
2244 | } | ||
2245 | |||
2205 | ovs_unlock(); | 2246 | ovs_unlock(); |
2206 | 2247 | ||
2207 | cancel_work_sync(&ovs_net->dp_notify_work); | 2248 | cancel_work_sync(&ovs_net->dp_notify_work); |
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 216f20b90aa5..22b18c145c92 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -2253,14 +2253,20 @@ static int masked_set_action_to_set_action_attr(const struct nlattr *a, | |||
2253 | struct sk_buff *skb) | 2253 | struct sk_buff *skb) |
2254 | { | 2254 | { |
2255 | const struct nlattr *ovs_key = nla_data(a); | 2255 | const struct nlattr *ovs_key = nla_data(a); |
2256 | struct nlattr *nla; | ||
2256 | size_t key_len = nla_len(ovs_key) / 2; | 2257 | size_t key_len = nla_len(ovs_key) / 2; |
2257 | 2258 | ||
2258 | /* Revert the conversion we did from a non-masked set action to | 2259 | /* Revert the conversion we did from a non-masked set action to |
2259 | * masked set action. | 2260 | * masked set action. |
2260 | */ | 2261 | */ |
2261 | if (nla_put(skb, OVS_ACTION_ATTR_SET, nla_len(a) - key_len, ovs_key)) | 2262 | nla = nla_nest_start(skb, OVS_ACTION_ATTR_SET); |
2263 | if (!nla) | ||
2262 | return -EMSGSIZE; | 2264 | return -EMSGSIZE; |
2263 | 2265 | ||
2266 | if (nla_put(skb, nla_type(ovs_key), key_len, nla_data(ovs_key))) | ||
2267 | return -EMSGSIZE; | ||
2268 | |||
2269 | nla_nest_end(skb, nla); | ||
2264 | return 0; | 2270 | return 0; |
2265 | } | 2271 | } |
2266 | 2272 | ||
diff --git a/net/openvswitch/vport.c b/net/openvswitch/vport.c index ec2954ffc690..067a3fff1d2c 100644 --- a/net/openvswitch/vport.c +++ b/net/openvswitch/vport.c | |||
@@ -274,10 +274,8 @@ void ovs_vport_del(struct vport *vport) | |||
274 | ASSERT_OVSL(); | 274 | ASSERT_OVSL(); |
275 | 275 | ||
276 | hlist_del_rcu(&vport->hash_node); | 276 | hlist_del_rcu(&vport->hash_node); |
277 | |||
278 | vport->ops->destroy(vport); | ||
279 | |||
280 | module_put(vport->ops->owner); | 277 | module_put(vport->ops->owner); |
278 | vport->ops->destroy(vport); | ||
281 | } | 279 | } |
282 | 280 | ||
283 | /** | 281 | /** |
diff --git a/net/openvswitch/vport.h b/net/openvswitch/vport.h index f8ae295fb001..bc85331a6c60 100644 --- a/net/openvswitch/vport.h +++ b/net/openvswitch/vport.h | |||
@@ -103,6 +103,7 @@ struct vport_portids { | |||
103 | * @ops: Class structure. | 103 | * @ops: Class structure. |
104 | * @percpu_stats: Points to per-CPU statistics used and maintained by vport | 104 | * @percpu_stats: Points to per-CPU statistics used and maintained by vport |
105 | * @err_stats: Points to error statistics used and maintained by vport | 105 | * @err_stats: Points to error statistics used and maintained by vport |
106 | * @detach_list: list used for detaching vport in net-exit call. | ||
106 | */ | 107 | */ |
107 | struct vport { | 108 | struct vport { |
108 | struct rcu_head rcu; | 109 | struct rcu_head rcu; |
@@ -117,6 +118,7 @@ struct vport { | |||
117 | struct pcpu_sw_netstats __percpu *percpu_stats; | 118 | struct pcpu_sw_netstats __percpu *percpu_stats; |
118 | 119 | ||
119 | struct vport_err_stats err_stats; | 120 | struct vport_err_stats err_stats; |
121 | struct list_head detach_list; | ||
120 | }; | 122 | }; |
121 | 123 | ||
122 | /** | 124 | /** |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9c28cec1a083..f8db7064d81c 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -698,6 +698,10 @@ static void prb_retire_rx_blk_timer_expired(unsigned long data) | |||
698 | 698 | ||
699 | if (pkc->last_kactive_blk_num == pkc->kactive_blk_num) { | 699 | if (pkc->last_kactive_blk_num == pkc->kactive_blk_num) { |
700 | if (!frozen) { | 700 | if (!frozen) { |
701 | if (!BLOCK_NUM_PKTS(pbd)) { | ||
702 | /* An empty block. Just refresh the timer. */ | ||
703 | goto refresh_timer; | ||
704 | } | ||
701 | prb_retire_current_block(pkc, po, TP_STATUS_BLK_TMO); | 705 | prb_retire_current_block(pkc, po, TP_STATUS_BLK_TMO); |
702 | if (!prb_dispatch_next_block(pkc, po)) | 706 | if (!prb_dispatch_next_block(pkc, po)) |
703 | goto refresh_timer; | 707 | goto refresh_timer; |
@@ -798,7 +802,11 @@ static void prb_close_block(struct tpacket_kbdq_core *pkc1, | |||
798 | h1->ts_last_pkt.ts_sec = last_pkt->tp_sec; | 802 | h1->ts_last_pkt.ts_sec = last_pkt->tp_sec; |
799 | h1->ts_last_pkt.ts_nsec = last_pkt->tp_nsec; | 803 | h1->ts_last_pkt.ts_nsec = last_pkt->tp_nsec; |
800 | } else { | 804 | } else { |
801 | /* Ok, we tmo'd - so get the current time */ | 805 | /* Ok, we tmo'd - so get the current time. |
806 | * | ||
807 | * It shouldn't really happen as we don't close empty | ||
808 | * blocks. See prb_retire_rx_blk_timer_expired(). | ||
809 | */ | ||
802 | struct timespec ts; | 810 | struct timespec ts; |
803 | getnstimeofday(&ts); | 811 | getnstimeofday(&ts); |
804 | h1->ts_last_pkt.ts_sec = ts.tv_sec; | 812 | h1->ts_last_pkt.ts_sec = ts.tv_sec; |
@@ -1349,14 +1357,14 @@ static int packet_rcv_fanout(struct sk_buff *skb, struct net_device *dev, | |||
1349 | return 0; | 1357 | return 0; |
1350 | } | 1358 | } |
1351 | 1359 | ||
1360 | if (fanout_has_flag(f, PACKET_FANOUT_FLAG_DEFRAG)) { | ||
1361 | skb = ip_check_defrag(skb, IP_DEFRAG_AF_PACKET); | ||
1362 | if (!skb) | ||
1363 | return 0; | ||
1364 | } | ||
1352 | switch (f->type) { | 1365 | switch (f->type) { |
1353 | case PACKET_FANOUT_HASH: | 1366 | case PACKET_FANOUT_HASH: |
1354 | default: | 1367 | default: |
1355 | if (fanout_has_flag(f, PACKET_FANOUT_FLAG_DEFRAG)) { | ||
1356 | skb = ip_check_defrag(skb, IP_DEFRAG_AF_PACKET); | ||
1357 | if (!skb) | ||
1358 | return 0; | ||
1359 | } | ||
1360 | idx = fanout_demux_hash(f, skb, num); | 1368 | idx = fanout_demux_hash(f, skb, num); |
1361 | break; | 1369 | break; |
1362 | case PACKET_FANOUT_LB: | 1370 | case PACKET_FANOUT_LB: |
@@ -3115,11 +3123,18 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i, | |||
3115 | return 0; | 3123 | return 0; |
3116 | } | 3124 | } |
3117 | 3125 | ||
3118 | 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) | ||
3119 | { | 3128 | { |
3120 | for ( ; i; i = i->next) { | 3129 | struct packet_mclist *ml; |
3121 | if (i->ifindex == dev->ifindex) | 3130 | |
3122 | 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; | ||
3123 | } | 3138 | } |
3124 | } | 3139 | } |
3125 | 3140 | ||
@@ -3196,12 +3211,11 @@ static int packet_mc_drop(struct sock *sk, struct packet_mreq_max *mreq) | |||
3196 | packet_dev_mc(dev, ml, -1); | 3211 | packet_dev_mc(dev, ml, -1); |
3197 | kfree(ml); | 3212 | kfree(ml); |
3198 | } | 3213 | } |
3199 | rtnl_unlock(); | 3214 | break; |
3200 | return 0; | ||
3201 | } | 3215 | } |
3202 | } | 3216 | } |
3203 | rtnl_unlock(); | 3217 | rtnl_unlock(); |
3204 | return -EADDRNOTAVAIL; | 3218 | return 0; |
3205 | } | 3219 | } |
3206 | 3220 | ||
3207 | static void packet_flush_mclist(struct sock *sk) | 3221 | static void packet_flush_mclist(struct sock *sk) |
@@ -3551,7 +3565,7 @@ static int packet_notifier(struct notifier_block *this, | |||
3551 | switch (msg) { | 3565 | switch (msg) { |
3552 | case NETDEV_UNREGISTER: | 3566 | case NETDEV_UNREGISTER: |
3553 | if (po->mclist) | 3567 | if (po->mclist) |
3554 | packet_dev_mclist(dev, po->mclist, -1); | 3568 | packet_dev_mclist_delete(dev, &po->mclist); |
3555 | /* fallthrough */ | 3569 | /* fallthrough */ |
3556 | 3570 | ||
3557 | 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-ack.c b/net/rxrpc/ar-ack.c index c6be17a959a6..e0547f521f20 100644 --- a/net/rxrpc/ar-ack.c +++ b/net/rxrpc/ar-ack.c | |||
@@ -218,7 +218,8 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
218 | struct rxrpc_header *hdr; | 218 | struct rxrpc_header *hdr; |
219 | struct sk_buff *txb; | 219 | struct sk_buff *txb; |
220 | unsigned long *p_txb, resend_at; | 220 | unsigned long *p_txb, resend_at; |
221 | int loop, stop; | 221 | bool stop; |
222 | int loop; | ||
222 | u8 resend; | 223 | u8 resend; |
223 | 224 | ||
224 | _enter("{%d,%d,%d,%d},", | 225 | _enter("{%d,%d,%d,%d},", |
@@ -226,7 +227,7 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
226 | atomic_read(&call->sequence), | 227 | atomic_read(&call->sequence), |
227 | CIRC_CNT(call->acks_head, call->acks_tail, call->acks_winsz)); | 228 | CIRC_CNT(call->acks_head, call->acks_tail, call->acks_winsz)); |
228 | 229 | ||
229 | stop = 0; | 230 | stop = false; |
230 | resend = 0; | 231 | resend = 0; |
231 | resend_at = 0; | 232 | resend_at = 0; |
232 | 233 | ||
@@ -255,11 +256,11 @@ static void rxrpc_resend(struct rxrpc_call *call) | |||
255 | _proto("Tx DATA %%%u { #%d }", | 256 | _proto("Tx DATA %%%u { #%d }", |
256 | ntohl(sp->hdr.serial), ntohl(sp->hdr.seq)); | 257 | ntohl(sp->hdr.serial), ntohl(sp->hdr.seq)); |
257 | if (rxrpc_send_packet(call->conn->trans, txb) < 0) { | 258 | if (rxrpc_send_packet(call->conn->trans, txb) < 0) { |
258 | stop = 0; | 259 | stop = true; |
259 | sp->resend_at = jiffies + 3; | 260 | sp->resend_at = jiffies + 3; |
260 | } else { | 261 | } else { |
261 | sp->resend_at = | 262 | sp->resend_at = |
262 | jiffies + rxrpc_resend_timeout * HZ; | 263 | jiffies + rxrpc_resend_timeout; |
263 | } | 264 | } |
264 | } | 265 | } |
265 | 266 | ||
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/sched/ematch.c b/net/sched/ematch.c index 6742200b1307..fbb7ebfc58c6 100644 --- a/net/sched/ematch.c +++ b/net/sched/ematch.c | |||
@@ -228,6 +228,7 @@ static int tcf_em_validate(struct tcf_proto *tp, | |||
228 | * to replay the request. | 228 | * to replay the request. |
229 | */ | 229 | */ |
230 | module_put(em->ops->owner); | 230 | module_put(em->ops->owner); |
231 | em->ops = NULL; | ||
231 | err = -EAGAIN; | 232 | err = -EAGAIN; |
232 | } | 233 | } |
233 | #endif | 234 | #endif |
diff --git a/net/socket.c b/net/socket.c index bbedbfcb42c2..245330ca0015 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1702,6 +1702,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, | |||
1702 | 1702 | ||
1703 | if (len > INT_MAX) | 1703 | if (len > INT_MAX) |
1704 | len = INT_MAX; | 1704 | len = INT_MAX; |
1705 | if (unlikely(!access_ok(VERIFY_READ, buff, len))) | ||
1706 | return -EFAULT; | ||
1705 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | 1707 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1706 | if (!sock) | 1708 | if (!sock) |
1707 | goto out; | 1709 | goto out; |
@@ -1760,6 +1762,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, | |||
1760 | 1762 | ||
1761 | if (size > INT_MAX) | 1763 | if (size > INT_MAX) |
1762 | size = INT_MAX; | 1764 | size = INT_MAX; |
1765 | if (unlikely(!access_ok(VERIFY_WRITE, ubuf, size))) | ||
1766 | return -EFAULT; | ||
1763 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | 1767 | sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1764 | if (!sock) | 1768 | if (!sock) |
1765 | goto out; | 1769 | goto out; |
diff --git a/net/sunrpc/auth_gss/gss_rpc_upcall.c b/net/sunrpc/auth_gss/gss_rpc_upcall.c index abbb7dcd1689..59eeed43eda2 100644 --- a/net/sunrpc/auth_gss/gss_rpc_upcall.c +++ b/net/sunrpc/auth_gss/gss_rpc_upcall.c | |||
@@ -217,6 +217,8 @@ static void gssp_free_receive_pages(struct gssx_arg_accept_sec_context *arg) | |||
217 | 217 | ||
218 | for (i = 0; i < arg->npages && arg->pages[i]; i++) | 218 | for (i = 0; i < arg->npages && arg->pages[i]; i++) |
219 | __free_page(arg->pages[i]); | 219 | __free_page(arg->pages[i]); |
220 | |||
221 | kfree(arg->pages); | ||
220 | } | 222 | } |
221 | 223 | ||
222 | static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) | 224 | static int gssp_alloc_receive_pages(struct gssx_arg_accept_sec_context *arg) |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 224a82f24d3c..1095be9c80ab 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -463,6 +463,8 @@ static int rsc_parse(struct cache_detail *cd, | |||
463 | /* number of additional gid's */ | 463 | /* number of additional gid's */ |
464 | if (get_int(&mesg, &N)) | 464 | if (get_int(&mesg, &N)) |
465 | goto out; | 465 | goto out; |
466 | if (N < 0 || N > NGROUPS_MAX) | ||
467 | goto out; | ||
466 | status = -ENOMEM; | 468 | status = -ENOMEM; |
467 | rsci.cred.cr_group_info = groups_alloc(N); | 469 | rsci.cred.cr_group_info = groups_alloc(N); |
468 | if (rsci.cred.cr_group_info == NULL) | 470 | if (rsci.cred.cr_group_info == NULL) |
diff --git a/net/sunrpc/cache.c b/net/sunrpc/cache.c index 33fb105d4352..5199bb1a017e 100644 --- a/net/sunrpc/cache.c +++ b/net/sunrpc/cache.c | |||
@@ -921,7 +921,7 @@ static unsigned int cache_poll(struct file *filp, poll_table *wait, | |||
921 | poll_wait(filp, &queue_wait, wait); | 921 | poll_wait(filp, &queue_wait, wait); |
922 | 922 | ||
923 | /* alway allow write */ | 923 | /* alway allow write */ |
924 | mask = POLL_OUT | POLLWRNORM; | 924 | mask = POLLOUT | POLLWRNORM; |
925 | 925 | ||
926 | if (!rp) | 926 | if (!rp) |
927 | return mask; | 927 | return mask; |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 612aa73bbc60..e6ce1517367f 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -303,9 +303,7 @@ static int rpc_client_register(struct rpc_clnt *clnt, | |||
303 | struct super_block *pipefs_sb; | 303 | struct super_block *pipefs_sb; |
304 | int err; | 304 | int err; |
305 | 305 | ||
306 | err = rpc_clnt_debugfs_register(clnt); | 306 | rpc_clnt_debugfs_register(clnt); |
307 | if (err) | ||
308 | return err; | ||
309 | 307 | ||
310 | pipefs_sb = rpc_get_sb_net(net); | 308 | pipefs_sb = rpc_get_sb_net(net); |
311 | if (pipefs_sb) { | 309 | if (pipefs_sb) { |
diff --git a/net/sunrpc/debugfs.c b/net/sunrpc/debugfs.c index e811f390f9f6..82962f7e6e88 100644 --- a/net/sunrpc/debugfs.c +++ b/net/sunrpc/debugfs.c | |||
@@ -129,48 +129,52 @@ static const struct file_operations tasks_fops = { | |||
129 | .release = tasks_release, | 129 | .release = tasks_release, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | int | 132 | void |
133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) | 133 | rpc_clnt_debugfs_register(struct rpc_clnt *clnt) |
134 | { | 134 | { |
135 | int len, err; | 135 | int len; |
136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ | 136 | char name[24]; /* enough for "../../rpc_xprt/ + 8 hex digits + NULL */ |
137 | struct rpc_xprt *xprt; | ||
137 | 138 | ||
138 | /* Already registered? */ | 139 | /* Already registered? */ |
139 | if (clnt->cl_debugfs) | 140 | if (clnt->cl_debugfs || !rpc_clnt_dir) |
140 | return 0; | 141 | return; |
141 | 142 | ||
142 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); | 143 | len = snprintf(name, sizeof(name), "%x", clnt->cl_clid); |
143 | if (len >= sizeof(name)) | 144 | if (len >= sizeof(name)) |
144 | return -EINVAL; | 145 | return; |
145 | 146 | ||
146 | /* make the per-client dir */ | 147 | /* make the per-client dir */ |
147 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); | 148 | clnt->cl_debugfs = debugfs_create_dir(name, rpc_clnt_dir); |
148 | if (!clnt->cl_debugfs) | 149 | if (!clnt->cl_debugfs) |
149 | return -ENOMEM; | 150 | return; |
150 | 151 | ||
151 | /* make tasks file */ | 152 | /* make tasks file */ |
152 | err = -ENOMEM; | ||
153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, | 153 | if (!debugfs_create_file("tasks", S_IFREG | S_IRUSR, clnt->cl_debugfs, |
154 | clnt, &tasks_fops)) | 154 | clnt, &tasks_fops)) |
155 | goto out_err; | 155 | goto out_err; |
156 | 156 | ||
157 | err = -EINVAL; | ||
158 | rcu_read_lock(); | 157 | rcu_read_lock(); |
158 | xprt = rcu_dereference(clnt->cl_xprt); | ||
159 | /* no "debugfs" dentry? Don't bother with the symlink. */ | ||
160 | if (!xprt->debugfs) { | ||
161 | rcu_read_unlock(); | ||
162 | return; | ||
163 | } | ||
159 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", | 164 | len = snprintf(name, sizeof(name), "../../rpc_xprt/%s", |
160 | rcu_dereference(clnt->cl_xprt)->debugfs->d_name.name); | 165 | xprt->debugfs->d_name.name); |
161 | rcu_read_unlock(); | 166 | rcu_read_unlock(); |
167 | |||
162 | if (len >= sizeof(name)) | 168 | if (len >= sizeof(name)) |
163 | goto out_err; | 169 | goto out_err; |
164 | 170 | ||
165 | err = -ENOMEM; | ||
166 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) | 171 | if (!debugfs_create_symlink("xprt", clnt->cl_debugfs, name)) |
167 | goto out_err; | 172 | goto out_err; |
168 | 173 | ||
169 | return 0; | 174 | return; |
170 | out_err: | 175 | out_err: |
171 | debugfs_remove_recursive(clnt->cl_debugfs); | 176 | debugfs_remove_recursive(clnt->cl_debugfs); |
172 | clnt->cl_debugfs = NULL; | 177 | clnt->cl_debugfs = NULL; |
173 | return err; | ||
174 | } | 178 | } |
175 | 179 | ||
176 | void | 180 | void |
@@ -226,33 +230,33 @@ static const struct file_operations xprt_info_fops = { | |||
226 | .release = xprt_info_release, | 230 | .release = xprt_info_release, |
227 | }; | 231 | }; |
228 | 232 | ||
229 | int | 233 | void |
230 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) | 234 | rpc_xprt_debugfs_register(struct rpc_xprt *xprt) |
231 | { | 235 | { |
232 | int len, id; | 236 | int len, id; |
233 | static atomic_t cur_id; | 237 | static atomic_t cur_id; |
234 | char name[9]; /* 8 hex digits + NULL term */ | 238 | char name[9]; /* 8 hex digits + NULL term */ |
235 | 239 | ||
240 | if (!rpc_xprt_dir) | ||
241 | return; | ||
242 | |||
236 | id = (unsigned int)atomic_inc_return(&cur_id); | 243 | id = (unsigned int)atomic_inc_return(&cur_id); |
237 | 244 | ||
238 | len = snprintf(name, sizeof(name), "%x", id); | 245 | len = snprintf(name, sizeof(name), "%x", id); |
239 | if (len >= sizeof(name)) | 246 | if (len >= sizeof(name)) |
240 | return -EINVAL; | 247 | return; |
241 | 248 | ||
242 | /* make the per-client dir */ | 249 | /* make the per-client dir */ |
243 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); | 250 | xprt->debugfs = debugfs_create_dir(name, rpc_xprt_dir); |
244 | if (!xprt->debugfs) | 251 | if (!xprt->debugfs) |
245 | return -ENOMEM; | 252 | return; |
246 | 253 | ||
247 | /* make tasks file */ | 254 | /* make tasks file */ |
248 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, | 255 | if (!debugfs_create_file("info", S_IFREG | S_IRUSR, xprt->debugfs, |
249 | xprt, &xprt_info_fops)) { | 256 | xprt, &xprt_info_fops)) { |
250 | debugfs_remove_recursive(xprt->debugfs); | 257 | debugfs_remove_recursive(xprt->debugfs); |
251 | xprt->debugfs = NULL; | 258 | xprt->debugfs = NULL; |
252 | return -ENOMEM; | ||
253 | } | 259 | } |
254 | |||
255 | return 0; | ||
256 | } | 260 | } |
257 | 261 | ||
258 | void | 262 | void |
@@ -266,14 +270,17 @@ void __exit | |||
266 | sunrpc_debugfs_exit(void) | 270 | sunrpc_debugfs_exit(void) |
267 | { | 271 | { |
268 | debugfs_remove_recursive(topdir); | 272 | debugfs_remove_recursive(topdir); |
273 | topdir = NULL; | ||
274 | rpc_clnt_dir = NULL; | ||
275 | rpc_xprt_dir = NULL; | ||
269 | } | 276 | } |
270 | 277 | ||
271 | int __init | 278 | void __init |
272 | sunrpc_debugfs_init(void) | 279 | sunrpc_debugfs_init(void) |
273 | { | 280 | { |
274 | topdir = debugfs_create_dir("sunrpc", NULL); | 281 | topdir = debugfs_create_dir("sunrpc", NULL); |
275 | if (!topdir) | 282 | if (!topdir) |
276 | goto out; | 283 | return; |
277 | 284 | ||
278 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); | 285 | rpc_clnt_dir = debugfs_create_dir("rpc_clnt", topdir); |
279 | if (!rpc_clnt_dir) | 286 | if (!rpc_clnt_dir) |
@@ -283,10 +290,9 @@ sunrpc_debugfs_init(void) | |||
283 | if (!rpc_xprt_dir) | 290 | if (!rpc_xprt_dir) |
284 | goto out_remove; | 291 | goto out_remove; |
285 | 292 | ||
286 | return 0; | 293 | return; |
287 | out_remove: | 294 | out_remove: |
288 | debugfs_remove_recursive(topdir); | 295 | debugfs_remove_recursive(topdir); |
289 | topdir = NULL; | 296 | topdir = NULL; |
290 | out: | 297 | rpc_clnt_dir = NULL; |
291 | return -ENOMEM; | ||
292 | } | 298 | } |
diff --git a/net/sunrpc/sunrpc_syms.c b/net/sunrpc/sunrpc_syms.c index e37fbed87956..ee5d3d253102 100644 --- a/net/sunrpc/sunrpc_syms.c +++ b/net/sunrpc/sunrpc_syms.c | |||
@@ -98,10 +98,7 @@ init_sunrpc(void) | |||
98 | if (err) | 98 | if (err) |
99 | goto out4; | 99 | goto out4; |
100 | 100 | ||
101 | err = sunrpc_debugfs_init(); | 101 | sunrpc_debugfs_init(); |
102 | if (err) | ||
103 | goto out5; | ||
104 | |||
105 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) | 102 | #if IS_ENABLED(CONFIG_SUNRPC_DEBUG) |
106 | rpc_register_sysctl(); | 103 | rpc_register_sysctl(); |
107 | #endif | 104 | #endif |
@@ -109,8 +106,6 @@ init_sunrpc(void) | |||
109 | init_socket_xprt(); /* clnt sock transport */ | 106 | init_socket_xprt(); /* clnt sock transport */ |
110 | return 0; | 107 | return 0; |
111 | 108 | ||
112 | out5: | ||
113 | unregister_rpc_pipefs(); | ||
114 | out4: | 109 | out4: |
115 | unregister_pernet_subsys(&sunrpc_net_ops); | 110 | unregister_pernet_subsys(&sunrpc_net_ops); |
116 | out3: | 111 | out3: |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index e3015aede0d9..9949722d99ce 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -1331,7 +1331,6 @@ static void xprt_init(struct rpc_xprt *xprt, struct net *net) | |||
1331 | */ | 1331 | */ |
1332 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) | 1332 | struct rpc_xprt *xprt_create_transport(struct xprt_create *args) |
1333 | { | 1333 | { |
1334 | int err; | ||
1335 | struct rpc_xprt *xprt; | 1334 | struct rpc_xprt *xprt; |
1336 | struct xprt_class *t; | 1335 | struct xprt_class *t; |
1337 | 1336 | ||
@@ -1372,11 +1371,7 @@ found: | |||
1372 | return ERR_PTR(-ENOMEM); | 1371 | return ERR_PTR(-ENOMEM); |
1373 | } | 1372 | } |
1374 | 1373 | ||
1375 | err = rpc_xprt_debugfs_register(xprt); | 1374 | rpc_xprt_debugfs_register(xprt); |
1376 | if (err) { | ||
1377 | xprt_destroy(xprt); | ||
1378 | return ERR_PTR(err); | ||
1379 | } | ||
1380 | 1375 | ||
1381 | dprintk("RPC: created transport %p with %u slots\n", xprt, | 1376 | dprintk("RPC: created transport %p with %u slots\n", xprt, |
1382 | xprt->max_reqs); | 1377 | xprt->max_reqs); |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index 7e9acd9361c5..91ffde82fa0c 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -738,8 +738,9 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep) | |||
738 | struct rpc_xprt *xprt = rep->rr_xprt; | 738 | struct rpc_xprt *xprt = rep->rr_xprt; |
739 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); | 739 | struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt); |
740 | __be32 *iptr; | 740 | __be32 *iptr; |
741 | int credits, rdmalen, status; | 741 | int rdmalen, status; |
742 | unsigned long cwnd; | 742 | unsigned long cwnd; |
743 | u32 credits; | ||
743 | 744 | ||
744 | /* Check status. If bad, signal disconnect and return rep to pool */ | 745 | /* Check status. If bad, signal disconnect and return rep to pool */ |
745 | if (rep->rr_len == ~0U) { | 746 | if (rep->rr_len == ~0U) { |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index d1b70397c60f..0a16fb6f0885 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -285,7 +285,7 @@ rpcr_to_rdmar(struct rpc_rqst *rqst) | |||
285 | */ | 285 | */ |
286 | struct rpcrdma_buffer { | 286 | struct rpcrdma_buffer { |
287 | spinlock_t rb_lock; /* protects indexes */ | 287 | spinlock_t rb_lock; /* protects indexes */ |
288 | int rb_max_requests;/* client max requests */ | 288 | u32 rb_max_requests;/* client max requests */ |
289 | struct list_head rb_mws; /* optional memory windows/fmrs/frmrs */ | 289 | struct list_head rb_mws; /* optional memory windows/fmrs/frmrs */ |
290 | struct list_head rb_all; | 290 | struct list_head rb_all; |
291 | int rb_send_index; | 291 | int rb_send_index; |
diff --git a/net/tipc/core.c b/net/tipc/core.c index 935205e6bcfe..be1c9fa60b09 100644 --- a/net/tipc/core.c +++ b/net/tipc/core.c | |||
@@ -152,11 +152,11 @@ out_netlink: | |||
152 | static void __exit tipc_exit(void) | 152 | static void __exit tipc_exit(void) |
153 | { | 153 | { |
154 | tipc_bearer_cleanup(); | 154 | tipc_bearer_cleanup(); |
155 | unregister_pernet_subsys(&tipc_net_ops); | ||
155 | tipc_netlink_stop(); | 156 | tipc_netlink_stop(); |
156 | tipc_netlink_compat_stop(); | 157 | tipc_netlink_compat_stop(); |
157 | tipc_socket_stop(); | 158 | tipc_socket_stop(); |
158 | tipc_unregister_sysctl(); | 159 | tipc_unregister_sysctl(); |
159 | unregister_pernet_subsys(&tipc_net_ops); | ||
160 | 160 | ||
161 | pr_info("Deactivated\n"); | 161 | pr_info("Deactivated\n"); |
162 | } | 162 | } |
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/tipc/socket.c b/net/tipc/socket.c index f73e975af80b..b4d4467d0bb0 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -2364,8 +2364,6 @@ int tipc_sk_rht_init(struct net *net) | |||
2364 | .hashfn = jhash, | 2364 | .hashfn = jhash, |
2365 | .max_shift = 20, /* 1M */ | 2365 | .max_shift = 20, /* 1M */ |
2366 | .min_shift = 8, /* 256 */ | 2366 | .min_shift = 8, /* 256 */ |
2367 | .grow_decision = rht_grow_above_75, | ||
2368 | .shrink_decision = rht_shrink_below_30, | ||
2369 | }; | 2367 | }; |
2370 | 2368 | ||
2371 | return rhashtable_init(&tn->sk_rht, &rht_params); | 2369 | return rhashtable_init(&tn->sk_rht, &rht_params); |
diff --git a/net/wireless/core.c b/net/wireless/core.c index 3af0ecf1cc16..2a0bbd22854b 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -1199,6 +1199,7 @@ out_fail_wq: | |||
1199 | regulatory_exit(); | 1199 | regulatory_exit(); |
1200 | out_fail_reg: | 1200 | out_fail_reg: |
1201 | debugfs_remove(ieee80211_debugfs_dir); | 1201 | debugfs_remove(ieee80211_debugfs_dir); |
1202 | nl80211_exit(); | ||
1202 | out_fail_nl80211: | 1203 | out_fail_nl80211: |
1203 | unregister_netdevice_notifier(&cfg80211_netdev_notifier); | 1204 | unregister_netdevice_notifier(&cfg80211_netdev_notifier); |
1204 | out_fail_notifier: | 1205 | out_fail_notifier: |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index d78fd8b54515..b6f84f6a2a09 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2654,10 +2654,6 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2654 | return err; | 2654 | return err; |
2655 | } | 2655 | } |
2656 | 2656 | ||
2657 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
2658 | if (!msg) | ||
2659 | return -ENOMEM; | ||
2660 | |||
2661 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? | 2657 | err = parse_monitor_flags(type == NL80211_IFTYPE_MONITOR ? |
2662 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, | 2658 | info->attrs[NL80211_ATTR_MNTR_FLAGS] : NULL, |
2663 | &flags); | 2659 | &flags); |
@@ -2666,6 +2662,10 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info) | |||
2666 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) | 2662 | !(rdev->wiphy.features & NL80211_FEATURE_ACTIVE_MONITOR)) |
2667 | return -EOPNOTSUPP; | 2663 | return -EOPNOTSUPP; |
2668 | 2664 | ||
2665 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
2666 | if (!msg) | ||
2667 | return -ENOMEM; | ||
2668 | |||
2669 | wdev = rdev_add_virtual_intf(rdev, | 2669 | wdev = rdev_add_virtual_intf(rdev, |
2670 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), | 2670 | nla_data(info->attrs[NL80211_ATTR_IFNAME]), |
2671 | type, err ? NULL : &flags, ¶ms); | 2671 | type, err ? NULL : &flags, ¶ms); |
@@ -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 | ||
@@ -12528,9 +12538,7 @@ static int cfg80211_net_detect_results(struct sk_buff *msg, | |||
12528 | } | 12538 | } |
12529 | 12539 | ||
12530 | for (j = 0; j < match->n_channels; j++) { | 12540 | for (j = 0; j < match->n_channels; j++) { |
12531 | if (nla_put_u32(msg, | 12541 | if (nla_put_u32(msg, j, match->channels[j])) { |
12532 | NL80211_ATTR_WIPHY_FREQ, | ||
12533 | match->channels[j])) { | ||
12534 | nla_nest_cancel(msg, nl_freqs); | 12542 | nla_nest_cancel(msg, nl_freqs); |
12535 | nla_nest_cancel(msg, nl_match); | 12543 | nla_nest_cancel(msg, nl_match); |
12536 | goto out; | 12544 | goto out; |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index b586d0dcb09e..48dfc7b4e981 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -228,7 +228,7 @@ static DECLARE_DELAYED_WORK(reg_timeout, reg_timeout_work); | |||
228 | 228 | ||
229 | /* We keep a static world regulatory domain in case of the absence of CRDA */ | 229 | /* We keep a static world regulatory domain in case of the absence of CRDA */ |
230 | static const struct ieee80211_regdomain world_regdom = { | 230 | static const struct ieee80211_regdomain world_regdom = { |
231 | .n_reg_rules = 6, | 231 | .n_reg_rules = 8, |
232 | .alpha2 = "00", | 232 | .alpha2 = "00", |
233 | .reg_rules = { | 233 | .reg_rules = { |
234 | /* IEEE 802.11b/g, channels 1..11 */ | 234 | /* IEEE 802.11b/g, channels 1..11 */ |
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); |