diff options
author | Radim Krčmář <rkrcmar@redhat.com> | 2018-02-01 09:04:17 -0500 |
---|---|---|
committer | Radim Krčmář <rkrcmar@redhat.com> | 2018-02-01 09:04:17 -0500 |
commit | 7bf14c28ee776be567855bd39ed8ff795ea19f55 (patch) | |
tree | 6113748c673e85fccc2c56c050697789c00c6bc2 /net | |
parent | 87cedc6be55954c6efd6eca2e694132513f65a2a (diff) | |
parent | 5fa4ec9cb2e6679e2f828033726f758ea314b9c5 (diff) |
Merge branch 'x86/hyperv' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Topic branch for stable KVM clockource under Hyper-V.
Thanks to Christoffer Dall for resolving the ARM conflict.
Diffstat (limited to 'net')
145 files changed, 1311 insertions, 692 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 8dfdd94e430f..bad01b14a4ad 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -111,12 +111,7 @@ void unregister_vlan_dev(struct net_device *dev, struct list_head *head) | |||
111 | vlan_gvrp_uninit_applicant(real_dev); | 111 | vlan_gvrp_uninit_applicant(real_dev); |
112 | } | 112 | } |
113 | 113 | ||
114 | /* Take it out of our own structures, but be sure to interlock with | 114 | vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); |
115 | * HW accelerating devices or SW vlan input packet processing if | ||
116 | * VLAN is not 0 (leave it there for 802.1p). | ||
117 | */ | ||
118 | if (vlan_id) | ||
119 | vlan_vid_del(real_dev, vlan->vlan_proto, vlan_id); | ||
120 | 115 | ||
121 | /* Get rid of the vlan's reference to real_dev */ | 116 | /* Get rid of the vlan's reference to real_dev */ |
122 | dev_put(real_dev); | 117 | dev_put(real_dev); |
diff --git a/net/9p/trans_xen.c b/net/9p/trans_xen.c index 325c56043007..086a4abdfa7c 100644 --- a/net/9p/trans_xen.c +++ b/net/9p/trans_xen.c | |||
@@ -543,3 +543,7 @@ static void p9_trans_xen_exit(void) | |||
543 | return xenbus_unregister_driver(&xen_9pfs_front_driver); | 543 | return xenbus_unregister_driver(&xen_9pfs_front_driver); |
544 | } | 544 | } |
545 | module_exit(p9_trans_xen_exit); | 545 | module_exit(p9_trans_xen_exit); |
546 | |||
547 | MODULE_AUTHOR("Stefano Stabellini <stefano@aporeto.com>"); | ||
548 | MODULE_DESCRIPTION("Xen Transport for 9P"); | ||
549 | MODULE_LICENSE("GPL"); | ||
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 1b659ab652fb..bbe8414b6ee7 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -1214,7 +1214,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1214 | orig_node->last_seen = jiffies; | 1214 | orig_node->last_seen = jiffies; |
1215 | 1215 | ||
1216 | /* find packet count of corresponding one hop neighbor */ | 1216 | /* find packet count of corresponding one hop neighbor */ |
1217 | spin_lock_bh(&orig_node->bat_iv.ogm_cnt_lock); | 1217 | spin_lock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1218 | if_num = if_incoming->if_num; | 1218 | if_num = if_incoming->if_num; |
1219 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; | 1219 | orig_eq_count = orig_neigh_node->bat_iv.bcast_own_sum[if_num]; |
1220 | neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); | 1220 | neigh_ifinfo = batadv_neigh_ifinfo_new(neigh_node, if_outgoing); |
@@ -1224,7 +1224,7 @@ static bool batadv_iv_ogm_calc_tq(struct batadv_orig_node *orig_node, | |||
1224 | } else { | 1224 | } else { |
1225 | neigh_rq_count = 0; | 1225 | neigh_rq_count = 0; |
1226 | } | 1226 | } |
1227 | spin_unlock_bh(&orig_node->bat_iv.ogm_cnt_lock); | 1227 | spin_unlock_bh(&orig_neigh_node->bat_iv.ogm_cnt_lock); |
1228 | 1228 | ||
1229 | /* pay attention to not get a value bigger than 100 % */ | 1229 | /* pay attention to not get a value bigger than 100 % */ |
1230 | if (orig_eq_count > neigh_rq_count) | 1230 | if (orig_eq_count > neigh_rq_count) |
diff --git a/net/batman-adv/bat_v.c b/net/batman-adv/bat_v.c index 341ceab8338d..e0e2bfcd6b3e 100644 --- a/net/batman-adv/bat_v.c +++ b/net/batman-adv/bat_v.c | |||
@@ -814,7 +814,7 @@ static bool batadv_v_gw_is_eligible(struct batadv_priv *bat_priv, | |||
814 | } | 814 | } |
815 | 815 | ||
816 | orig_gw = batadv_gw_node_get(bat_priv, orig_node); | 816 | orig_gw = batadv_gw_node_get(bat_priv, orig_node); |
817 | if (!orig_node) | 817 | if (!orig_gw) |
818 | goto out; | 818 | goto out; |
819 | 819 | ||
820 | if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) | 820 | if (batadv_v_gw_throughput_get(orig_gw, &orig_throughput) < 0) |
diff --git a/net/batman-adv/fragmentation.c b/net/batman-adv/fragmentation.c index a98cf1104a30..ebe6e38934e4 100644 --- a/net/batman-adv/fragmentation.c +++ b/net/batman-adv/fragmentation.c | |||
@@ -499,6 +499,8 @@ int batadv_frag_send_packet(struct sk_buff *skb, | |||
499 | */ | 499 | */ |
500 | if (skb->priority >= 256 && skb->priority <= 263) | 500 | if (skb->priority >= 256 && skb->priority <= 263) |
501 | frag_header.priority = skb->priority - 256; | 501 | frag_header.priority = skb->priority - 256; |
502 | else | ||
503 | frag_header.priority = 0; | ||
502 | 504 | ||
503 | ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); | 505 | ether_addr_copy(frag_header.orig, primary_if->net_dev->dev_addr); |
504 | ether_addr_copy(frag_header.dest, orig_node->orig); | 506 | ether_addr_copy(frag_header.dest, orig_node->orig); |
diff --git a/net/batman-adv/tp_meter.c b/net/batman-adv/tp_meter.c index 15cd2139381e..ebc4e2241c77 100644 --- a/net/batman-adv/tp_meter.c +++ b/net/batman-adv/tp_meter.c | |||
@@ -482,7 +482,7 @@ static void batadv_tp_reset_sender_timer(struct batadv_tp_vars *tp_vars) | |||
482 | 482 | ||
483 | /** | 483 | /** |
484 | * batadv_tp_sender_timeout - timer that fires in case of packet loss | 484 | * batadv_tp_sender_timeout - timer that fires in case of packet loss |
485 | * @arg: address of the related tp_vars | 485 | * @t: address to timer_list inside tp_vars |
486 | * | 486 | * |
487 | * If fired it means that there was packet loss. | 487 | * If fired it means that there was packet loss. |
488 | * Switch to Slow Start, set the ss_threshold to half of the current cwnd and | 488 | * Switch to Slow Start, set the ss_threshold to half of the current cwnd and |
@@ -1106,7 +1106,7 @@ static void batadv_tp_reset_receiver_timer(struct batadv_tp_vars *tp_vars) | |||
1106 | /** | 1106 | /** |
1107 | * batadv_tp_receiver_shutdown - stop a tp meter receiver when timeout is | 1107 | * batadv_tp_receiver_shutdown - stop a tp meter receiver when timeout is |
1108 | * reached without received ack | 1108 | * reached without received ack |
1109 | * @arg: address of the related tp_vars | 1109 | * @t: address to timer_list inside tp_vars |
1110 | */ | 1110 | */ |
1111 | static void batadv_tp_receiver_shutdown(struct timer_list *t) | 1111 | static void batadv_tp_receiver_shutdown(struct timer_list *t) |
1112 | { | 1112 | { |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 43ba91c440bc..fc6615d59165 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3363,9 +3363,10 @@ static int l2cap_parse_conf_req(struct l2cap_chan *chan, void *data, size_t data | |||
3363 | break; | 3363 | break; |
3364 | 3364 | ||
3365 | case L2CAP_CONF_EFS: | 3365 | case L2CAP_CONF_EFS: |
3366 | remote_efs = 1; | 3366 | if (olen == sizeof(efs)) { |
3367 | if (olen == sizeof(efs)) | 3367 | remote_efs = 1; |
3368 | memcpy(&efs, (void *) val, olen); | 3368 | memcpy(&efs, (void *) val, olen); |
3369 | } | ||
3369 | break; | 3370 | break; |
3370 | 3371 | ||
3371 | case L2CAP_CONF_EWS: | 3372 | case L2CAP_CONF_EWS: |
@@ -3584,16 +3585,17 @@ static int l2cap_parse_conf_rsp(struct l2cap_chan *chan, void *rsp, int len, | |||
3584 | break; | 3585 | break; |
3585 | 3586 | ||
3586 | case L2CAP_CONF_EFS: | 3587 | case L2CAP_CONF_EFS: |
3587 | if (olen == sizeof(efs)) | 3588 | if (olen == sizeof(efs)) { |
3588 | memcpy(&efs, (void *)val, olen); | 3589 | memcpy(&efs, (void *)val, olen); |
3589 | 3590 | ||
3590 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && | 3591 | if (chan->local_stype != L2CAP_SERV_NOTRAFIC && |
3591 | efs.stype != L2CAP_SERV_NOTRAFIC && | 3592 | efs.stype != L2CAP_SERV_NOTRAFIC && |
3592 | efs.stype != chan->local_stype) | 3593 | efs.stype != chan->local_stype) |
3593 | return -ECONNREFUSED; | 3594 | return -ECONNREFUSED; |
3594 | 3595 | ||
3595 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), | 3596 | l2cap_add_conf_opt(&ptr, L2CAP_CONF_EFS, sizeof(efs), |
3596 | (unsigned long) &efs, endptr - ptr); | 3597 | (unsigned long) &efs, endptr - ptr); |
3598 | } | ||
3597 | break; | 3599 | break; |
3598 | 3600 | ||
3599 | case L2CAP_CONF_FCS: | 3601 | case L2CAP_CONF_FCS: |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index d0ef0a8e8831..015f465c514b 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -1262,19 +1262,20 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev, | |||
1262 | struct net_bridge *br = netdev_priv(dev); | 1262 | struct net_bridge *br = netdev_priv(dev); |
1263 | int err; | 1263 | int err; |
1264 | 1264 | ||
1265 | err = register_netdevice(dev); | ||
1266 | if (err) | ||
1267 | return err; | ||
1268 | |||
1265 | if (tb[IFLA_ADDRESS]) { | 1269 | if (tb[IFLA_ADDRESS]) { |
1266 | spin_lock_bh(&br->lock); | 1270 | spin_lock_bh(&br->lock); |
1267 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); | 1271 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); |
1268 | spin_unlock_bh(&br->lock); | 1272 | spin_unlock_bh(&br->lock); |
1269 | } | 1273 | } |
1270 | 1274 | ||
1271 | err = register_netdevice(dev); | ||
1272 | if (err) | ||
1273 | return err; | ||
1274 | |||
1275 | err = br_changelink(dev, tb, data, extack); | 1275 | err = br_changelink(dev, tb, data, extack); |
1276 | if (err) | 1276 | if (err) |
1277 | unregister_netdevice(dev); | 1277 | br_dev_delete(dev, NULL); |
1278 | |||
1278 | return err; | 1279 | return err; |
1279 | } | 1280 | } |
1280 | 1281 | ||
diff --git a/net/caif/caif_dev.c b/net/caif/caif_dev.c index 2d38b6e34203..e0adcd123f48 100644 --- a/net/caif/caif_dev.c +++ b/net/caif/caif_dev.c | |||
@@ -334,9 +334,8 @@ void caif_enroll_dev(struct net_device *dev, struct caif_dev_common *caifdev, | |||
334 | mutex_lock(&caifdevs->lock); | 334 | mutex_lock(&caifdevs->lock); |
335 | list_add_rcu(&caifd->list, &caifdevs->list); | 335 | list_add_rcu(&caifd->list, &caifdevs->list); |
336 | 336 | ||
337 | strncpy(caifd->layer.name, dev->name, | 337 | strlcpy(caifd->layer.name, dev->name, |
338 | sizeof(caifd->layer.name) - 1); | 338 | sizeof(caifd->layer.name)); |
339 | caifd->layer.name[sizeof(caifd->layer.name) - 1] = 0; | ||
340 | caifd->layer.transmit = transmit; | 339 | caifd->layer.transmit = transmit; |
341 | cfcnfg_add_phy_layer(cfg, | 340 | cfcnfg_add_phy_layer(cfg, |
342 | dev, | 341 | dev, |
diff --git a/net/caif/caif_usb.c b/net/caif/caif_usb.c index 5cd44f001f64..1a082a946045 100644 --- a/net/caif/caif_usb.c +++ b/net/caif/caif_usb.c | |||
@@ -176,9 +176,7 @@ static int cfusbl_device_notify(struct notifier_block *me, unsigned long what, | |||
176 | dev_add_pack(&caif_usb_type); | 176 | dev_add_pack(&caif_usb_type); |
177 | pack_added = true; | 177 | pack_added = true; |
178 | 178 | ||
179 | strncpy(layer->name, dev->name, | 179 | strlcpy(layer->name, dev->name, sizeof(layer->name)); |
180 | sizeof(layer->name) - 1); | ||
181 | layer->name[sizeof(layer->name) - 1] = 0; | ||
182 | 180 | ||
183 | return 0; | 181 | return 0; |
184 | } | 182 | } |
diff --git a/net/caif/cfcnfg.c b/net/caif/cfcnfg.c index 273cb07f57d8..8f00bea093b9 100644 --- a/net/caif/cfcnfg.c +++ b/net/caif/cfcnfg.c | |||
@@ -268,17 +268,15 @@ static int caif_connect_req_to_link_param(struct cfcnfg *cnfg, | |||
268 | case CAIFPROTO_RFM: | 268 | case CAIFPROTO_RFM: |
269 | l->linktype = CFCTRL_SRV_RFM; | 269 | l->linktype = CFCTRL_SRV_RFM; |
270 | l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; | 270 | l->u.datagram.connid = s->sockaddr.u.rfm.connection_id; |
271 | strncpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, | 271 | strlcpy(l->u.rfm.volume, s->sockaddr.u.rfm.volume, |
272 | sizeof(l->u.rfm.volume)-1); | 272 | sizeof(l->u.rfm.volume)); |
273 | l->u.rfm.volume[sizeof(l->u.rfm.volume)-1] = 0; | ||
274 | break; | 273 | break; |
275 | case CAIFPROTO_UTIL: | 274 | case CAIFPROTO_UTIL: |
276 | l->linktype = CFCTRL_SRV_UTIL; | 275 | l->linktype = CFCTRL_SRV_UTIL; |
277 | l->endpoint = 0x00; | 276 | l->endpoint = 0x00; |
278 | l->chtype = 0x00; | 277 | l->chtype = 0x00; |
279 | strncpy(l->u.utility.name, s->sockaddr.u.util.service, | 278 | strlcpy(l->u.utility.name, s->sockaddr.u.util.service, |
280 | sizeof(l->u.utility.name)-1); | 279 | sizeof(l->u.utility.name)); |
281 | l->u.utility.name[sizeof(l->u.utility.name)-1] = 0; | ||
282 | caif_assert(sizeof(l->u.utility.name) > 10); | 280 | caif_assert(sizeof(l->u.utility.name) > 10); |
283 | l->u.utility.paramlen = s->param.size; | 281 | l->u.utility.paramlen = s->param.size; |
284 | if (l->u.utility.paramlen > sizeof(l->u.utility.params)) | 282 | if (l->u.utility.paramlen > sizeof(l->u.utility.params)) |
diff --git a/net/caif/cfctrl.c b/net/caif/cfctrl.c index f5afda1abc76..655ed7032150 100644 --- a/net/caif/cfctrl.c +++ b/net/caif/cfctrl.c | |||
@@ -258,8 +258,8 @@ int cfctrl_linkup_request(struct cflayer *layer, | |||
258 | tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); | 258 | tmp16 = cpu_to_le16(param->u.utility.fifosize_bufs); |
259 | cfpkt_add_body(pkt, &tmp16, 2); | 259 | cfpkt_add_body(pkt, &tmp16, 2); |
260 | memset(utility_name, 0, sizeof(utility_name)); | 260 | memset(utility_name, 0, sizeof(utility_name)); |
261 | strncpy(utility_name, param->u.utility.name, | 261 | strlcpy(utility_name, param->u.utility.name, |
262 | UTILITY_NAME_LENGTH - 1); | 262 | UTILITY_NAME_LENGTH); |
263 | cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH); | 263 | cfpkt_add_body(pkt, utility_name, UTILITY_NAME_LENGTH); |
264 | tmp8 = param->u.utility.paramlen; | 264 | tmp8 = param->u.utility.paramlen; |
265 | cfpkt_add_body(pkt, &tmp8, 1); | 265 | cfpkt_add_body(pkt, &tmp8, 1); |
diff --git a/net/can/af_can.c b/net/can/af_can.c index 003b2d6d655f..4d7f988a3130 100644 --- a/net/can/af_can.c +++ b/net/can/af_can.c | |||
@@ -721,20 +721,16 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev, | |||
721 | { | 721 | { |
722 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; | 722 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; |
723 | 723 | ||
724 | if (WARN_ONCE(dev->type != ARPHRD_CAN || | 724 | if (unlikely(dev->type != ARPHRD_CAN || skb->len != CAN_MTU || |
725 | skb->len != CAN_MTU || | 725 | cfd->len > CAN_MAX_DLEN)) { |
726 | cfd->len > CAN_MAX_DLEN, | 726 | pr_warn_once("PF_CAN: dropped non conform CAN skbuf: dev type %d, len %d, datalen %d\n", |
727 | "PF_CAN: dropped non conform CAN skbuf: " | 727 | dev->type, skb->len, cfd->len); |
728 | "dev type %d, len %d, datalen %d\n", | 728 | kfree_skb(skb); |
729 | dev->type, skb->len, cfd->len)) | 729 | return NET_RX_DROP; |
730 | goto drop; | 730 | } |
731 | 731 | ||
732 | can_receive(skb, dev); | 732 | can_receive(skb, dev); |
733 | return NET_RX_SUCCESS; | 733 | return NET_RX_SUCCESS; |
734 | |||
735 | drop: | ||
736 | kfree_skb(skb); | ||
737 | return NET_RX_DROP; | ||
738 | } | 734 | } |
739 | 735 | ||
740 | static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, | 736 | static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, |
@@ -742,20 +738,16 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev, | |||
742 | { | 738 | { |
743 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; | 739 | struct canfd_frame *cfd = (struct canfd_frame *)skb->data; |
744 | 740 | ||
745 | if (WARN_ONCE(dev->type != ARPHRD_CAN || | 741 | if (unlikely(dev->type != ARPHRD_CAN || skb->len != CANFD_MTU || |
746 | skb->len != CANFD_MTU || | 742 | cfd->len > CANFD_MAX_DLEN)) { |
747 | cfd->len > CANFD_MAX_DLEN, | 743 | pr_warn_once("PF_CAN: dropped non conform CAN FD skbuf: dev type %d, len %d, datalen %d\n", |
748 | "PF_CAN: dropped non conform CAN FD skbuf: " | 744 | dev->type, skb->len, cfd->len); |
749 | "dev type %d, len %d, datalen %d\n", | 745 | kfree_skb(skb); |
750 | dev->type, skb->len, cfd->len)) | 746 | return NET_RX_DROP; |
751 | goto drop; | 747 | } |
752 | 748 | ||
753 | can_receive(skb, dev); | 749 | can_receive(skb, dev); |
754 | return NET_RX_SUCCESS; | 750 | return NET_RX_SUCCESS; |
755 | |||
756 | drop: | ||
757 | kfree_skb(skb); | ||
758 | return NET_RX_DROP; | ||
759 | } | 751 | } |
760 | 752 | ||
761 | /* | 753 | /* |
diff --git a/net/core/dev.c b/net/core/dev.c index f47e96b62308..613fb4066be7 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1146,7 +1146,19 @@ EXPORT_SYMBOL(dev_alloc_name); | |||
1146 | int dev_get_valid_name(struct net *net, struct net_device *dev, | 1146 | int dev_get_valid_name(struct net *net, struct net_device *dev, |
1147 | const char *name) | 1147 | const char *name) |
1148 | { | 1148 | { |
1149 | return dev_alloc_name_ns(net, dev, name); | 1149 | BUG_ON(!net); |
1150 | |||
1151 | if (!dev_valid_name(name)) | ||
1152 | return -EINVAL; | ||
1153 | |||
1154 | if (strchr(name, '%')) | ||
1155 | return dev_alloc_name_ns(net, dev, name); | ||
1156 | else if (__dev_get_by_name(net, name)) | ||
1157 | return -EEXIST; | ||
1158 | else if (dev->name != name) | ||
1159 | strlcpy(dev->name, name, IFNAMSIZ); | ||
1160 | |||
1161 | return 0; | ||
1150 | } | 1162 | } |
1151 | EXPORT_SYMBOL(dev_get_valid_name); | 1163 | EXPORT_SYMBOL(dev_get_valid_name); |
1152 | 1164 | ||
@@ -3139,10 +3151,21 @@ static void qdisc_pkt_len_init(struct sk_buff *skb) | |||
3139 | hdr_len = skb_transport_header(skb) - skb_mac_header(skb); | 3151 | hdr_len = skb_transport_header(skb) - skb_mac_header(skb); |
3140 | 3152 | ||
3141 | /* + transport layer */ | 3153 | /* + transport layer */ |
3142 | if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) | 3154 | if (likely(shinfo->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))) { |
3143 | hdr_len += tcp_hdrlen(skb); | 3155 | const struct tcphdr *th; |
3144 | else | 3156 | struct tcphdr _tcphdr; |
3145 | hdr_len += sizeof(struct udphdr); | 3157 | |
3158 | th = skb_header_pointer(skb, skb_transport_offset(skb), | ||
3159 | sizeof(_tcphdr), &_tcphdr); | ||
3160 | if (likely(th)) | ||
3161 | hdr_len += __tcp_hdrlen(th); | ||
3162 | } else { | ||
3163 | struct udphdr _udphdr; | ||
3164 | |||
3165 | if (skb_header_pointer(skb, skb_transport_offset(skb), | ||
3166 | sizeof(_udphdr), &_udphdr)) | ||
3167 | hdr_len += sizeof(struct udphdr); | ||
3168 | } | ||
3146 | 3169 | ||
3147 | if (shinfo->gso_type & SKB_GSO_DODGY) | 3170 | if (shinfo->gso_type & SKB_GSO_DODGY) |
3148 | gso_segs = DIV_ROUND_UP(skb->len - hdr_len, | 3171 | gso_segs = DIV_ROUND_UP(skb->len - hdr_len, |
@@ -3904,7 +3927,7 @@ static u32 netif_receive_generic_xdp(struct sk_buff *skb, | |||
3904 | hroom > 0 ? ALIGN(hroom, NET_SKB_PAD) : 0, | 3927 | hroom > 0 ? ALIGN(hroom, NET_SKB_PAD) : 0, |
3905 | troom > 0 ? troom + 128 : 0, GFP_ATOMIC)) | 3928 | troom > 0 ? troom + 128 : 0, GFP_ATOMIC)) |
3906 | goto do_drop; | 3929 | goto do_drop; |
3907 | if (troom > 0 && __skb_linearize(skb)) | 3930 | if (skb_linearize(skb)) |
3908 | goto do_drop; | 3931 | goto do_drop; |
3909 | } | 3932 | } |
3910 | 3933 | ||
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index f8fcf450a36e..8225416911ae 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -770,15 +770,6 @@ static int ethtool_set_link_ksettings(struct net_device *dev, | |||
770 | return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings); | 770 | return dev->ethtool_ops->set_link_ksettings(dev, &link_ksettings); |
771 | } | 771 | } |
772 | 772 | ||
773 | static void | ||
774 | warn_incomplete_ethtool_legacy_settings_conversion(const char *details) | ||
775 | { | ||
776 | char name[sizeof(current->comm)]; | ||
777 | |||
778 | pr_info_once("warning: `%s' uses legacy ethtool link settings API, %s\n", | ||
779 | get_task_comm(name, current), details); | ||
780 | } | ||
781 | |||
782 | /* Query device for its ethtool_cmd settings. | 773 | /* Query device for its ethtool_cmd settings. |
783 | * | 774 | * |
784 | * Backward compatibility note: for compatibility with legacy ethtool, | 775 | * Backward compatibility note: for compatibility with legacy ethtool, |
@@ -805,10 +796,8 @@ static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) | |||
805 | &link_ksettings); | 796 | &link_ksettings); |
806 | if (err < 0) | 797 | if (err < 0) |
807 | return err; | 798 | return err; |
808 | if (!convert_link_ksettings_to_legacy_settings(&cmd, | 799 | convert_link_ksettings_to_legacy_settings(&cmd, |
809 | &link_ksettings)) | 800 | &link_ksettings); |
810 | warn_incomplete_ethtool_legacy_settings_conversion( | ||
811 | "link modes are only partially reported"); | ||
812 | 801 | ||
813 | /* send a sensible cmd tag back to user */ | 802 | /* send a sensible cmd tag back to user */ |
814 | cmd.cmd = ETHTOOL_GSET; | 803 | cmd.cmd = ETHTOOL_GSET; |
diff --git a/net/core/filter.c b/net/core/filter.c index 6a85e67fafce..1c0eb436671f 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -458,6 +458,10 @@ do_pass: | |||
458 | convert_bpf_extensions(fp, &insn)) | 458 | convert_bpf_extensions(fp, &insn)) |
459 | break; | 459 | break; |
460 | 460 | ||
461 | if (fp->code == (BPF_ALU | BPF_DIV | BPF_X) || | ||
462 | fp->code == (BPF_ALU | BPF_MOD | BPF_X)) | ||
463 | *insn++ = BPF_MOV32_REG(BPF_REG_X, BPF_REG_X); | ||
464 | |||
461 | *insn = BPF_RAW_INSN(fp->code, BPF_REG_A, BPF_REG_X, 0, fp->k); | 465 | *insn = BPF_RAW_INSN(fp->code, BPF_REG_A, BPF_REG_X, 0, fp->k); |
462 | break; | 466 | break; |
463 | 467 | ||
@@ -1054,11 +1058,9 @@ static struct bpf_prog *bpf_migrate_filter(struct bpf_prog *fp) | |||
1054 | */ | 1058 | */ |
1055 | goto out_err_free; | 1059 | goto out_err_free; |
1056 | 1060 | ||
1057 | /* We are guaranteed to never error here with cBPF to eBPF | ||
1058 | * transitions, since there's no issue with type compatibility | ||
1059 | * checks on program arrays. | ||
1060 | */ | ||
1061 | fp = bpf_prog_select_runtime(fp, &err); | 1061 | fp = bpf_prog_select_runtime(fp, &err); |
1062 | if (err) | ||
1063 | goto out_err_free; | ||
1062 | 1064 | ||
1063 | kfree(old_prog); | 1065 | kfree(old_prog); |
1064 | return fp; | 1066 | return fp; |
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c index 15ce30063765..544bddf08e13 100644 --- a/net/core/flow_dissector.c +++ b/net/core/flow_dissector.c | |||
@@ -976,8 +976,8 @@ ip_proto_again: | |||
976 | out_good: | 976 | out_good: |
977 | ret = true; | 977 | ret = true; |
978 | 978 | ||
979 | key_control->thoff = (u16)nhoff; | ||
980 | out: | 979 | out: |
980 | key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen); | ||
981 | key_basic->n_proto = proto; | 981 | key_basic->n_proto = proto; |
982 | key_basic->ip_proto = ip_proto; | 982 | key_basic->ip_proto = ip_proto; |
983 | 983 | ||
@@ -985,7 +985,6 @@ out: | |||
985 | 985 | ||
986 | out_bad: | 986 | out_bad: |
987 | ret = false; | 987 | ret = false; |
988 | key_control->thoff = min_t(u16, nhoff, skb ? skb->len : hlen); | ||
989 | goto out; | 988 | goto out; |
990 | } | 989 | } |
991 | EXPORT_SYMBOL(__skb_flow_dissect); | 990 | EXPORT_SYMBOL(__skb_flow_dissect); |
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index d1f5fe986edd..7f831711b6e0 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -532,7 +532,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, | |||
532 | if (atomic_read(&tbl->entries) > (1 << nht->hash_shift)) | 532 | if (atomic_read(&tbl->entries) > (1 << nht->hash_shift)) |
533 | nht = neigh_hash_grow(tbl, nht->hash_shift + 1); | 533 | nht = neigh_hash_grow(tbl, nht->hash_shift + 1); |
534 | 534 | ||
535 | hash_val = tbl->hash(pkey, dev, nht->hash_rnd) >> (32 - nht->hash_shift); | 535 | hash_val = tbl->hash(n->primary_key, dev, nht->hash_rnd) >> (32 - nht->hash_shift); |
536 | 536 | ||
537 | if (n->parms->dead) { | 537 | if (n->parms->dead) { |
538 | rc = ERR_PTR(-EINVAL); | 538 | rc = ERR_PTR(-EINVAL); |
@@ -544,7 +544,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, | |||
544 | n1 != NULL; | 544 | n1 != NULL; |
545 | n1 = rcu_dereference_protected(n1->next, | 545 | n1 = rcu_dereference_protected(n1->next, |
546 | lockdep_is_held(&tbl->lock))) { | 546 | lockdep_is_held(&tbl->lock))) { |
547 | if (dev == n1->dev && !memcmp(n1->primary_key, pkey, key_len)) { | 547 | if (dev == n1->dev && !memcmp(n1->primary_key, n->primary_key, key_len)) { |
548 | if (want_ref) | 548 | if (want_ref) |
549 | neigh_hold(n1); | 549 | neigh_hold(n1); |
550 | rc = n1; | 550 | rc = n1; |
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c index b797832565d3..60a71be75aea 100644 --- a/net/core/net_namespace.c +++ b/net/core/net_namespace.c | |||
@@ -267,7 +267,7 @@ struct net *get_net_ns_by_id(struct net *net, int id) | |||
267 | spin_lock_bh(&net->nsid_lock); | 267 | spin_lock_bh(&net->nsid_lock); |
268 | peer = idr_find(&net->netns_ids, id); | 268 | peer = idr_find(&net->netns_ids, id); |
269 | if (peer) | 269 | if (peer) |
270 | get_net(peer); | 270 | peer = maybe_get_net(peer); |
271 | spin_unlock_bh(&net->nsid_lock); | 271 | spin_unlock_bh(&net->nsid_lock); |
272 | rcu_read_unlock(); | 272 | rcu_read_unlock(); |
273 | 273 | ||
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index 1c4810919a0a..b9057478d69c 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/types.h> | 16 | #include <linux/types.h> |
17 | #include <linux/module.h> | ||
18 | #include <linux/string.h> | 17 | #include <linux/string.h> |
19 | #include <linux/errno.h> | 18 | #include <linux/errno.h> |
20 | #include <linux/skbuff.h> | 19 | #include <linux/skbuff.h> |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index dabba2a91fc8..778d7f03404a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1681,18 +1681,18 @@ static bool link_dump_filtered(struct net_device *dev, | |||
1681 | return false; | 1681 | return false; |
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct net *get_target_net(struct sk_buff *skb, int netnsid) | 1684 | static struct net *get_target_net(struct sock *sk, int netnsid) |
1685 | { | 1685 | { |
1686 | struct net *net; | 1686 | struct net *net; |
1687 | 1687 | ||
1688 | net = get_net_ns_by_id(sock_net(skb->sk), netnsid); | 1688 | net = get_net_ns_by_id(sock_net(sk), netnsid); |
1689 | if (!net) | 1689 | if (!net) |
1690 | return ERR_PTR(-EINVAL); | 1690 | return ERR_PTR(-EINVAL); |
1691 | 1691 | ||
1692 | /* For now, the caller is required to have CAP_NET_ADMIN in | 1692 | /* For now, the caller is required to have CAP_NET_ADMIN in |
1693 | * the user namespace owning the target net ns. | 1693 | * the user namespace owning the target net ns. |
1694 | */ | 1694 | */ |
1695 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { | 1695 | if (!sk_ns_capable(sk, net->user_ns, CAP_NET_ADMIN)) { |
1696 | put_net(net); | 1696 | put_net(net); |
1697 | return ERR_PTR(-EACCES); | 1697 | return ERR_PTR(-EACCES); |
1698 | } | 1698 | } |
@@ -1733,7 +1733,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1733 | ifla_policy, NULL) >= 0) { | 1733 | ifla_policy, NULL) >= 0) { |
1734 | if (tb[IFLA_IF_NETNSID]) { | 1734 | if (tb[IFLA_IF_NETNSID]) { |
1735 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); | 1735 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); |
1736 | tgt_net = get_target_net(skb, netnsid); | 1736 | tgt_net = get_target_net(skb->sk, netnsid); |
1737 | if (IS_ERR(tgt_net)) { | 1737 | if (IS_ERR(tgt_net)) { |
1738 | tgt_net = net; | 1738 | tgt_net = net; |
1739 | netnsid = -1; | 1739 | netnsid = -1; |
@@ -2883,7 +2883,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
2883 | 2883 | ||
2884 | if (tb[IFLA_IF_NETNSID]) { | 2884 | if (tb[IFLA_IF_NETNSID]) { |
2885 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); | 2885 | netnsid = nla_get_s32(tb[IFLA_IF_NETNSID]); |
2886 | tgt_net = get_target_net(skb, netnsid); | 2886 | tgt_net = get_target_net(NETLINK_CB(skb).sk, netnsid); |
2887 | if (IS_ERR(tgt_net)) | 2887 | if (IS_ERR(tgt_net)) |
2888 | return PTR_ERR(tgt_net); | 2888 | return PTR_ERR(tgt_net); |
2889 | } | 2889 | } |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 6b0ff396fa9d..08f574081315 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -1177,12 +1177,12 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
1177 | int i, new_frags; | 1177 | int i, new_frags; |
1178 | u32 d_off; | 1178 | u32 d_off; |
1179 | 1179 | ||
1180 | if (!num_frags) | ||
1181 | return 0; | ||
1182 | |||
1183 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) | 1180 | if (skb_shared(skb) || skb_unclone(skb, gfp_mask)) |
1184 | return -EINVAL; | 1181 | return -EINVAL; |
1185 | 1182 | ||
1183 | if (!num_frags) | ||
1184 | goto release; | ||
1185 | |||
1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; | 1186 | new_frags = (__skb_pagelen(skb) + PAGE_SIZE - 1) >> PAGE_SHIFT; |
1187 | for (i = 0; i < new_frags; i++) { | 1187 | for (i = 0; i < new_frags; i++) { |
1188 | page = alloc_page(gfp_mask); | 1188 | page = alloc_page(gfp_mask); |
@@ -1238,6 +1238,7 @@ int skb_copy_ubufs(struct sk_buff *skb, gfp_t gfp_mask) | |||
1238 | __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); | 1238 | __skb_fill_page_desc(skb, new_frags - 1, head, 0, d_off); |
1239 | skb_shinfo(skb)->nr_frags = new_frags; | 1239 | skb_shinfo(skb)->nr_frags = new_frags; |
1240 | 1240 | ||
1241 | release: | ||
1241 | skb_zcopy_clear(skb, false); | 1242 | skb_zcopy_clear(skb, false); |
1242 | return 0; | 1243 | return 0; |
1243 | } | 1244 | } |
@@ -3654,8 +3655,6 @@ normal: | |||
3654 | 3655 | ||
3655 | skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & | 3656 | skb_shinfo(nskb)->tx_flags |= skb_shinfo(head_skb)->tx_flags & |
3656 | SKBTX_SHARED_FRAG; | 3657 | SKBTX_SHARED_FRAG; |
3657 | if (skb_zerocopy_clone(nskb, head_skb, GFP_ATOMIC)) | ||
3658 | goto err; | ||
3659 | 3658 | ||
3660 | while (pos < offset + len) { | 3659 | while (pos < offset + len) { |
3661 | if (i >= nfrags) { | 3660 | if (i >= nfrags) { |
@@ -3681,6 +3680,8 @@ normal: | |||
3681 | 3680 | ||
3682 | if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) | 3681 | if (unlikely(skb_orphan_frags(frag_skb, GFP_ATOMIC))) |
3683 | goto err; | 3682 | goto err; |
3683 | if (skb_zerocopy_clone(nskb, frag_skb, GFP_ATOMIC)) | ||
3684 | goto err; | ||
3684 | 3685 | ||
3685 | *nskb_frag = *frag; | 3686 | *nskb_frag = *frag; |
3686 | __skb_frag_ref(nskb_frag); | 3687 | __skb_frag_ref(nskb_frag); |
@@ -4293,7 +4294,7 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
4293 | struct sock *sk = skb->sk; | 4294 | struct sock *sk = skb->sk; |
4294 | 4295 | ||
4295 | if (!skb_may_tx_timestamp(sk, false)) | 4296 | if (!skb_may_tx_timestamp(sk, false)) |
4296 | return; | 4297 | goto err; |
4297 | 4298 | ||
4298 | /* Take a reference to prevent skb_orphan() from freeing the socket, | 4299 | /* Take a reference to prevent skb_orphan() from freeing the socket, |
4299 | * but only if the socket refcount is not zero. | 4300 | * but only if the socket refcount is not zero. |
@@ -4302,7 +4303,11 @@ void skb_complete_tx_timestamp(struct sk_buff *skb, | |||
4302 | *skb_hwtstamps(skb) = *hwtstamps; | 4303 | *skb_hwtstamps(skb) = *hwtstamps; |
4303 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); | 4304 | __skb_complete_tx_timestamp(skb, sk, SCM_TSTAMP_SND, false); |
4304 | sock_put(sk); | 4305 | sock_put(sk); |
4306 | return; | ||
4305 | } | 4307 | } |
4308 | |||
4309 | err: | ||
4310 | kfree_skb(skb); | ||
4306 | } | 4311 | } |
4307 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); | 4312 | EXPORT_SYMBOL_GPL(skb_complete_tx_timestamp); |
4308 | 4313 | ||
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index 217f4e3b82f6..146b50e30659 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -288,7 +288,7 @@ static int sock_diag_bind(struct net *net, int group) | |||
288 | case SKNLGRP_INET6_UDP_DESTROY: | 288 | case SKNLGRP_INET6_UDP_DESTROY: |
289 | if (!sock_diag_handlers[AF_INET6]) | 289 | if (!sock_diag_handlers[AF_INET6]) |
290 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, | 290 | request_module("net-pf-%d-proto-%d-type-%d", PF_NETLINK, |
291 | NETLINK_SOCK_DIAG, AF_INET); | 291 | NETLINK_SOCK_DIAG, AF_INET6); |
292 | break; | 292 | break; |
293 | } | 293 | } |
294 | return 0; | 294 | return 0; |
diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c index cbc3dde4cfcc..a47ad6cd41c0 100644 --- a/net/core/sysctl_net_core.c +++ b/net/core/sysctl_net_core.c | |||
@@ -325,7 +325,13 @@ static struct ctl_table net_core_table[] = { | |||
325 | .data = &bpf_jit_enable, | 325 | .data = &bpf_jit_enable, |
326 | .maxlen = sizeof(int), | 326 | .maxlen = sizeof(int), |
327 | .mode = 0644, | 327 | .mode = 0644, |
328 | #ifndef CONFIG_BPF_JIT_ALWAYS_ON | ||
328 | .proc_handler = proc_dointvec | 329 | .proc_handler = proc_dointvec |
330 | #else | ||
331 | .proc_handler = proc_dointvec_minmax, | ||
332 | .extra1 = &one, | ||
333 | .extra2 = &one, | ||
334 | #endif | ||
329 | }, | 335 | }, |
330 | # ifdef CONFIG_HAVE_EBPF_JIT | 336 | # ifdef CONFIG_HAVE_EBPF_JIT |
331 | { | 337 | { |
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c index 1c75cd1255f6..92d016e87816 100644 --- a/net/dccp/ccids/ccid2.c +++ b/net/dccp/ccids/ccid2.c | |||
@@ -140,6 +140,9 @@ static void ccid2_hc_tx_rto_expire(struct timer_list *t) | |||
140 | 140 | ||
141 | ccid2_pr_debug("RTO_EXPIRE\n"); | 141 | ccid2_pr_debug("RTO_EXPIRE\n"); |
142 | 142 | ||
143 | if (sk->sk_state == DCCP_CLOSED) | ||
144 | goto out; | ||
145 | |||
143 | /* back-off timer */ | 146 | /* back-off timer */ |
144 | hc->tx_rto <<= 1; | 147 | hc->tx_rto <<= 1; |
145 | if (hc->tx_rto > DCCP_RTO_MAX) | 148 | if (hc->tx_rto > DCCP_RTO_MAX) |
diff --git a/net/dsa/slave.c b/net/dsa/slave.c index d6e7a642493b..a95a55f79137 100644 --- a/net/dsa/slave.c +++ b/net/dsa/slave.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/of_net.h> | 16 | #include <linux/of_net.h> |
17 | #include <linux/of_mdio.h> | 17 | #include <linux/of_mdio.h> |
18 | #include <linux/mdio.h> | 18 | #include <linux/mdio.h> |
19 | #include <linux/list.h> | ||
20 | #include <net/rtnetlink.h> | 19 | #include <net/rtnetlink.h> |
21 | #include <net/pkt_cls.h> | 20 | #include <net/pkt_cls.h> |
22 | #include <net/tc_act/tc_mirred.h> | 21 | #include <net/tc_act/tc_mirred.h> |
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index a8d7c5a9fb05..6c231b43974d 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -223,11 +223,16 @@ static bool arp_key_eq(const struct neighbour *neigh, const void *pkey) | |||
223 | 223 | ||
224 | static int arp_constructor(struct neighbour *neigh) | 224 | static int arp_constructor(struct neighbour *neigh) |
225 | { | 225 | { |
226 | __be32 addr = *(__be32 *)neigh->primary_key; | 226 | __be32 addr; |
227 | struct net_device *dev = neigh->dev; | 227 | struct net_device *dev = neigh->dev; |
228 | struct in_device *in_dev; | 228 | struct in_device *in_dev; |
229 | struct neigh_parms *parms; | 229 | struct neigh_parms *parms; |
230 | u32 inaddr_any = INADDR_ANY; | ||
230 | 231 | ||
232 | if (dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)) | ||
233 | memcpy(neigh->primary_key, &inaddr_any, arp_tbl.key_len); | ||
234 | |||
235 | addr = *(__be32 *)neigh->primary_key; | ||
231 | rcu_read_lock(); | 236 | rcu_read_lock(); |
232 | in_dev = __in_dev_get_rcu(dev); | 237 | in_dev = __in_dev_get_rcu(dev); |
233 | if (!in_dev) { | 238 | if (!in_dev) { |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index a4573bccd6da..7a93359fbc72 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -1428,7 +1428,7 @@ skip: | |||
1428 | 1428 | ||
1429 | static bool inetdev_valid_mtu(unsigned int mtu) | 1429 | static bool inetdev_valid_mtu(unsigned int mtu) |
1430 | { | 1430 | { |
1431 | return mtu >= 68; | 1431 | return mtu >= IPV4_MIN_MTU; |
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | static void inetdev_send_gratuitous_arp(struct net_device *dev, | 1434 | static void inetdev_send_gratuitous_arp(struct net_device *dev, |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index d57aa64fa7c7..61fe6e4d23fc 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -981,6 +981,7 @@ static int esp_init_state(struct xfrm_state *x) | |||
981 | 981 | ||
982 | switch (encap->encap_type) { | 982 | switch (encap->encap_type) { |
983 | default: | 983 | default: |
984 | err = -EINVAL; | ||
984 | goto error; | 985 | goto error; |
985 | case UDP_ENCAP_ESPINUDP: | 986 | case UDP_ENCAP_ESPINUDP: |
986 | x->props.header_len += sizeof(struct udphdr); | 987 | x->props.header_len += sizeof(struct udphdr); |
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index f8b918c766b0..29b333a62ab0 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c | |||
@@ -38,7 +38,8 @@ static struct sk_buff **esp4_gro_receive(struct sk_buff **head, | |||
38 | __be32 spi; | 38 | __be32 spi; |
39 | int err; | 39 | int err; |
40 | 40 | ||
41 | skb_pull(skb, offset); | 41 | if (!pskb_pull(skb, offset)) |
42 | return NULL; | ||
42 | 43 | ||
43 | if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0) | 44 | if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0) |
44 | goto out; | 45 | goto out; |
@@ -121,6 +122,9 @@ static struct sk_buff *esp4_gso_segment(struct sk_buff *skb, | |||
121 | if (!xo) | 122 | if (!xo) |
122 | goto out; | 123 | goto out; |
123 | 124 | ||
125 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_ESP)) | ||
126 | goto out; | ||
127 | |||
124 | seq = xo->seq.low; | 128 | seq = xo->seq.low; |
125 | 129 | ||
126 | x = skb->sp->xvec[skb->sp->len - 1]; | 130 | x = skb->sp->xvec[skb->sp->len - 1]; |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index f52d27a422c3..08259d078b1c 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
@@ -1298,14 +1298,19 @@ err_table_hash_alloc: | |||
1298 | 1298 | ||
1299 | static void ip_fib_net_exit(struct net *net) | 1299 | static void ip_fib_net_exit(struct net *net) |
1300 | { | 1300 | { |
1301 | unsigned int i; | 1301 | int i; |
1302 | 1302 | ||
1303 | rtnl_lock(); | 1303 | rtnl_lock(); |
1304 | #ifdef CONFIG_IP_MULTIPLE_TABLES | 1304 | #ifdef CONFIG_IP_MULTIPLE_TABLES |
1305 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); | 1305 | RCU_INIT_POINTER(net->ipv4.fib_main, NULL); |
1306 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); | 1306 | RCU_INIT_POINTER(net->ipv4.fib_default, NULL); |
1307 | #endif | 1307 | #endif |
1308 | for (i = 0; i < FIB_TABLE_HASHSZ; i++) { | 1308 | /* Destroy the tables in reverse order to guarantee that the |
1309 | * local table, ID 255, is destroyed before the main table, ID | ||
1310 | * 254. This is necessary as the local table may contain | ||
1311 | * references to data contained in the main table. | ||
1312 | */ | ||
1313 | for (i = FIB_TABLE_HASHSZ - 1; i >= 0; i--) { | ||
1309 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; | 1314 | struct hlist_head *head = &net->ipv4.fib_table_hash[i]; |
1310 | struct hlist_node *tmp; | 1315 | struct hlist_node *tmp; |
1311 | struct fib_table *tb; | 1316 | struct fib_table *tb; |
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c index f04d944f8abe..c586597da20d 100644 --- a/net/ipv4/fib_semantics.c +++ b/net/ipv4/fib_semantics.c | |||
@@ -698,7 +698,7 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) | |||
698 | 698 | ||
699 | nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { | 699 | nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) { |
700 | int type = nla_type(nla); | 700 | int type = nla_type(nla); |
701 | u32 val; | 701 | u32 fi_val, val; |
702 | 702 | ||
703 | if (!type) | 703 | if (!type) |
704 | continue; | 704 | continue; |
@@ -715,7 +715,11 @@ bool fib_metrics_match(struct fib_config *cfg, struct fib_info *fi) | |||
715 | val = nla_get_u32(nla); | 715 | val = nla_get_u32(nla); |
716 | } | 716 | } |
717 | 717 | ||
718 | if (fi->fib_metrics->metrics[type - 1] != val) | 718 | fi_val = fi->fib_metrics->metrics[type - 1]; |
719 | if (type == RTAX_FEATURES) | ||
720 | fi_val &= ~DST_FEATURE_ECN_CA; | ||
721 | |||
722 | if (fi_val != val) | ||
719 | return false; | 723 | return false; |
720 | } | 724 | } |
721 | 725 | ||
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c index d1f8f302dbf3..2d49717a7421 100644 --- a/net/ipv4/igmp.c +++ b/net/ipv4/igmp.c | |||
@@ -89,6 +89,7 @@ | |||
89 | #include <linux/rtnetlink.h> | 89 | #include <linux/rtnetlink.h> |
90 | #include <linux/times.h> | 90 | #include <linux/times.h> |
91 | #include <linux/pkt_sched.h> | 91 | #include <linux/pkt_sched.h> |
92 | #include <linux/byteorder/generic.h> | ||
92 | 93 | ||
93 | #include <net/net_namespace.h> | 94 | #include <net/net_namespace.h> |
94 | #include <net/arp.h> | 95 | #include <net/arp.h> |
@@ -321,6 +322,23 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted) | |||
321 | return scount; | 322 | return scount; |
322 | } | 323 | } |
323 | 324 | ||
325 | /* source address selection per RFC 3376 section 4.2.13 */ | ||
326 | static __be32 igmpv3_get_srcaddr(struct net_device *dev, | ||
327 | const struct flowi4 *fl4) | ||
328 | { | ||
329 | struct in_device *in_dev = __in_dev_get_rcu(dev); | ||
330 | |||
331 | if (!in_dev) | ||
332 | return htonl(INADDR_ANY); | ||
333 | |||
334 | for_ifa(in_dev) { | ||
335 | if (fl4->saddr == ifa->ifa_local) | ||
336 | return fl4->saddr; | ||
337 | } endfor_ifa(in_dev); | ||
338 | |||
339 | return htonl(INADDR_ANY); | ||
340 | } | ||
341 | |||
324 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) | 342 | static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) |
325 | { | 343 | { |
326 | struct sk_buff *skb; | 344 | struct sk_buff *skb; |
@@ -368,7 +386,7 @@ static struct sk_buff *igmpv3_newpack(struct net_device *dev, unsigned int mtu) | |||
368 | pip->frag_off = htons(IP_DF); | 386 | pip->frag_off = htons(IP_DF); |
369 | pip->ttl = 1; | 387 | pip->ttl = 1; |
370 | pip->daddr = fl4.daddr; | 388 | pip->daddr = fl4.daddr; |
371 | pip->saddr = fl4.saddr; | 389 | pip->saddr = igmpv3_get_srcaddr(dev, &fl4); |
372 | pip->protocol = IPPROTO_IGMP; | 390 | pip->protocol = IPPROTO_IGMP; |
373 | pip->tot_len = 0; /* filled in later */ | 391 | pip->tot_len = 0; /* filled in later */ |
374 | ip_select_ident(net, skb, NULL); | 392 | ip_select_ident(net, skb, NULL); |
@@ -404,16 +422,17 @@ static int grec_size(struct ip_mc_list *pmc, int type, int gdel, int sdel) | |||
404 | } | 422 | } |
405 | 423 | ||
406 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, | 424 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ip_mc_list *pmc, |
407 | int type, struct igmpv3_grec **ppgr) | 425 | int type, struct igmpv3_grec **ppgr, unsigned int mtu) |
408 | { | 426 | { |
409 | struct net_device *dev = pmc->interface->dev; | 427 | struct net_device *dev = pmc->interface->dev; |
410 | struct igmpv3_report *pih; | 428 | struct igmpv3_report *pih; |
411 | struct igmpv3_grec *pgr; | 429 | struct igmpv3_grec *pgr; |
412 | 430 | ||
413 | if (!skb) | 431 | if (!skb) { |
414 | skb = igmpv3_newpack(dev, dev->mtu); | 432 | skb = igmpv3_newpack(dev, mtu); |
415 | if (!skb) | 433 | if (!skb) |
416 | return NULL; | 434 | return NULL; |
435 | } | ||
417 | pgr = skb_put(skb, sizeof(struct igmpv3_grec)); | 436 | pgr = skb_put(skb, sizeof(struct igmpv3_grec)); |
418 | pgr->grec_type = type; | 437 | pgr->grec_type = type; |
419 | pgr->grec_auxwords = 0; | 438 | pgr->grec_auxwords = 0; |
@@ -436,12 +455,17 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
436 | struct igmpv3_grec *pgr = NULL; | 455 | struct igmpv3_grec *pgr = NULL; |
437 | struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 456 | struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
438 | int scount, stotal, first, isquery, truncate; | 457 | int scount, stotal, first, isquery, truncate; |
458 | unsigned int mtu; | ||
439 | 459 | ||
440 | if (pmc->multiaddr == IGMP_ALL_HOSTS) | 460 | if (pmc->multiaddr == IGMP_ALL_HOSTS) |
441 | return skb; | 461 | return skb; |
442 | if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) | 462 | if (ipv4_is_local_multicast(pmc->multiaddr) && !net->ipv4.sysctl_igmp_llm_reports) |
443 | return skb; | 463 | return skb; |
444 | 464 | ||
465 | mtu = READ_ONCE(dev->mtu); | ||
466 | if (mtu < IPV4_MIN_MTU) | ||
467 | return skb; | ||
468 | |||
445 | isquery = type == IGMPV3_MODE_IS_INCLUDE || | 469 | isquery = type == IGMPV3_MODE_IS_INCLUDE || |
446 | type == IGMPV3_MODE_IS_EXCLUDE; | 470 | type == IGMPV3_MODE_IS_EXCLUDE; |
447 | truncate = type == IGMPV3_MODE_IS_EXCLUDE || | 471 | truncate = type == IGMPV3_MODE_IS_EXCLUDE || |
@@ -462,7 +486,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
462 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 486 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
463 | if (skb) | 487 | if (skb) |
464 | igmpv3_sendpack(skb); | 488 | igmpv3_sendpack(skb); |
465 | skb = igmpv3_newpack(dev, dev->mtu); | 489 | skb = igmpv3_newpack(dev, mtu); |
466 | } | 490 | } |
467 | } | 491 | } |
468 | first = 1; | 492 | first = 1; |
@@ -498,12 +522,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc, | |||
498 | pgr->grec_nsrcs = htons(scount); | 522 | pgr->grec_nsrcs = htons(scount); |
499 | if (skb) | 523 | if (skb) |
500 | igmpv3_sendpack(skb); | 524 | igmpv3_sendpack(skb); |
501 | skb = igmpv3_newpack(dev, dev->mtu); | 525 | skb = igmpv3_newpack(dev, mtu); |
502 | first = 1; | 526 | first = 1; |
503 | scount = 0; | 527 | scount = 0; |
504 | } | 528 | } |
505 | if (first) { | 529 | if (first) { |
506 | skb = add_grhead(skb, pmc, type, &pgr); | 530 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
507 | first = 0; | 531 | first = 0; |
508 | } | 532 | } |
509 | if (!skb) | 533 | if (!skb) |
@@ -538,7 +562,7 @@ empty_source: | |||
538 | igmpv3_sendpack(skb); | 562 | igmpv3_sendpack(skb); |
539 | skb = NULL; /* add_grhead will get a new one */ | 563 | skb = NULL; /* add_grhead will get a new one */ |
540 | } | 564 | } |
541 | skb = add_grhead(skb, pmc, type, &pgr); | 565 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
542 | } | 566 | } |
543 | } | 567 | } |
544 | if (pgr) | 568 | if (pgr) |
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index bb6239169b1a..45ffd3d045d2 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -266,7 +266,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi, | |||
266 | len = gre_hdr_len + sizeof(*ershdr); | 266 | len = gre_hdr_len + sizeof(*ershdr); |
267 | 267 | ||
268 | if (unlikely(!pskb_may_pull(skb, len))) | 268 | if (unlikely(!pskb_may_pull(skb, len))) |
269 | return -ENOMEM; | 269 | return PACKET_REJECT; |
270 | 270 | ||
271 | iph = ip_hdr(skb); | 271 | iph = ip_hdr(skb); |
272 | ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len); | 272 | ershdr = (struct erspanhdr *)(skb->data + gre_hdr_len); |
@@ -1310,6 +1310,7 @@ static const struct net_device_ops erspan_netdev_ops = { | |||
1310 | static void ipgre_tap_setup(struct net_device *dev) | 1310 | static void ipgre_tap_setup(struct net_device *dev) |
1311 | { | 1311 | { |
1312 | ether_setup(dev); | 1312 | ether_setup(dev); |
1313 | dev->max_mtu = 0; | ||
1313 | dev->netdev_ops = &gre_tap_netdev_ops; | 1314 | dev->netdev_ops = &gre_tap_netdev_ops; |
1314 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; | 1315 | dev->priv_flags &= ~IFF_TX_SKB_SHARING; |
1315 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | 1316 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index fe6fee728ce4..6d21068f9b55 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -349,8 +349,8 @@ static int ip_tunnel_bind_dev(struct net_device *dev) | |||
349 | dev->needed_headroom = t_hlen + hlen; | 349 | dev->needed_headroom = t_hlen + hlen; |
350 | mtu -= (dev->hard_header_len + t_hlen); | 350 | mtu -= (dev->hard_header_len + t_hlen); |
351 | 351 | ||
352 | if (mtu < 68) | 352 | if (mtu < IPV4_MIN_MTU) |
353 | mtu = 68; | 353 | mtu = IPV4_MIN_MTU; |
354 | 354 | ||
355 | return mtu; | 355 | return mtu; |
356 | } | 356 | } |
@@ -520,8 +520,7 @@ static int tnl_update_pmtu(struct net_device *dev, struct sk_buff *skb, | |||
520 | else | 520 | else |
521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; | 521 | mtu = skb_dst(skb) ? dst_mtu(skb_dst(skb)) : dev->mtu; |
522 | 522 | ||
523 | if (skb_dst(skb)) | 523 | skb_dst_update_pmtu(skb, mtu); |
524 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | ||
525 | 524 | ||
526 | if (skb->protocol == htons(ETH_P_IP)) { | 525 | if (skb->protocol == htons(ETH_P_IP)) { |
527 | if (!skb_is_gso(skb) && | 526 | if (!skb_is_gso(skb) && |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 949f432a5f04..51b1669334fe 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -200,7 +200,7 @@ static netdev_tx_t vti_xmit(struct sk_buff *skb, struct net_device *dev, | |||
200 | 200 | ||
201 | mtu = dst_mtu(dst); | 201 | mtu = dst_mtu(dst); |
202 | if (skb->len > mtu) { | 202 | if (skb->len > mtu) { |
203 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 203 | skb_dst_update_pmtu(skb, mtu); |
204 | if (skb->protocol == htons(ETH_P_IP)) { | 204 | if (skb->protocol == htons(ETH_P_IP)) { |
205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, | 205 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED, |
206 | htonl(mtu)); | 206 | htonl(mtu)); |
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index f88221aebc9d..eb8246c39de0 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -202,13 +202,8 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
202 | 202 | ||
203 | local_bh_disable(); | 203 | local_bh_disable(); |
204 | addend = xt_write_recseq_begin(); | 204 | addend = xt_write_recseq_begin(); |
205 | private = table->private; | 205 | private = READ_ONCE(table->private); /* Address dependency. */ |
206 | cpu = smp_processor_id(); | 206 | cpu = smp_processor_id(); |
207 | /* | ||
208 | * Ensure we load private-> members after we've fetched the base | ||
209 | * pointer. | ||
210 | */ | ||
211 | smp_read_barrier_depends(); | ||
212 | table_base = private->entries; | 207 | table_base = private->entries; |
213 | jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; | 208 | jumpstack = (struct arpt_entry **)private->jumpstack[cpu]; |
214 | 209 | ||
@@ -373,7 +368,6 @@ static int mark_source_chains(const struct xt_table_info *newinfo, | |||
373 | if (!xt_find_jump_offset(offsets, newpos, | 368 | if (!xt_find_jump_offset(offsets, newpos, |
374 | newinfo->number)) | 369 | newinfo->number)) |
375 | return 0; | 370 | return 0; |
376 | e = entry0 + newpos; | ||
377 | } else { | 371 | } else { |
378 | /* ... this is a fallthru */ | 372 | /* ... this is a fallthru */ |
379 | newpos = pos + e->next_offset; | 373 | newpos = pos + e->next_offset; |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 4cbe5e80f3bf..cc984d0e0c69 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -260,13 +260,8 @@ ipt_do_table(struct sk_buff *skb, | |||
260 | WARN_ON(!(table->valid_hooks & (1 << hook))); | 260 | WARN_ON(!(table->valid_hooks & (1 << hook))); |
261 | local_bh_disable(); | 261 | local_bh_disable(); |
262 | addend = xt_write_recseq_begin(); | 262 | addend = xt_write_recseq_begin(); |
263 | private = table->private; | 263 | private = READ_ONCE(table->private); /* Address dependency. */ |
264 | cpu = smp_processor_id(); | 264 | cpu = smp_processor_id(); |
265 | /* | ||
266 | * Ensure we load private-> members after we've fetched the base | ||
267 | * pointer. | ||
268 | */ | ||
269 | smp_read_barrier_depends(); | ||
270 | table_base = private->entries; | 265 | table_base = private->entries; |
271 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; | 266 | jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; |
272 | 267 | ||
@@ -439,7 +434,6 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
439 | if (!xt_find_jump_offset(offsets, newpos, | 434 | if (!xt_find_jump_offset(offsets, newpos, |
440 | newinfo->number)) | 435 | newinfo->number)) |
441 | return 0; | 436 | return 0; |
442 | e = entry0 + newpos; | ||
443 | } else { | 437 | } else { |
444 | /* ... this is a fallthru */ | 438 | /* ... this is a fallthru */ |
445 | newpos = pos + e->next_offset; | 439 | newpos = pos + e->next_offset; |
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c index 17b4ca562944..69060e3abe85 100644 --- a/net/ipv4/netfilter/ipt_CLUSTERIP.c +++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c | |||
@@ -813,12 +813,13 @@ static int clusterip_net_init(struct net *net) | |||
813 | 813 | ||
814 | static void clusterip_net_exit(struct net *net) | 814 | static void clusterip_net_exit(struct net *net) |
815 | { | 815 | { |
816 | #ifdef CONFIG_PROC_FS | ||
817 | struct clusterip_net *cn = net_generic(net, clusterip_net_id); | 816 | struct clusterip_net *cn = net_generic(net, clusterip_net_id); |
817 | #ifdef CONFIG_PROC_FS | ||
818 | proc_remove(cn->procdir); | 818 | proc_remove(cn->procdir); |
819 | cn->procdir = NULL; | 819 | cn->procdir = NULL; |
820 | #endif | 820 | #endif |
821 | nf_unregister_net_hook(net, &cip_arp_ops); | 821 | nf_unregister_net_hook(net, &cip_arp_ops); |
822 | WARN_ON_ONCE(!list_empty(&cn->configs)); | ||
822 | } | 823 | } |
823 | 824 | ||
824 | static struct pernet_operations clusterip_net_ops = { | 825 | static struct pernet_operations clusterip_net_ops = { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index 33b70bfd1122..5e570aa9e43b 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
@@ -513,11 +513,18 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
513 | int err; | 513 | int err; |
514 | struct ip_options_data opt_copy; | 514 | struct ip_options_data opt_copy; |
515 | struct raw_frag_vec rfv; | 515 | struct raw_frag_vec rfv; |
516 | int hdrincl; | ||
516 | 517 | ||
517 | err = -EMSGSIZE; | 518 | err = -EMSGSIZE; |
518 | if (len > 0xFFFF) | 519 | if (len > 0xFFFF) |
519 | goto out; | 520 | goto out; |
520 | 521 | ||
522 | /* hdrincl should be READ_ONCE(inet->hdrincl) | ||
523 | * but READ_ONCE() doesn't work with bit fields. | ||
524 | * Doing this indirectly yields the same result. | ||
525 | */ | ||
526 | hdrincl = inet->hdrincl; | ||
527 | hdrincl = READ_ONCE(hdrincl); | ||
521 | /* | 528 | /* |
522 | * Check the flags. | 529 | * Check the flags. |
523 | */ | 530 | */ |
@@ -593,7 +600,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
593 | /* Linux does not mangle headers on raw sockets, | 600 | /* Linux does not mangle headers on raw sockets, |
594 | * so that IP options + IP_HDRINCL is non-sense. | 601 | * so that IP options + IP_HDRINCL is non-sense. |
595 | */ | 602 | */ |
596 | if (inet->hdrincl) | 603 | if (hdrincl) |
597 | goto done; | 604 | goto done; |
598 | if (ipc.opt->opt.srr) { | 605 | if (ipc.opt->opt.srr) { |
599 | if (!daddr) | 606 | if (!daddr) |
@@ -615,12 +622,12 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
615 | 622 | ||
616 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, | 623 | flowi4_init_output(&fl4, ipc.oif, sk->sk_mark, tos, |
617 | RT_SCOPE_UNIVERSE, | 624 | RT_SCOPE_UNIVERSE, |
618 | inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol, | 625 | hdrincl ? IPPROTO_RAW : sk->sk_protocol, |
619 | inet_sk_flowi_flags(sk) | | 626 | inet_sk_flowi_flags(sk) | |
620 | (inet->hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), | 627 | (hdrincl ? FLOWI_FLAG_KNOWN_NH : 0), |
621 | daddr, saddr, 0, 0, sk->sk_uid); | 628 | daddr, saddr, 0, 0, sk->sk_uid); |
622 | 629 | ||
623 | if (!inet->hdrincl) { | 630 | if (!hdrincl) { |
624 | rfv.msg = msg; | 631 | rfv.msg = msg; |
625 | rfv.hlen = 0; | 632 | rfv.hlen = 0; |
626 | 633 | ||
@@ -645,7 +652,7 @@ static int raw_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) | |||
645 | goto do_confirm; | 652 | goto do_confirm; |
646 | back_from_confirm: | 653 | back_from_confirm: |
647 | 654 | ||
648 | if (inet->hdrincl) | 655 | if (hdrincl) |
649 | err = raw_send_hdrinc(sk, &fl4, msg, len, | 656 | err = raw_send_hdrinc(sk, &fl4, msg, len, |
650 | &rt, msg->msg_flags, &ipc.sockc); | 657 | &rt, msg->msg_flags, &ipc.sockc); |
651 | 658 | ||
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 43b69af242e1..4e153b23bcec 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2762,6 +2762,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
2762 | if (err == 0 && rt->dst.error) | 2762 | if (err == 0 && rt->dst.error) |
2763 | err = -rt->dst.error; | 2763 | err = -rt->dst.error; |
2764 | } else { | 2764 | } else { |
2765 | fl4.flowi4_iif = LOOPBACK_IFINDEX; | ||
2765 | rt = ip_route_output_key_hash_rcu(net, &fl4, &res, skb); | 2766 | rt = ip_route_output_key_hash_rcu(net, &fl4, &res, skb); |
2766 | err = 0; | 2767 | err = 0; |
2767 | if (IS_ERR(rt)) | 2768 | if (IS_ERR(rt)) |
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index f08eebe60446..8e053ad7cae2 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c | |||
@@ -2298,6 +2298,9 @@ adjudge_to_death: | |||
2298 | tcp_send_active_reset(sk, GFP_ATOMIC); | 2298 | tcp_send_active_reset(sk, GFP_ATOMIC); |
2299 | __NET_INC_STATS(sock_net(sk), | 2299 | __NET_INC_STATS(sock_net(sk), |
2300 | LINUX_MIB_TCPABORTONMEMORY); | 2300 | LINUX_MIB_TCPABORTONMEMORY); |
2301 | } else if (!check_net(sock_net(sk))) { | ||
2302 | /* Not possible to send reset; just close */ | ||
2303 | tcp_set_state(sk, TCP_CLOSE); | ||
2301 | } | 2304 | } |
2302 | } | 2305 | } |
2303 | 2306 | ||
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 9550cc42de2d..45f750e85714 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -508,9 +508,6 @@ static void tcp_rcv_rtt_update(struct tcp_sock *tp, u32 sample, int win_dep) | |||
508 | u32 new_sample = tp->rcv_rtt_est.rtt_us; | 508 | u32 new_sample = tp->rcv_rtt_est.rtt_us; |
509 | long m = sample; | 509 | long m = sample; |
510 | 510 | ||
511 | if (m == 0) | ||
512 | m = 1; | ||
513 | |||
514 | if (new_sample != 0) { | 511 | if (new_sample != 0) { |
515 | /* If we sample in larger samples in the non-timestamp | 512 | /* If we sample in larger samples in the non-timestamp |
516 | * case, we could grossly overestimate the RTT especially | 513 | * case, we could grossly overestimate the RTT especially |
@@ -547,6 +544,8 @@ static inline void tcp_rcv_rtt_measure(struct tcp_sock *tp) | |||
547 | if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) | 544 | if (before(tp->rcv_nxt, tp->rcv_rtt_est.seq)) |
548 | return; | 545 | return; |
549 | delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time); | 546 | delta_us = tcp_stamp_us_delta(tp->tcp_mstamp, tp->rcv_rtt_est.time); |
547 | if (!delta_us) | ||
548 | delta_us = 1; | ||
550 | tcp_rcv_rtt_update(tp, delta_us, 1); | 549 | tcp_rcv_rtt_update(tp, delta_us, 1); |
551 | 550 | ||
552 | new_measure: | 551 | new_measure: |
@@ -563,8 +562,11 @@ static inline void tcp_rcv_rtt_measure_ts(struct sock *sk, | |||
563 | (TCP_SKB_CB(skb)->end_seq - | 562 | (TCP_SKB_CB(skb)->end_seq - |
564 | TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) { | 563 | TCP_SKB_CB(skb)->seq >= inet_csk(sk)->icsk_ack.rcv_mss)) { |
565 | u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; | 564 | u32 delta = tcp_time_stamp(tp) - tp->rx_opt.rcv_tsecr; |
566 | u32 delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); | 565 | u32 delta_us; |
567 | 566 | ||
567 | if (!delta) | ||
568 | delta = 1; | ||
569 | delta_us = delta * (USEC_PER_SEC / TCP_TS_HZ); | ||
568 | tcp_rcv_rtt_update(tp, delta_us, 0); | 570 | tcp_rcv_rtt_update(tp, delta_us, 0); |
569 | } | 571 | } |
570 | } | 572 | } |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 77ea45da0fe9..94e28350f420 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -848,7 +848,7 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
848 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 848 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
849 | req->ts_recent, | 849 | req->ts_recent, |
850 | 0, | 850 | 0, |
851 | tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->daddr, | 851 | tcp_md5_do_lookup(sk, (union tcp_md5_addr *)&ip_hdr(skb)->saddr, |
852 | AF_INET), | 852 | AF_INET), |
853 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, | 853 | inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0, |
854 | ip_hdr(skb)->tos); | 854 | ip_hdr(skb)->tos); |
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c index b6a2aa1dcf56..4d58e2ce0b5b 100644 --- a/net/ipv4/tcp_offload.c +++ b/net/ipv4/tcp_offload.c | |||
@@ -32,6 +32,9 @@ static void tcp_gso_tstamp(struct sk_buff *skb, unsigned int ts_seq, | |||
32 | static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, | 32 | static struct sk_buff *tcp4_gso_segment(struct sk_buff *skb, |
33 | netdev_features_t features) | 33 | netdev_features_t features) |
34 | { | 34 | { |
35 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_TCPV4)) | ||
36 | return ERR_PTR(-EINVAL); | ||
37 | |||
35 | if (!pskb_may_pull(skb, sizeof(struct tcphdr))) | 38 | if (!pskb_may_pull(skb, sizeof(struct tcphdr))) |
36 | return ERR_PTR(-EINVAL); | 39 | return ERR_PTR(-EINVAL); |
37 | 40 | ||
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 16df6dd44b98..388158c9d9f6 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -48,11 +48,19 @@ static void tcp_write_err(struct sock *sk) | |||
48 | * to prevent DoS attacks. It is called when a retransmission timeout | 48 | * to prevent DoS attacks. It is called when a retransmission timeout |
49 | * or zero probe timeout occurs on orphaned socket. | 49 | * or zero probe timeout occurs on orphaned socket. |
50 | * | 50 | * |
51 | * Also close if our net namespace is exiting; in that case there is no | ||
52 | * hope of ever communicating again since all netns interfaces are already | ||
53 | * down (or about to be down), and we need to release our dst references, | ||
54 | * which have been moved to the netns loopback interface, so the namespace | ||
55 | * can finish exiting. This condition is only possible if we are a kernel | ||
56 | * socket, as those do not hold references to the namespace. | ||
57 | * | ||
51 | * Criteria is still not confirmed experimentally and may change. | 58 | * Criteria is still not confirmed experimentally and may change. |
52 | * We kill the socket, if: | 59 | * We kill the socket, if: |
53 | * 1. If number of orphaned sockets exceeds an administratively configured | 60 | * 1. If number of orphaned sockets exceeds an administratively configured |
54 | * limit. | 61 | * limit. |
55 | * 2. If we have strong memory pressure. | 62 | * 2. If we have strong memory pressure. |
63 | * 3. If our net namespace is exiting. | ||
56 | */ | 64 | */ |
57 | static int tcp_out_of_resources(struct sock *sk, bool do_reset) | 65 | static int tcp_out_of_resources(struct sock *sk, bool do_reset) |
58 | { | 66 | { |
@@ -81,6 +89,13 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset) | |||
81 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); | 89 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY); |
82 | return 1; | 90 | return 1; |
83 | } | 91 | } |
92 | |||
93 | if (!check_net(sock_net(sk))) { | ||
94 | /* Not possible to send reset; just close */ | ||
95 | tcp_done(sk); | ||
96 | return 1; | ||
97 | } | ||
98 | |||
84 | return 0; | 99 | return 0; |
85 | } | 100 | } |
86 | 101 | ||
@@ -264,6 +279,7 @@ void tcp_delack_timer_handler(struct sock *sk) | |||
264 | icsk->icsk_ack.pingpong = 0; | 279 | icsk->icsk_ack.pingpong = 0; |
265 | icsk->icsk_ack.ato = TCP_ATO_MIN; | 280 | icsk->icsk_ack.ato = TCP_ATO_MIN; |
266 | } | 281 | } |
282 | tcp_mstamp_refresh(tcp_sk(sk)); | ||
267 | tcp_send_ack(sk); | 283 | tcp_send_ack(sk); |
268 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKS); | 284 | __NET_INC_STATS(sock_net(sk), LINUX_MIB_DELAYEDACKS); |
269 | } | 285 | } |
@@ -632,6 +648,7 @@ static void tcp_keepalive_timer (struct timer_list *t) | |||
632 | goto out; | 648 | goto out; |
633 | } | 649 | } |
634 | 650 | ||
651 | tcp_mstamp_refresh(tp); | ||
635 | if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { | 652 | if (sk->sk_state == TCP_FIN_WAIT2 && sock_flag(sk, SOCK_DEAD)) { |
636 | if (tp->linger2 >= 0) { | 653 | if (tp->linger2 >= 0) { |
637 | const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; | 654 | const int tmo = tcp_fin_time(sk) - TCP_TIMEWAIT_LEN; |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 01801b77bd0d..ea6e6e7df0ee 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
@@ -203,6 +203,9 @@ static struct sk_buff *udp4_ufo_fragment(struct sk_buff *skb, | |||
203 | goto out; | 203 | goto out; |
204 | } | 204 | } |
205 | 205 | ||
206 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP)) | ||
207 | goto out; | ||
208 | |||
206 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 209 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
207 | goto out; | 210 | goto out; |
208 | 211 | ||
diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index e50b7fea57ee..bcfc00e88756 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c | |||
@@ -23,6 +23,12 @@ int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb) | |||
23 | return xfrm4_extract_header(skb); | 23 | return xfrm4_extract_header(skb); |
24 | } | 24 | } |
25 | 25 | ||
26 | static int xfrm4_rcv_encap_finish2(struct net *net, struct sock *sk, | ||
27 | struct sk_buff *skb) | ||
28 | { | ||
29 | return dst_input(skb); | ||
30 | } | ||
31 | |||
26 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | 32 | static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, |
27 | struct sk_buff *skb) | 33 | struct sk_buff *skb) |
28 | { | 34 | { |
@@ -33,7 +39,11 @@ static inline int xfrm4_rcv_encap_finish(struct net *net, struct sock *sk, | |||
33 | iph->tos, skb->dev)) | 39 | iph->tos, skb->dev)) |
34 | goto drop; | 40 | goto drop; |
35 | } | 41 | } |
36 | return dst_input(skb); | 42 | |
43 | if (xfrm_trans_queue(skb, xfrm4_rcv_encap_finish2)) | ||
44 | goto drop; | ||
45 | |||
46 | return 0; | ||
37 | drop: | 47 | drop: |
38 | kfree_skb(skb); | 48 | kfree_skb(skb); |
39 | return NET_RX_DROP; | 49 | return NET_RX_DROP; |
diff --git a/net/ipv4/xfrm4_mode_tunnel.c b/net/ipv4/xfrm4_mode_tunnel.c index e6265e2c274e..20ca486b3cad 100644 --- a/net/ipv4/xfrm4_mode_tunnel.c +++ b/net/ipv4/xfrm4_mode_tunnel.c | |||
@@ -92,6 +92,7 @@ static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
92 | 92 | ||
93 | skb_reset_network_header(skb); | 93 | skb_reset_network_header(skb); |
94 | skb_mac_header_rebuild(skb); | 94 | skb_mac_header_rebuild(skb); |
95 | eth_hdr(skb)->h_proto = skb->protocol; | ||
95 | 96 | ||
96 | err = 0; | 97 | err = 0; |
97 | 98 | ||
diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index c26f71234b9c..c9441ca45399 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c | |||
@@ -210,7 +210,6 @@ lookup_protocol: | |||
210 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; | 210 | np->mcast_hops = IPV6_DEFAULT_MCASTHOPS; |
211 | np->mc_loop = 1; | 211 | np->mc_loop = 1; |
212 | np->pmtudisc = IPV6_PMTUDISC_WANT; | 212 | np->pmtudisc = IPV6_PMTUDISC_WANT; |
213 | np->autoflowlabel = ip6_default_np_autolabel(net); | ||
214 | np->repflow = net->ipv6.sysctl.flowlabel_reflect; | 213 | np->repflow = net->ipv6.sysctl.flowlabel_reflect; |
215 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; | 214 | sk->sk_ipv6only = net->ipv6.sysctl.bindv6only; |
216 | 215 | ||
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c index a902ff8f59be..1a7f00cd4803 100644 --- a/net/ipv6/esp6.c +++ b/net/ipv6/esp6.c | |||
@@ -890,13 +890,12 @@ static int esp6_init_state(struct xfrm_state *x) | |||
890 | x->props.header_len += IPV4_BEET_PHMAXLEN + | 890 | x->props.header_len += IPV4_BEET_PHMAXLEN + |
891 | (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); | 891 | (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); |
892 | break; | 892 | break; |
893 | default: | ||
893 | case XFRM_MODE_TRANSPORT: | 894 | case XFRM_MODE_TRANSPORT: |
894 | break; | 895 | break; |
895 | case XFRM_MODE_TUNNEL: | 896 | case XFRM_MODE_TUNNEL: |
896 | x->props.header_len += sizeof(struct ipv6hdr); | 897 | x->props.header_len += sizeof(struct ipv6hdr); |
897 | break; | 898 | break; |
898 | default: | ||
899 | goto error; | ||
900 | } | 899 | } |
901 | 900 | ||
902 | align = ALIGN(crypto_aead_blocksize(aead), 4); | 901 | align = ALIGN(crypto_aead_blocksize(aead), 4); |
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index 333a478aa161..f52c314d4c97 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c | |||
@@ -60,7 +60,8 @@ static struct sk_buff **esp6_gro_receive(struct sk_buff **head, | |||
60 | int nhoff; | 60 | int nhoff; |
61 | int err; | 61 | int err; |
62 | 62 | ||
63 | skb_pull(skb, offset); | 63 | if (!pskb_pull(skb, offset)) |
64 | return NULL; | ||
64 | 65 | ||
65 | if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0) | 66 | if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0) |
66 | goto out; | 67 | goto out; |
@@ -148,6 +149,9 @@ static struct sk_buff *esp6_gso_segment(struct sk_buff *skb, | |||
148 | if (!xo) | 149 | if (!xo) |
149 | goto out; | 150 | goto out; |
150 | 151 | ||
152 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_ESP)) | ||
153 | goto out; | ||
154 | |||
151 | seq = xo->seq.low; | 155 | seq = xo->seq.low; |
152 | 156 | ||
153 | x = skb->sp->xvec[skb->sp->len - 1]; | 157 | x = skb->sp->xvec[skb->sp->len - 1]; |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 83bd75713535..bc68eb661970 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -925,6 +925,15 @@ static void ipv6_push_rthdr4(struct sk_buff *skb, u8 *proto, | |||
925 | sr_phdr->segments[0] = **addr_p; | 925 | sr_phdr->segments[0] = **addr_p; |
926 | *addr_p = &sr_ihdr->segments[sr_ihdr->segments_left]; | 926 | *addr_p = &sr_ihdr->segments[sr_ihdr->segments_left]; |
927 | 927 | ||
928 | if (sr_ihdr->hdrlen > hops * 2) { | ||
929 | int tlvs_offset, tlvs_length; | ||
930 | |||
931 | tlvs_offset = (1 + hops * 2) << 3; | ||
932 | tlvs_length = (sr_ihdr->hdrlen - hops * 2) << 3; | ||
933 | memcpy((char *)sr_phdr + tlvs_offset, | ||
934 | (char *)sr_ihdr + tlvs_offset, tlvs_length); | ||
935 | } | ||
936 | |||
928 | #ifdef CONFIG_IPV6_SEG6_HMAC | 937 | #ifdef CONFIG_IPV6_SEG6_HMAC |
929 | if (sr_has_hmac(sr_phdr)) { | 938 | if (sr_has_hmac(sr_phdr)) { |
930 | struct net *net = NULL; | 939 | struct net *net = NULL; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index f5285f4e1d08..217683d40f12 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -640,6 +640,11 @@ static struct fib6_node *fib6_add_1(struct net *net, | |||
640 | if (!(fn->fn_flags & RTN_RTINFO)) { | 640 | if (!(fn->fn_flags & RTN_RTINFO)) { |
641 | RCU_INIT_POINTER(fn->leaf, NULL); | 641 | RCU_INIT_POINTER(fn->leaf, NULL); |
642 | rt6_release(leaf); | 642 | rt6_release(leaf); |
643 | /* remove null_entry in the root node */ | ||
644 | } else if (fn->fn_flags & RTN_TL_ROOT && | ||
645 | rcu_access_pointer(fn->leaf) == | ||
646 | net->ipv6.ip6_null_entry) { | ||
647 | RCU_INIT_POINTER(fn->leaf, NULL); | ||
643 | } | 648 | } |
644 | 649 | ||
645 | return fn; | 650 | return fn; |
@@ -1221,8 +1226,14 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt, | |||
1221 | } | 1226 | } |
1222 | 1227 | ||
1223 | if (!rcu_access_pointer(fn->leaf)) { | 1228 | if (!rcu_access_pointer(fn->leaf)) { |
1224 | atomic_inc(&rt->rt6i_ref); | 1229 | if (fn->fn_flags & RTN_TL_ROOT) { |
1225 | rcu_assign_pointer(fn->leaf, rt); | 1230 | /* put back null_entry for root node */ |
1231 | rcu_assign_pointer(fn->leaf, | ||
1232 | info->nl_net->ipv6.ip6_null_entry); | ||
1233 | } else { | ||
1234 | atomic_inc(&rt->rt6i_ref); | ||
1235 | rcu_assign_pointer(fn->leaf, rt); | ||
1236 | } | ||
1226 | } | 1237 | } |
1227 | fn = sn; | 1238 | fn = sn; |
1228 | } | 1239 | } |
@@ -1241,23 +1252,28 @@ out: | |||
1241 | * If fib6_add_1 has cleared the old leaf pointer in the | 1252 | * If fib6_add_1 has cleared the old leaf pointer in the |
1242 | * super-tree leaf node we have to find a new one for it. | 1253 | * super-tree leaf node we have to find a new one for it. |
1243 | */ | 1254 | */ |
1244 | struct rt6_info *pn_leaf = rcu_dereference_protected(pn->leaf, | 1255 | if (pn != fn) { |
1245 | lockdep_is_held(&table->tb6_lock)); | 1256 | struct rt6_info *pn_leaf = |
1246 | if (pn != fn && pn_leaf == rt) { | 1257 | rcu_dereference_protected(pn->leaf, |
1247 | pn_leaf = NULL; | 1258 | lockdep_is_held(&table->tb6_lock)); |
1248 | RCU_INIT_POINTER(pn->leaf, NULL); | 1259 | if (pn_leaf == rt) { |
1249 | atomic_dec(&rt->rt6i_ref); | 1260 | pn_leaf = NULL; |
1250 | } | 1261 | RCU_INIT_POINTER(pn->leaf, NULL); |
1251 | if (pn != fn && !pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { | 1262 | atomic_dec(&rt->rt6i_ref); |
1252 | pn_leaf = fib6_find_prefix(info->nl_net, table, pn); | ||
1253 | #if RT6_DEBUG >= 2 | ||
1254 | if (!pn_leaf) { | ||
1255 | WARN_ON(!pn_leaf); | ||
1256 | pn_leaf = info->nl_net->ipv6.ip6_null_entry; | ||
1257 | } | 1263 | } |
1264 | if (!pn_leaf && !(pn->fn_flags & RTN_RTINFO)) { | ||
1265 | pn_leaf = fib6_find_prefix(info->nl_net, table, | ||
1266 | pn); | ||
1267 | #if RT6_DEBUG >= 2 | ||
1268 | if (!pn_leaf) { | ||
1269 | WARN_ON(!pn_leaf); | ||
1270 | pn_leaf = | ||
1271 | info->nl_net->ipv6.ip6_null_entry; | ||
1272 | } | ||
1258 | #endif | 1273 | #endif |
1259 | atomic_inc(&pn_leaf->rt6i_ref); | 1274 | atomic_inc(&pn_leaf->rt6i_ref); |
1260 | rcu_assign_pointer(pn->leaf, pn_leaf); | 1275 | rcu_assign_pointer(pn->leaf, pn_leaf); |
1276 | } | ||
1261 | } | 1277 | } |
1262 | #endif | 1278 | #endif |
1263 | goto failure; | 1279 | goto failure; |
@@ -1265,13 +1281,17 @@ out: | |||
1265 | return err; | 1281 | return err; |
1266 | 1282 | ||
1267 | failure: | 1283 | failure: |
1268 | /* fn->leaf could be NULL if fn is an intermediate node and we | 1284 | /* fn->leaf could be NULL and fib6_repair_tree() needs to be called if: |
1269 | * failed to add the new route to it in both subtree creation | 1285 | * 1. fn is an intermediate node and we failed to add the new |
1270 | * failure and fib6_add_rt2node() failure case. | 1286 | * route to it in both subtree creation failure and fib6_add_rt2node() |
1271 | * In both cases, fib6_repair_tree() should be called to fix | 1287 | * failure case. |
1272 | * fn->leaf. | 1288 | * 2. fn is the root node in the table and we fail to add the first |
1289 | * default route to it. | ||
1273 | */ | 1290 | */ |
1274 | if (fn && !(fn->fn_flags & (RTN_RTINFO|RTN_ROOT))) | 1291 | if (fn && |
1292 | (!(fn->fn_flags & (RTN_RTINFO|RTN_ROOT)) || | ||
1293 | (fn->fn_flags & RTN_TL_ROOT && | ||
1294 | !rcu_access_pointer(fn->leaf)))) | ||
1275 | fib6_repair_tree(info->nl_net, table, fn); | 1295 | fib6_repair_tree(info->nl_net, table, fn); |
1276 | /* Always release dst as dst->__refcnt is guaranteed | 1296 | /* Always release dst as dst->__refcnt is guaranteed |
1277 | * to be taken before entering this function | 1297 | * to be taken before entering this function |
@@ -1526,6 +1546,12 @@ static struct fib6_node *fib6_repair_tree(struct net *net, | |||
1526 | struct fib6_walker *w; | 1546 | struct fib6_walker *w; |
1527 | int iter = 0; | 1547 | int iter = 0; |
1528 | 1548 | ||
1549 | /* Set fn->leaf to null_entry for root node. */ | ||
1550 | if (fn->fn_flags & RTN_TL_ROOT) { | ||
1551 | rcu_assign_pointer(fn->leaf, net->ipv6.ip6_null_entry); | ||
1552 | return fn; | ||
1553 | } | ||
1554 | |||
1529 | for (;;) { | 1555 | for (;;) { |
1530 | struct fib6_node *fn_r = rcu_dereference_protected(fn->right, | 1556 | struct fib6_node *fn_r = rcu_dereference_protected(fn->right, |
1531 | lockdep_is_held(&table->tb6_lock)); | 1557 | lockdep_is_held(&table->tb6_lock)); |
@@ -1680,10 +1706,15 @@ static void fib6_del_route(struct fib6_table *table, struct fib6_node *fn, | |||
1680 | } | 1706 | } |
1681 | read_unlock(&net->ipv6.fib6_walker_lock); | 1707 | read_unlock(&net->ipv6.fib6_walker_lock); |
1682 | 1708 | ||
1683 | /* If it was last route, expunge its radix tree node */ | 1709 | /* If it was last route, call fib6_repair_tree() to: |
1710 | * 1. For root node, put back null_entry as how the table was created. | ||
1711 | * 2. For other nodes, expunge its radix tree node. | ||
1712 | */ | ||
1684 | if (!rcu_access_pointer(fn->leaf)) { | 1713 | if (!rcu_access_pointer(fn->leaf)) { |
1685 | fn->fn_flags &= ~RTN_RTINFO; | 1714 | if (!(fn->fn_flags & RTN_TL_ROOT)) { |
1686 | net->ipv6.rt6_stats->fib_route_nodes--; | 1715 | fn->fn_flags &= ~RTN_RTINFO; |
1716 | net->ipv6.rt6_stats->fib_route_nodes--; | ||
1717 | } | ||
1687 | fn = fib6_repair_tree(net, table, fn); | 1718 | fn = fib6_repair_tree(net, table, fn); |
1688 | } | 1719 | } |
1689 | 1720 | ||
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c index 4cfd8e0696fe..873549228ccb 100644 --- a/net/ipv6/ip6_gre.c +++ b/net/ipv6/ip6_gre.c | |||
@@ -337,11 +337,12 @@ static struct ip6_tnl *ip6gre_tunnel_locate(struct net *net, | |||
337 | 337 | ||
338 | nt->dev = dev; | 338 | nt->dev = dev; |
339 | nt->net = dev_net(dev); | 339 | nt->net = dev_net(dev); |
340 | ip6gre_tnl_link_config(nt, 1); | ||
341 | 340 | ||
342 | if (register_netdevice(dev) < 0) | 341 | if (register_netdevice(dev) < 0) |
343 | goto failed_free; | 342 | goto failed_free; |
344 | 343 | ||
344 | ip6gre_tnl_link_config(nt, 1); | ||
345 | |||
345 | /* Can use a lockless transmit, unless we generate output sequences */ | 346 | /* Can use a lockless transmit, unless we generate output sequences */ |
346 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) | 347 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) |
347 | dev->features |= NETIF_F_LLTX; | 348 | dev->features |= NETIF_F_LLTX; |
@@ -1014,6 +1015,36 @@ static void ip6gre_tunnel_setup(struct net_device *dev) | |||
1014 | eth_random_addr(dev->perm_addr); | 1015 | eth_random_addr(dev->perm_addr); |
1015 | } | 1016 | } |
1016 | 1017 | ||
1018 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1019 | NETIF_F_FRAGLIST | \ | ||
1020 | NETIF_F_HIGHDMA | \ | ||
1021 | NETIF_F_HW_CSUM) | ||
1022 | |||
1023 | static void ip6gre_tnl_init_features(struct net_device *dev) | ||
1024 | { | ||
1025 | struct ip6_tnl *nt = netdev_priv(dev); | ||
1026 | |||
1027 | dev->features |= GRE6_FEATURES; | ||
1028 | dev->hw_features |= GRE6_FEATURES; | ||
1029 | |||
1030 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1031 | /* TCP offload with GRE SEQ is not supported, nor | ||
1032 | * can we support 2 levels of outer headers requiring | ||
1033 | * an update. | ||
1034 | */ | ||
1035 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1036 | nt->encap.type == TUNNEL_ENCAP_NONE) { | ||
1037 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1038 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1039 | } | ||
1040 | |||
1041 | /* Can use a lockless transmit, unless we generate | ||
1042 | * output sequences | ||
1043 | */ | ||
1044 | dev->features |= NETIF_F_LLTX; | ||
1045 | } | ||
1046 | } | ||
1047 | |||
1017 | static int ip6gre_tunnel_init_common(struct net_device *dev) | 1048 | static int ip6gre_tunnel_init_common(struct net_device *dev) |
1018 | { | 1049 | { |
1019 | struct ip6_tnl *tunnel; | 1050 | struct ip6_tnl *tunnel; |
@@ -1048,6 +1079,8 @@ static int ip6gre_tunnel_init_common(struct net_device *dev) | |||
1048 | if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) | 1079 | if (!(tunnel->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT)) |
1049 | dev->mtu -= 8; | 1080 | dev->mtu -= 8; |
1050 | 1081 | ||
1082 | ip6gre_tnl_init_features(dev); | ||
1083 | |||
1051 | return 0; | 1084 | return 0; |
1052 | } | 1085 | } |
1053 | 1086 | ||
@@ -1271,7 +1304,6 @@ static void ip6gre_netlink_parms(struct nlattr *data[], | |||
1271 | 1304 | ||
1272 | static int ip6gre_tap_init(struct net_device *dev) | 1305 | static int ip6gre_tap_init(struct net_device *dev) |
1273 | { | 1306 | { |
1274 | struct ip6_tnl *tunnel; | ||
1275 | int ret; | 1307 | int ret; |
1276 | 1308 | ||
1277 | ret = ip6gre_tunnel_init_common(dev); | 1309 | ret = ip6gre_tunnel_init_common(dev); |
@@ -1280,10 +1312,6 @@ static int ip6gre_tap_init(struct net_device *dev) | |||
1280 | 1312 | ||
1281 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; | 1313 | dev->priv_flags |= IFF_LIVE_ADDR_CHANGE; |
1282 | 1314 | ||
1283 | tunnel = netdev_priv(dev); | ||
1284 | |||
1285 | ip6gre_tnl_link_config(tunnel, 1); | ||
1286 | |||
1287 | return 0; | 1315 | return 0; |
1288 | } | 1316 | } |
1289 | 1317 | ||
@@ -1298,16 +1326,12 @@ static const struct net_device_ops ip6gre_tap_netdev_ops = { | |||
1298 | .ndo_get_iflink = ip6_tnl_get_iflink, | 1326 | .ndo_get_iflink = ip6_tnl_get_iflink, |
1299 | }; | 1327 | }; |
1300 | 1328 | ||
1301 | #define GRE6_FEATURES (NETIF_F_SG | \ | ||
1302 | NETIF_F_FRAGLIST | \ | ||
1303 | NETIF_F_HIGHDMA | \ | ||
1304 | NETIF_F_HW_CSUM) | ||
1305 | |||
1306 | static void ip6gre_tap_setup(struct net_device *dev) | 1329 | static void ip6gre_tap_setup(struct net_device *dev) |
1307 | { | 1330 | { |
1308 | 1331 | ||
1309 | ether_setup(dev); | 1332 | ether_setup(dev); |
1310 | 1333 | ||
1334 | dev->max_mtu = 0; | ||
1311 | dev->netdev_ops = &ip6gre_tap_netdev_ops; | 1335 | dev->netdev_ops = &ip6gre_tap_netdev_ops; |
1312 | dev->needs_free_netdev = true; | 1336 | dev->needs_free_netdev = true; |
1313 | dev->priv_destructor = ip6gre_dev_free; | 1337 | dev->priv_destructor = ip6gre_dev_free; |
@@ -1380,32 +1404,16 @@ static int ip6gre_newlink(struct net *src_net, struct net_device *dev, | |||
1380 | 1404 | ||
1381 | nt->dev = dev; | 1405 | nt->dev = dev; |
1382 | nt->net = dev_net(dev); | 1406 | nt->net = dev_net(dev); |
1383 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); | ||
1384 | |||
1385 | dev->features |= GRE6_FEATURES; | ||
1386 | dev->hw_features |= GRE6_FEATURES; | ||
1387 | |||
1388 | if (!(nt->parms.o_flags & TUNNEL_SEQ)) { | ||
1389 | /* TCP offload with GRE SEQ is not supported, nor | ||
1390 | * can we support 2 levels of outer headers requiring | ||
1391 | * an update. | ||
1392 | */ | ||
1393 | if (!(nt->parms.o_flags & TUNNEL_CSUM) || | ||
1394 | (nt->encap.type == TUNNEL_ENCAP_NONE)) { | ||
1395 | dev->features |= NETIF_F_GSO_SOFTWARE; | ||
1396 | dev->hw_features |= NETIF_F_GSO_SOFTWARE; | ||
1397 | } | ||
1398 | |||
1399 | /* Can use a lockless transmit, unless we generate | ||
1400 | * output sequences | ||
1401 | */ | ||
1402 | dev->features |= NETIF_F_LLTX; | ||
1403 | } | ||
1404 | 1407 | ||
1405 | err = register_netdevice(dev); | 1408 | err = register_netdevice(dev); |
1406 | if (err) | 1409 | if (err) |
1407 | goto out; | 1410 | goto out; |
1408 | 1411 | ||
1412 | ip6gre_tnl_link_config(nt, !tb[IFLA_MTU]); | ||
1413 | |||
1414 | if (tb[IFLA_MTU]) | ||
1415 | ip6_tnl_change_mtu(dev, nla_get_u32(tb[IFLA_MTU])); | ||
1416 | |||
1409 | dev_hold(dev); | 1417 | dev_hold(dev); |
1410 | ip6gre_tunnel_link(ign, nt); | 1418 | ip6gre_tunnel_link(ign, nt); |
1411 | 1419 | ||
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 5110a418cc4d..3763dc01e374 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -166,6 +166,14 @@ int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
166 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); | 166 | !(IP6CB(skb)->flags & IP6SKB_REROUTED)); |
167 | } | 167 | } |
168 | 168 | ||
169 | bool ip6_autoflowlabel(struct net *net, const struct ipv6_pinfo *np) | ||
170 | { | ||
171 | if (!np->autoflowlabel_set) | ||
172 | return ip6_default_np_autolabel(net); | ||
173 | else | ||
174 | return np->autoflowlabel; | ||
175 | } | ||
176 | |||
169 | /* | 177 | /* |
170 | * xmit an sk_buff (used by TCP, SCTP and DCCP) | 178 | * xmit an sk_buff (used by TCP, SCTP and DCCP) |
171 | * Note : socket lock is not held for SYNACK packets, but might be modified | 179 | * Note : socket lock is not held for SYNACK packets, but might be modified |
@@ -230,7 +238,7 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | |||
230 | hlimit = ip6_dst_hoplimit(dst); | 238 | hlimit = ip6_dst_hoplimit(dst); |
231 | 239 | ||
232 | ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, | 240 | ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, |
233 | np->autoflowlabel, fl6)); | 241 | ip6_autoflowlabel(net, np), fl6)); |
234 | 242 | ||
235 | hdr->payload_len = htons(seg_len); | 243 | hdr->payload_len = htons(seg_len); |
236 | hdr->nexthdr = proto; | 244 | hdr->nexthdr = proto; |
@@ -1198,14 +1206,16 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork, | |||
1198 | v6_cork->tclass = ipc6->tclass; | 1206 | v6_cork->tclass = ipc6->tclass; |
1199 | if (rt->dst.flags & DST_XFRM_TUNNEL) | 1207 | if (rt->dst.flags & DST_XFRM_TUNNEL) |
1200 | mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? | 1208 | mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? |
1201 | rt->dst.dev->mtu : dst_mtu(&rt->dst); | 1209 | READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); |
1202 | else | 1210 | else |
1203 | mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? | 1211 | mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ? |
1204 | rt->dst.dev->mtu : dst_mtu(rt->dst.path); | 1212 | READ_ONCE(rt->dst.dev->mtu) : dst_mtu(rt->dst.path); |
1205 | if (np->frag_size < mtu) { | 1213 | if (np->frag_size < mtu) { |
1206 | if (np->frag_size) | 1214 | if (np->frag_size) |
1207 | mtu = np->frag_size; | 1215 | mtu = np->frag_size; |
1208 | } | 1216 | } |
1217 | if (mtu < IPV6_MIN_MTU) | ||
1218 | return -EINVAL; | ||
1209 | cork->base.fragsize = mtu; | 1219 | cork->base.fragsize = mtu; |
1210 | if (dst_allfrag(rt->dst.path)) | 1220 | if (dst_allfrag(rt->dst.path)) |
1211 | cork->base.flags |= IPCORK_ALLFRAG; | 1221 | cork->base.flags |= IPCORK_ALLFRAG; |
@@ -1626,7 +1636,7 @@ struct sk_buff *__ip6_make_skb(struct sock *sk, | |||
1626 | 1636 | ||
1627 | ip6_flow_hdr(hdr, v6_cork->tclass, | 1637 | ip6_flow_hdr(hdr, v6_cork->tclass, |
1628 | ip6_make_flowlabel(net, skb, fl6->flowlabel, | 1638 | ip6_make_flowlabel(net, skb, fl6->flowlabel, |
1629 | np->autoflowlabel, fl6)); | 1639 | ip6_autoflowlabel(net, np), fl6)); |
1630 | hdr->hop_limit = v6_cork->hop_limit; | 1640 | hdr->hop_limit = v6_cork->hop_limit; |
1631 | hdr->nexthdr = proto; | 1641 | hdr->nexthdr = proto; |
1632 | hdr->saddr = fl6->saddr; | 1642 | hdr->saddr = fl6->saddr; |
@@ -1725,11 +1735,13 @@ struct sk_buff *ip6_make_skb(struct sock *sk, | |||
1725 | cork.base.flags = 0; | 1735 | cork.base.flags = 0; |
1726 | cork.base.addr = 0; | 1736 | cork.base.addr = 0; |
1727 | cork.base.opt = NULL; | 1737 | cork.base.opt = NULL; |
1738 | cork.base.dst = NULL; | ||
1728 | v6_cork.opt = NULL; | 1739 | v6_cork.opt = NULL; |
1729 | err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); | 1740 | err = ip6_setup_cork(sk, &cork, &v6_cork, ipc6, rt, fl6); |
1730 | if (err) | 1741 | if (err) { |
1742 | ip6_cork_release(&cork, &v6_cork); | ||
1731 | return ERR_PTR(err); | 1743 | return ERR_PTR(err); |
1732 | 1744 | } | |
1733 | if (ipc6->dontfrag < 0) | 1745 | if (ipc6->dontfrag < 0) |
1734 | ipc6->dontfrag = inet6_sk(sk)->dontfrag; | 1746 | ipc6->dontfrag = inet6_sk(sk)->dontfrag; |
1735 | 1747 | ||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c index db84f523656d..1ee5584c3555 100644 --- a/net/ipv6/ip6_tunnel.c +++ b/net/ipv6/ip6_tunnel.c | |||
@@ -642,8 +642,7 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
642 | if (rel_info > dst_mtu(skb_dst(skb2))) | 642 | if (rel_info > dst_mtu(skb_dst(skb2))) |
643 | goto out; | 643 | goto out; |
644 | 644 | ||
645 | skb_dst(skb2)->ops->update_pmtu(skb_dst(skb2), NULL, skb2, | 645 | skb_dst_update_pmtu(skb2, rel_info); |
646 | rel_info); | ||
647 | } | 646 | } |
648 | 647 | ||
649 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); | 648 | icmp_send(skb2, rel_type, rel_code, htonl(rel_info)); |
@@ -1074,10 +1073,11 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield, | |||
1074 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); | 1073 | memcpy(&fl6->daddr, addr6, sizeof(fl6->daddr)); |
1075 | neigh_release(neigh); | 1074 | neigh_release(neigh); |
1076 | } | 1075 | } |
1077 | } else if (!(t->parms.flags & | 1076 | } else if (t->parms.proto != 0 && !(t->parms.flags & |
1078 | (IP6_TNL_F_USE_ORIG_TCLASS | IP6_TNL_F_USE_ORIG_FWMARK))) { | 1077 | (IP6_TNL_F_USE_ORIG_TCLASS | |
1079 | /* enable the cache only only if the routing decision does | 1078 | IP6_TNL_F_USE_ORIG_FWMARK))) { |
1080 | * not depend on the current inner header value | 1079 | /* enable the cache only if neither the outer protocol nor the |
1080 | * routing decision depends on the current inner header value | ||
1081 | */ | 1081 | */ |
1082 | use_cache = true; | 1082 | use_cache = true; |
1083 | } | 1083 | } |
@@ -1123,10 +1123,14 @@ route_lookup: | |||
1123 | max_headroom += 8; | 1123 | max_headroom += 8; |
1124 | mtu -= 8; | 1124 | mtu -= 8; |
1125 | } | 1125 | } |
1126 | if (mtu < IPV6_MIN_MTU) | 1126 | if (skb->protocol == htons(ETH_P_IPV6)) { |
1127 | mtu = IPV6_MIN_MTU; | 1127 | if (mtu < IPV6_MIN_MTU) |
1128 | if (skb_dst(skb) && !t->parms.collect_md) | 1128 | mtu = IPV6_MIN_MTU; |
1129 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 1129 | } else if (mtu < 576) { |
1130 | mtu = 576; | ||
1131 | } | ||
1132 | |||
1133 | skb_dst_update_pmtu(skb, mtu); | ||
1130 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { | 1134 | if (skb->len - t->tun_hlen - eth_hlen > mtu && !skb_is_gso(skb)) { |
1131 | *pmtu = mtu; | 1135 | *pmtu = mtu; |
1132 | err = -EMSGSIZE; | 1136 | err = -EMSGSIZE; |
@@ -1671,11 +1675,11 @@ int ip6_tnl_change_mtu(struct net_device *dev, int new_mtu) | |||
1671 | { | 1675 | { |
1672 | struct ip6_tnl *tnl = netdev_priv(dev); | 1676 | struct ip6_tnl *tnl = netdev_priv(dev); |
1673 | 1677 | ||
1674 | if (tnl->parms.proto == IPPROTO_IPIP) { | 1678 | if (tnl->parms.proto == IPPROTO_IPV6) { |
1675 | if (new_mtu < ETH_MIN_MTU) | 1679 | if (new_mtu < IPV6_MIN_MTU) |
1676 | return -EINVAL; | 1680 | return -EINVAL; |
1677 | } else { | 1681 | } else { |
1678 | if (new_mtu < IPV6_MIN_MTU) | 1682 | if (new_mtu < ETH_MIN_MTU) |
1679 | return -EINVAL; | 1683 | return -EINVAL; |
1680 | } | 1684 | } |
1681 | if (new_mtu > 0xFFF8 - dev->hard_header_len) | 1685 | if (new_mtu > 0xFFF8 - dev->hard_header_len) |
diff --git a/net/ipv6/ip6_vti.c b/net/ipv6/ip6_vti.c index dbb74f3c57a7..8c184f84f353 100644 --- a/net/ipv6/ip6_vti.c +++ b/net/ipv6/ip6_vti.c | |||
@@ -483,7 +483,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl) | |||
483 | 483 | ||
484 | mtu = dst_mtu(dst); | 484 | mtu = dst_mtu(dst); |
485 | if (!skb->ignore_df && skb->len > mtu) { | 485 | if (!skb->ignore_df && skb->len > mtu) { |
486 | skb_dst(skb)->ops->update_pmtu(dst, NULL, skb, mtu); | 486 | skb_dst_update_pmtu(skb, mtu); |
487 | 487 | ||
488 | if (skb->protocol == htons(ETH_P_IPV6)) { | 488 | if (skb->protocol == htons(ETH_P_IPV6)) { |
489 | if (mtu < IPV6_MIN_MTU) | 489 | if (mtu < IPV6_MIN_MTU) |
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index b9404feabd78..e8ffb5b5d84e 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c | |||
@@ -886,6 +886,7 @@ pref_skip_coa: | |||
886 | break; | 886 | break; |
887 | case IPV6_AUTOFLOWLABEL: | 887 | case IPV6_AUTOFLOWLABEL: |
888 | np->autoflowlabel = valbool; | 888 | np->autoflowlabel = valbool; |
889 | np->autoflowlabel_set = 1; | ||
889 | retv = 0; | 890 | retv = 0; |
890 | break; | 891 | break; |
891 | case IPV6_RECVFRAGSIZE: | 892 | case IPV6_RECVFRAGSIZE: |
@@ -1335,7 +1336,7 @@ static int do_ipv6_getsockopt(struct sock *sk, int level, int optname, | |||
1335 | break; | 1336 | break; |
1336 | 1337 | ||
1337 | case IPV6_AUTOFLOWLABEL: | 1338 | case IPV6_AUTOFLOWLABEL: |
1338 | val = np->autoflowlabel; | 1339 | val = ip6_autoflowlabel(sock_net(sk), np); |
1339 | break; | 1340 | break; |
1340 | 1341 | ||
1341 | case IPV6_RECVFRAGSIZE: | 1342 | case IPV6_RECVFRAGSIZE: |
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index fc6d7d143f2c..844642682b83 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c | |||
@@ -1682,16 +1682,16 @@ static int grec_size(struct ifmcaddr6 *pmc, int type, int gdel, int sdel) | |||
1682 | } | 1682 | } |
1683 | 1683 | ||
1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, | 1684 | static struct sk_buff *add_grhead(struct sk_buff *skb, struct ifmcaddr6 *pmc, |
1685 | int type, struct mld2_grec **ppgr) | 1685 | int type, struct mld2_grec **ppgr, unsigned int mtu) |
1686 | { | 1686 | { |
1687 | struct net_device *dev = pmc->idev->dev; | ||
1688 | struct mld2_report *pmr; | 1687 | struct mld2_report *pmr; |
1689 | struct mld2_grec *pgr; | 1688 | struct mld2_grec *pgr; |
1690 | 1689 | ||
1691 | if (!skb) | 1690 | if (!skb) { |
1692 | skb = mld_newpack(pmc->idev, dev->mtu); | 1691 | skb = mld_newpack(pmc->idev, mtu); |
1693 | if (!skb) | 1692 | if (!skb) |
1694 | return NULL; | 1693 | return NULL; |
1694 | } | ||
1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); | 1695 | pgr = skb_put(skb, sizeof(struct mld2_grec)); |
1696 | pgr->grec_type = type; | 1696 | pgr->grec_type = type; |
1697 | pgr->grec_auxwords = 0; | 1697 | pgr->grec_auxwords = 0; |
@@ -1714,10 +1714,15 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1714 | struct mld2_grec *pgr = NULL; | 1714 | struct mld2_grec *pgr = NULL; |
1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; | 1715 | struct ip6_sf_list *psf, *psf_next, *psf_prev, **psf_list; |
1716 | int scount, stotal, first, isquery, truncate; | 1716 | int scount, stotal, first, isquery, truncate; |
1717 | unsigned int mtu; | ||
1717 | 1718 | ||
1718 | if (pmc->mca_flags & MAF_NOREPORT) | 1719 | if (pmc->mca_flags & MAF_NOREPORT) |
1719 | return skb; | 1720 | return skb; |
1720 | 1721 | ||
1722 | mtu = READ_ONCE(dev->mtu); | ||
1723 | if (mtu < IPV6_MIN_MTU) | ||
1724 | return skb; | ||
1725 | |||
1721 | isquery = type == MLD2_MODE_IS_INCLUDE || | 1726 | isquery = type == MLD2_MODE_IS_INCLUDE || |
1722 | type == MLD2_MODE_IS_EXCLUDE; | 1727 | type == MLD2_MODE_IS_EXCLUDE; |
1723 | truncate = type == MLD2_MODE_IS_EXCLUDE || | 1728 | truncate = type == MLD2_MODE_IS_EXCLUDE || |
@@ -1738,7 +1743,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1738 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { | 1743 | AVAILABLE(skb) < grec_size(pmc, type, gdeleted, sdeleted)) { |
1739 | if (skb) | 1744 | if (skb) |
1740 | mld_sendpack(skb); | 1745 | mld_sendpack(skb); |
1741 | skb = mld_newpack(idev, dev->mtu); | 1746 | skb = mld_newpack(idev, mtu); |
1742 | } | 1747 | } |
1743 | } | 1748 | } |
1744 | first = 1; | 1749 | first = 1; |
@@ -1774,12 +1779,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ifmcaddr6 *pmc, | |||
1774 | pgr->grec_nsrcs = htons(scount); | 1779 | pgr->grec_nsrcs = htons(scount); |
1775 | if (skb) | 1780 | if (skb) |
1776 | mld_sendpack(skb); | 1781 | mld_sendpack(skb); |
1777 | skb = mld_newpack(idev, dev->mtu); | 1782 | skb = mld_newpack(idev, mtu); |
1778 | first = 1; | 1783 | first = 1; |
1779 | scount = 0; | 1784 | scount = 0; |
1780 | } | 1785 | } |
1781 | if (first) { | 1786 | if (first) { |
1782 | skb = add_grhead(skb, pmc, type, &pgr); | 1787 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1783 | first = 0; | 1788 | first = 0; |
1784 | } | 1789 | } |
1785 | if (!skb) | 1790 | if (!skb) |
@@ -1814,7 +1819,7 @@ empty_source: | |||
1814 | mld_sendpack(skb); | 1819 | mld_sendpack(skb); |
1815 | skb = NULL; /* add_grhead will get a new one */ | 1820 | skb = NULL; /* add_grhead will get a new one */ |
1816 | } | 1821 | } |
1817 | skb = add_grhead(skb, pmc, type, &pgr); | 1822 | skb = add_grhead(skb, pmc, type, &pgr, mtu); |
1818 | } | 1823 | } |
1819 | } | 1824 | } |
1820 | if (pgr) | 1825 | if (pgr) |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index f06e25065a34..66a8c69a3db4 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -282,12 +282,7 @@ ip6t_do_table(struct sk_buff *skb, | |||
282 | 282 | ||
283 | local_bh_disable(); | 283 | local_bh_disable(); |
284 | addend = xt_write_recseq_begin(); | 284 | addend = xt_write_recseq_begin(); |
285 | private = table->private; | 285 | private = READ_ONCE(table->private); /* Address dependency. */ |
286 | /* | ||
287 | * Ensure we load private-> members after we've fetched the base | ||
288 | * pointer. | ||
289 | */ | ||
290 | smp_read_barrier_depends(); | ||
291 | cpu = smp_processor_id(); | 286 | cpu = smp_processor_id(); |
292 | table_base = private->entries; | 287 | table_base = private->entries; |
293 | jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; | 288 | jumpstack = (struct ip6t_entry **)private->jumpstack[cpu]; |
@@ -458,7 +453,6 @@ mark_source_chains(const struct xt_table_info *newinfo, | |||
458 | if (!xt_find_jump_offset(offsets, newpos, | 453 | if (!xt_find_jump_offset(offsets, newpos, |
459 | newinfo->number)) | 454 | newinfo->number)) |
460 | return 0; | 455 | return 0; |
461 | e = entry0 + newpos; | ||
462 | } else { | 456 | } else { |
463 | /* ... this is a fallthru */ | 457 | /* ... this is a fallthru */ |
464 | newpos = pos + e->next_offset; | 458 | newpos = pos + e->next_offset; |
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c index 2b1a15846f9a..92c0047e7e33 100644 --- a/net/ipv6/netfilter/ip6t_MASQUERADE.c +++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c | |||
@@ -33,13 +33,19 @@ static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par) | |||
33 | 33 | ||
34 | if (range->flags & NF_NAT_RANGE_MAP_IPS) | 34 | if (range->flags & NF_NAT_RANGE_MAP_IPS) |
35 | return -EINVAL; | 35 | return -EINVAL; |
36 | return 0; | 36 | return nf_ct_netns_get(par->net, par->family); |
37 | } | ||
38 | |||
39 | static void masquerade_tg6_destroy(const struct xt_tgdtor_param *par) | ||
40 | { | ||
41 | nf_ct_netns_put(par->net, par->family); | ||
37 | } | 42 | } |
38 | 43 | ||
39 | static struct xt_target masquerade_tg6_reg __read_mostly = { | 44 | static struct xt_target masquerade_tg6_reg __read_mostly = { |
40 | .name = "MASQUERADE", | 45 | .name = "MASQUERADE", |
41 | .family = NFPROTO_IPV6, | 46 | .family = NFPROTO_IPV6, |
42 | .checkentry = masquerade_tg6_checkentry, | 47 | .checkentry = masquerade_tg6_checkentry, |
48 | .destroy = masquerade_tg6_destroy, | ||
43 | .target = masquerade_tg6, | 49 | .target = masquerade_tg6, |
44 | .targetsize = sizeof(struct nf_nat_range), | 50 | .targetsize = sizeof(struct nf_nat_range), |
45 | .table = "nat", | 51 | .table = "nat", |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7a8d1500d374..0458b761f3c5 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -2336,6 +2336,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | |||
2336 | } | 2336 | } |
2337 | 2337 | ||
2338 | rt->dst.flags |= DST_HOST; | 2338 | rt->dst.flags |= DST_HOST; |
2339 | rt->dst.input = ip6_input; | ||
2339 | rt->dst.output = ip6_output; | 2340 | rt->dst.output = ip6_output; |
2340 | rt->rt6i_gateway = fl6->daddr; | 2341 | rt->rt6i_gateway = fl6->daddr; |
2341 | rt->rt6i_dst.addr = fl6->daddr; | 2342 | rt->rt6i_dst.addr = fl6->daddr; |
@@ -4297,19 +4298,13 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
4297 | if (!ipv6_addr_any(&fl6.saddr)) | 4298 | if (!ipv6_addr_any(&fl6.saddr)) |
4298 | flags |= RT6_LOOKUP_F_HAS_SADDR; | 4299 | flags |= RT6_LOOKUP_F_HAS_SADDR; |
4299 | 4300 | ||
4300 | if (!fibmatch) | 4301 | dst = ip6_route_input_lookup(net, dev, &fl6, flags); |
4301 | dst = ip6_route_input_lookup(net, dev, &fl6, flags); | ||
4302 | else | ||
4303 | dst = ip6_route_lookup(net, &fl6, 0); | ||
4304 | 4302 | ||
4305 | rcu_read_unlock(); | 4303 | rcu_read_unlock(); |
4306 | } else { | 4304 | } else { |
4307 | fl6.flowi6_oif = oif; | 4305 | fl6.flowi6_oif = oif; |
4308 | 4306 | ||
4309 | if (!fibmatch) | 4307 | dst = ip6_route_output(net, NULL, &fl6); |
4310 | dst = ip6_route_output(net, NULL, &fl6); | ||
4311 | else | ||
4312 | dst = ip6_route_lookup(net, &fl6, 0); | ||
4313 | } | 4308 | } |
4314 | 4309 | ||
4315 | 4310 | ||
@@ -4326,6 +4321,15 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
4326 | goto errout; | 4321 | goto errout; |
4327 | } | 4322 | } |
4328 | 4323 | ||
4324 | if (fibmatch && rt->dst.from) { | ||
4325 | struct rt6_info *ort = container_of(rt->dst.from, | ||
4326 | struct rt6_info, dst); | ||
4327 | |||
4328 | dst_hold(&ort->dst); | ||
4329 | ip6_rt_put(rt); | ||
4330 | rt = ort; | ||
4331 | } | ||
4332 | |||
4329 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 4333 | skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
4330 | if (!skb) { | 4334 | if (!skb) { |
4331 | ip6_rt_put(rt); | 4335 | ip6_rt_put(rt); |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index d7dc23c1b2ca..3873d3877135 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
@@ -934,8 +934,8 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb, | |||
934 | df = 0; | 934 | df = 0; |
935 | } | 935 | } |
936 | 936 | ||
937 | if (tunnel->parms.iph.daddr && skb_dst(skb)) | 937 | if (tunnel->parms.iph.daddr) |
938 | skb_dst(skb)->ops->update_pmtu(skb_dst(skb), NULL, skb, mtu); | 938 | skb_dst_update_pmtu(skb, mtu); |
939 | 939 | ||
940 | if (skb->len > mtu && !skb_is_gso(skb)) { | 940 | if (skb->len > mtu && !skb_is_gso(skb)) { |
941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); | 941 | icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); |
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 1f04ec0e4a7a..7178476b3d2f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -994,7 +994,7 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb, | |||
994 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, | 994 | req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale, |
995 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, | 995 | tcp_time_stamp_raw() + tcp_rsk(req)->ts_off, |
996 | req->ts_recent, sk->sk_bound_dev_if, | 996 | req->ts_recent, sk->sk_bound_dev_if, |
997 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->daddr), | 997 | tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr), |
998 | 0, 0); | 998 | 0, 0); |
999 | } | 999 | } |
1000 | 1000 | ||
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c index d883c9204c01..278e49cd67d4 100644 --- a/net/ipv6/tcpv6_offload.c +++ b/net/ipv6/tcpv6_offload.c | |||
@@ -46,6 +46,9 @@ static struct sk_buff *tcp6_gso_segment(struct sk_buff *skb, | |||
46 | { | 46 | { |
47 | struct tcphdr *th; | 47 | struct tcphdr *th; |
48 | 48 | ||
49 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_TCPV6)) | ||
50 | return ERR_PTR(-EINVAL); | ||
51 | |||
49 | if (!pskb_may_pull(skb, sizeof(*th))) | 52 | if (!pskb_may_pull(skb, sizeof(*th))) |
50 | return ERR_PTR(-EINVAL); | 53 | return ERR_PTR(-EINVAL); |
51 | 54 | ||
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index a0f89ad76f9d..2a04dc9c781b 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -42,6 +42,9 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
42 | const struct ipv6hdr *ipv6h; | 42 | const struct ipv6hdr *ipv6h; |
43 | struct udphdr *uh; | 43 | struct udphdr *uh; |
44 | 44 | ||
45 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_UDP)) | ||
46 | goto out; | ||
47 | |||
45 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) | 48 | if (!pskb_may_pull(skb, sizeof(struct udphdr))) |
46 | goto out; | 49 | goto out; |
47 | 50 | ||
diff --git a/net/ipv6/xfrm6_input.c b/net/ipv6/xfrm6_input.c index fe04e23af986..841f4a07438e 100644 --- a/net/ipv6/xfrm6_input.c +++ b/net/ipv6/xfrm6_input.c | |||
@@ -32,6 +32,14 @@ int xfrm6_rcv_spi(struct sk_buff *skb, int nexthdr, __be32 spi, | |||
32 | } | 32 | } |
33 | EXPORT_SYMBOL(xfrm6_rcv_spi); | 33 | EXPORT_SYMBOL(xfrm6_rcv_spi); |
34 | 34 | ||
35 | static int xfrm6_transport_finish2(struct net *net, struct sock *sk, | ||
36 | struct sk_buff *skb) | ||
37 | { | ||
38 | if (xfrm_trans_queue(skb, ip6_rcv_finish)) | ||
39 | __kfree_skb(skb); | ||
40 | return -1; | ||
41 | } | ||
42 | |||
35 | int xfrm6_transport_finish(struct sk_buff *skb, int async) | 43 | int xfrm6_transport_finish(struct sk_buff *skb, int async) |
36 | { | 44 | { |
37 | struct xfrm_offload *xo = xfrm_offload(skb); | 45 | struct xfrm_offload *xo = xfrm_offload(skb); |
@@ -56,7 +64,7 @@ int xfrm6_transport_finish(struct sk_buff *skb, int async) | |||
56 | 64 | ||
57 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, | 65 | NF_HOOK(NFPROTO_IPV6, NF_INET_PRE_ROUTING, |
58 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, | 66 | dev_net(skb->dev), NULL, skb, skb->dev, NULL, |
59 | ip6_rcv_finish); | 67 | xfrm6_transport_finish2); |
60 | return -1; | 68 | return -1; |
61 | } | 69 | } |
62 | 70 | ||
diff --git a/net/ipv6/xfrm6_mode_tunnel.c b/net/ipv6/xfrm6_mode_tunnel.c index 02556e356f87..dc93002ff9d1 100644 --- a/net/ipv6/xfrm6_mode_tunnel.c +++ b/net/ipv6/xfrm6_mode_tunnel.c | |||
@@ -92,6 +92,7 @@ static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb) | |||
92 | 92 | ||
93 | skb_reset_network_header(skb); | 93 | skb_reset_network_header(skb); |
94 | skb_mac_header_rebuild(skb); | 94 | skb_mac_header_rebuild(skb); |
95 | eth_hdr(skb)->h_proto = skb->protocol; | ||
95 | 96 | ||
96 | err = 0; | 97 | err = 0; |
97 | 98 | ||
diff --git a/net/kcm/kcmsock.c b/net/kcm/kcmsock.c index d4e98f20fc2a..4a8d407f8902 100644 --- a/net/kcm/kcmsock.c +++ b/net/kcm/kcmsock.c | |||
@@ -1387,8 +1387,13 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
1387 | if (!csk) | 1387 | if (!csk) |
1388 | return -EINVAL; | 1388 | return -EINVAL; |
1389 | 1389 | ||
1390 | /* We must prevent loops or risk deadlock ! */ | 1390 | /* Only allow TCP sockets to be attached for now */ |
1391 | if (csk->sk_family == PF_KCM) | 1391 | if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) || |
1392 | csk->sk_protocol != IPPROTO_TCP) | ||
1393 | return -EOPNOTSUPP; | ||
1394 | |||
1395 | /* Don't allow listeners or closed sockets */ | ||
1396 | if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) | ||
1392 | return -EOPNOTSUPP; | 1397 | return -EOPNOTSUPP; |
1393 | 1398 | ||
1394 | psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); | 1399 | psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL); |
@@ -1405,9 +1410,18 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
1405 | return err; | 1410 | return err; |
1406 | } | 1411 | } |
1407 | 1412 | ||
1408 | sock_hold(csk); | ||
1409 | |||
1410 | write_lock_bh(&csk->sk_callback_lock); | 1413 | write_lock_bh(&csk->sk_callback_lock); |
1414 | |||
1415 | /* Check if sk_user_data is aready by KCM or someone else. | ||
1416 | * Must be done under lock to prevent race conditions. | ||
1417 | */ | ||
1418 | if (csk->sk_user_data) { | ||
1419 | write_unlock_bh(&csk->sk_callback_lock); | ||
1420 | strp_done(&psock->strp); | ||
1421 | kmem_cache_free(kcm_psockp, psock); | ||
1422 | return -EALREADY; | ||
1423 | } | ||
1424 | |||
1411 | psock->save_data_ready = csk->sk_data_ready; | 1425 | psock->save_data_ready = csk->sk_data_ready; |
1412 | psock->save_write_space = csk->sk_write_space; | 1426 | psock->save_write_space = csk->sk_write_space; |
1413 | psock->save_state_change = csk->sk_state_change; | 1427 | psock->save_state_change = csk->sk_state_change; |
@@ -1415,8 +1429,11 @@ static int kcm_attach(struct socket *sock, struct socket *csock, | |||
1415 | csk->sk_data_ready = psock_data_ready; | 1429 | csk->sk_data_ready = psock_data_ready; |
1416 | csk->sk_write_space = psock_write_space; | 1430 | csk->sk_write_space = psock_write_space; |
1417 | csk->sk_state_change = psock_state_change; | 1431 | csk->sk_state_change = psock_state_change; |
1432 | |||
1418 | write_unlock_bh(&csk->sk_callback_lock); | 1433 | write_unlock_bh(&csk->sk_callback_lock); |
1419 | 1434 | ||
1435 | sock_hold(csk); | ||
1436 | |||
1420 | /* Finished initialization, now add the psock to the MUX. */ | 1437 | /* Finished initialization, now add the psock to the MUX. */ |
1421 | spin_lock_bh(&mux->lock); | 1438 | spin_lock_bh(&mux->lock); |
1422 | head = &mux->psocks; | 1439 | head = &mux->psocks; |
diff --git a/net/key/af_key.c b/net/key/af_key.c index 3dffb892d52c..7e2e7188e7f4 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -401,6 +401,11 @@ static int verify_address_len(const void *p) | |||
401 | #endif | 401 | #endif |
402 | int len; | 402 | int len; |
403 | 403 | ||
404 | if (sp->sadb_address_len < | ||
405 | DIV_ROUND_UP(sizeof(*sp) + offsetofend(typeof(*addr), sa_family), | ||
406 | sizeof(uint64_t))) | ||
407 | return -EINVAL; | ||
408 | |||
404 | switch (addr->sa_family) { | 409 | switch (addr->sa_family) { |
405 | case AF_INET: | 410 | case AF_INET: |
406 | len = DIV_ROUND_UP(sizeof(*sp) + sizeof(*sin), sizeof(uint64_t)); | 411 | len = DIV_ROUND_UP(sizeof(*sp) + sizeof(*sin), sizeof(uint64_t)); |
@@ -511,6 +516,9 @@ static int parse_exthdrs(struct sk_buff *skb, const struct sadb_msg *hdr, void * | |||
511 | uint16_t ext_type; | 516 | uint16_t ext_type; |
512 | int ext_len; | 517 | int ext_len; |
513 | 518 | ||
519 | if (len < sizeof(*ehdr)) | ||
520 | return -EINVAL; | ||
521 | |||
514 | ext_len = ehdr->sadb_ext_len; | 522 | ext_len = ehdr->sadb_ext_len; |
515 | ext_len *= sizeof(uint64_t); | 523 | ext_len *= sizeof(uint64_t); |
516 | ext_type = ehdr->sadb_ext_type; | 524 | ext_type = ehdr->sadb_ext_type; |
@@ -2194,8 +2202,10 @@ static int key_notify_policy(struct xfrm_policy *xp, int dir, const struct km_ev | |||
2194 | return PTR_ERR(out_skb); | 2202 | return PTR_ERR(out_skb); |
2195 | 2203 | ||
2196 | err = pfkey_xfrm_policy2msg(out_skb, xp, dir); | 2204 | err = pfkey_xfrm_policy2msg(out_skb, xp, dir); |
2197 | if (err < 0) | 2205 | if (err < 0) { |
2206 | kfree_skb(out_skb); | ||
2198 | return err; | 2207 | return err; |
2208 | } | ||
2199 | 2209 | ||
2200 | out_hdr = (struct sadb_msg *) out_skb->data; | 2210 | out_hdr = (struct sadb_msg *) out_skb->data; |
2201 | out_hdr->sadb_msg_version = PF_KEY_V2; | 2211 | out_hdr->sadb_msg_version = PF_KEY_V2; |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index 167f83b853e6..1621b6ab17ba 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
@@ -291,16 +291,15 @@ void ieee80211_sta_tear_down_BA_sessions(struct sta_info *sta, | |||
291 | int i; | 291 | int i; |
292 | 292 | ||
293 | mutex_lock(&sta->ampdu_mlme.mtx); | 293 | mutex_lock(&sta->ampdu_mlme.mtx); |
294 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) { | 294 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
295 | ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, | 295 | ___ieee80211_stop_rx_ba_session(sta, i, WLAN_BACK_RECIPIENT, |
296 | WLAN_REASON_QSTA_LEAVE_QBSS, | 296 | WLAN_REASON_QSTA_LEAVE_QBSS, |
297 | reason != AGG_STOP_DESTROY_STA && | 297 | reason != AGG_STOP_DESTROY_STA && |
298 | reason != AGG_STOP_PEER_REQUEST); | 298 | reason != AGG_STOP_PEER_REQUEST); |
299 | } | ||
300 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
301 | 299 | ||
302 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) | 300 | for (i = 0; i < IEEE80211_NUM_TIDS; i++) |
303 | ___ieee80211_stop_tx_ba_session(sta, i, reason); | 301 | ___ieee80211_stop_tx_ba_session(sta, i, reason); |
302 | mutex_unlock(&sta->ampdu_mlme.mtx); | ||
304 | 303 | ||
305 | /* stopping might queue the work again - so cancel only afterwards */ | 304 | /* stopping might queue the work again - so cancel only afterwards */ |
306 | cancel_work_sync(&sta->ampdu_mlme.work); | 305 | cancel_work_sync(&sta->ampdu_mlme.work); |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 70e9d2ca8bbe..4daafb07602f 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -3632,6 +3632,8 @@ static bool ieee80211_accept_frame(struct ieee80211_rx_data *rx) | |||
3632 | } | 3632 | } |
3633 | return true; | 3633 | return true; |
3634 | case NL80211_IFTYPE_MESH_POINT: | 3634 | case NL80211_IFTYPE_MESH_POINT: |
3635 | if (ether_addr_equal(sdata->vif.addr, hdr->addr2)) | ||
3636 | return false; | ||
3635 | if (multicast) | 3637 | if (multicast) |
3636 | return true; | 3638 | return true; |
3637 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); | 3639 | return ether_addr_equal(sdata->vif.addr, hdr->addr1); |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index 85f643c1e227..4efaa3066c78 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -1044,7 +1044,7 @@ static void gc_worker(struct work_struct *work) | |||
1044 | * we will just continue with next hash slot. | 1044 | * we will just continue with next hash slot. |
1045 | */ | 1045 | */ |
1046 | rcu_read_unlock(); | 1046 | rcu_read_unlock(); |
1047 | cond_resched_rcu_qs(); | 1047 | cond_resched(); |
1048 | } while (++buckets < goal); | 1048 | } while (++buckets < goal); |
1049 | 1049 | ||
1050 | if (gc_work->exiting) | 1050 | if (gc_work->exiting) |
diff --git a/net/netfilter/nf_conntrack_h323_asn1.c b/net/netfilter/nf_conntrack_h323_asn1.c index cf1bf2605c10..dc6347342e34 100644 --- a/net/netfilter/nf_conntrack_h323_asn1.c +++ b/net/netfilter/nf_conntrack_h323_asn1.c | |||
@@ -103,7 +103,6 @@ struct bitstr { | |||
103 | #define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;} | 103 | #define INC_BIT(bs) if((++(bs)->bit)>7){(bs)->cur++;(bs)->bit=0;} |
104 | #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;} | 104 | #define INC_BITS(bs,b) if(((bs)->bit+=(b))>7){(bs)->cur+=(bs)->bit>>3;(bs)->bit&=7;} |
105 | #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;} | 105 | #define BYTE_ALIGN(bs) if((bs)->bit){(bs)->cur++;(bs)->bit=0;} |
106 | #define CHECK_BOUND(bs,n) if((bs)->cur+(n)>(bs)->end)return(H323_ERROR_BOUND) | ||
107 | static unsigned int get_len(struct bitstr *bs); | 106 | static unsigned int get_len(struct bitstr *bs); |
108 | static unsigned int get_bit(struct bitstr *bs); | 107 | static unsigned int get_bit(struct bitstr *bs); |
109 | static unsigned int get_bits(struct bitstr *bs, unsigned int b); | 108 | static unsigned int get_bits(struct bitstr *bs, unsigned int b); |
@@ -165,6 +164,19 @@ static unsigned int get_len(struct bitstr *bs) | |||
165 | return v; | 164 | return v; |
166 | } | 165 | } |
167 | 166 | ||
167 | static int nf_h323_error_boundary(struct bitstr *bs, size_t bytes, size_t bits) | ||
168 | { | ||
169 | bits += bs->bit; | ||
170 | bytes += bits / BITS_PER_BYTE; | ||
171 | if (bits % BITS_PER_BYTE > 0) | ||
172 | bytes++; | ||
173 | |||
174 | if (*bs->cur + bytes > *bs->end) | ||
175 | return 1; | ||
176 | |||
177 | return 0; | ||
178 | } | ||
179 | |||
168 | /****************************************************************************/ | 180 | /****************************************************************************/ |
169 | static unsigned int get_bit(struct bitstr *bs) | 181 | static unsigned int get_bit(struct bitstr *bs) |
170 | { | 182 | { |
@@ -279,8 +291,8 @@ static int decode_bool(struct bitstr *bs, const struct field_t *f, | |||
279 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 291 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
280 | 292 | ||
281 | INC_BIT(bs); | 293 | INC_BIT(bs); |
282 | 294 | if (nf_h323_error_boundary(bs, 0, 0)) | |
283 | CHECK_BOUND(bs, 0); | 295 | return H323_ERROR_BOUND; |
284 | return H323_ERROR_NONE; | 296 | return H323_ERROR_NONE; |
285 | } | 297 | } |
286 | 298 | ||
@@ -293,11 +305,14 @@ static int decode_oid(struct bitstr *bs, const struct field_t *f, | |||
293 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 305 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
294 | 306 | ||
295 | BYTE_ALIGN(bs); | 307 | BYTE_ALIGN(bs); |
296 | CHECK_BOUND(bs, 1); | 308 | if (nf_h323_error_boundary(bs, 1, 0)) |
309 | return H323_ERROR_BOUND; | ||
310 | |||
297 | len = *bs->cur++; | 311 | len = *bs->cur++; |
298 | bs->cur += len; | 312 | bs->cur += len; |
313 | if (nf_h323_error_boundary(bs, 0, 0)) | ||
314 | return H323_ERROR_BOUND; | ||
299 | 315 | ||
300 | CHECK_BOUND(bs, 0); | ||
301 | return H323_ERROR_NONE; | 316 | return H323_ERROR_NONE; |
302 | } | 317 | } |
303 | 318 | ||
@@ -319,6 +334,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
319 | bs->cur += 2; | 334 | bs->cur += 2; |
320 | break; | 335 | break; |
321 | case CONS: /* 64K < Range < 4G */ | 336 | case CONS: /* 64K < Range < 4G */ |
337 | if (nf_h323_error_boundary(bs, 0, 2)) | ||
338 | return H323_ERROR_BOUND; | ||
322 | len = get_bits(bs, 2) + 1; | 339 | len = get_bits(bs, 2) + 1; |
323 | BYTE_ALIGN(bs); | 340 | BYTE_ALIGN(bs); |
324 | if (base && (f->attr & DECODE)) { /* timeToLive */ | 341 | if (base && (f->attr & DECODE)) { /* timeToLive */ |
@@ -330,7 +347,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
330 | break; | 347 | break; |
331 | case UNCO: | 348 | case UNCO: |
332 | BYTE_ALIGN(bs); | 349 | BYTE_ALIGN(bs); |
333 | CHECK_BOUND(bs, 2); | 350 | if (nf_h323_error_boundary(bs, 2, 0)) |
351 | return H323_ERROR_BOUND; | ||
334 | len = get_len(bs); | 352 | len = get_len(bs); |
335 | bs->cur += len; | 353 | bs->cur += len; |
336 | break; | 354 | break; |
@@ -341,7 +359,8 @@ static int decode_int(struct bitstr *bs, const struct field_t *f, | |||
341 | 359 | ||
342 | PRINT("\n"); | 360 | PRINT("\n"); |
343 | 361 | ||
344 | CHECK_BOUND(bs, 0); | 362 | if (nf_h323_error_boundary(bs, 0, 0)) |
363 | return H323_ERROR_BOUND; | ||
345 | return H323_ERROR_NONE; | 364 | return H323_ERROR_NONE; |
346 | } | 365 | } |
347 | 366 | ||
@@ -357,7 +376,8 @@ static int decode_enum(struct bitstr *bs, const struct field_t *f, | |||
357 | INC_BITS(bs, f->sz); | 376 | INC_BITS(bs, f->sz); |
358 | } | 377 | } |
359 | 378 | ||
360 | CHECK_BOUND(bs, 0); | 379 | if (nf_h323_error_boundary(bs, 0, 0)) |
380 | return H323_ERROR_BOUND; | ||
361 | return H323_ERROR_NONE; | 381 | return H323_ERROR_NONE; |
362 | } | 382 | } |
363 | 383 | ||
@@ -375,12 +395,14 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f, | |||
375 | len = f->lb; | 395 | len = f->lb; |
376 | break; | 396 | break; |
377 | case WORD: /* 2-byte length */ | 397 | case WORD: /* 2-byte length */ |
378 | CHECK_BOUND(bs, 2); | 398 | if (nf_h323_error_boundary(bs, 2, 0)) |
399 | return H323_ERROR_BOUND; | ||
379 | len = (*bs->cur++) << 8; | 400 | len = (*bs->cur++) << 8; |
380 | len += (*bs->cur++) + f->lb; | 401 | len += (*bs->cur++) + f->lb; |
381 | break; | 402 | break; |
382 | case SEMI: | 403 | case SEMI: |
383 | CHECK_BOUND(bs, 2); | 404 | if (nf_h323_error_boundary(bs, 2, 0)) |
405 | return H323_ERROR_BOUND; | ||
384 | len = get_len(bs); | 406 | len = get_len(bs); |
385 | break; | 407 | break; |
386 | default: | 408 | default: |
@@ -391,7 +413,8 @@ static int decode_bitstr(struct bitstr *bs, const struct field_t *f, | |||
391 | bs->cur += len >> 3; | 413 | bs->cur += len >> 3; |
392 | bs->bit = len & 7; | 414 | bs->bit = len & 7; |
393 | 415 | ||
394 | CHECK_BOUND(bs, 0); | 416 | if (nf_h323_error_boundary(bs, 0, 0)) |
417 | return H323_ERROR_BOUND; | ||
395 | return H323_ERROR_NONE; | 418 | return H323_ERROR_NONE; |
396 | } | 419 | } |
397 | 420 | ||
@@ -404,12 +427,15 @@ static int decode_numstr(struct bitstr *bs, const struct field_t *f, | |||
404 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); | 427 | PRINT("%*.s%s\n", level * TAB_SIZE, " ", f->name); |
405 | 428 | ||
406 | /* 2 <= Range <= 255 */ | 429 | /* 2 <= Range <= 255 */ |
430 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
431 | return H323_ERROR_BOUND; | ||
407 | len = get_bits(bs, f->sz) + f->lb; | 432 | len = get_bits(bs, f->sz) + f->lb; |
408 | 433 | ||
409 | BYTE_ALIGN(bs); | 434 | BYTE_ALIGN(bs); |
410 | INC_BITS(bs, (len << 2)); | 435 | INC_BITS(bs, (len << 2)); |
411 | 436 | ||
412 | CHECK_BOUND(bs, 0); | 437 | if (nf_h323_error_boundary(bs, 0, 0)) |
438 | return H323_ERROR_BOUND; | ||
413 | return H323_ERROR_NONE; | 439 | return H323_ERROR_NONE; |
414 | } | 440 | } |
415 | 441 | ||
@@ -440,15 +466,19 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f, | |||
440 | break; | 466 | break; |
441 | case BYTE: /* Range == 256 */ | 467 | case BYTE: /* Range == 256 */ |
442 | BYTE_ALIGN(bs); | 468 | BYTE_ALIGN(bs); |
443 | CHECK_BOUND(bs, 1); | 469 | if (nf_h323_error_boundary(bs, 1, 0)) |
470 | return H323_ERROR_BOUND; | ||
444 | len = (*bs->cur++) + f->lb; | 471 | len = (*bs->cur++) + f->lb; |
445 | break; | 472 | break; |
446 | case SEMI: | 473 | case SEMI: |
447 | BYTE_ALIGN(bs); | 474 | BYTE_ALIGN(bs); |
448 | CHECK_BOUND(bs, 2); | 475 | if (nf_h323_error_boundary(bs, 2, 0)) |
476 | return H323_ERROR_BOUND; | ||
449 | len = get_len(bs) + f->lb; | 477 | len = get_len(bs) + f->lb; |
450 | break; | 478 | break; |
451 | default: /* 2 <= Range <= 255 */ | 479 | default: /* 2 <= Range <= 255 */ |
480 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
481 | return H323_ERROR_BOUND; | ||
452 | len = get_bits(bs, f->sz) + f->lb; | 482 | len = get_bits(bs, f->sz) + f->lb; |
453 | BYTE_ALIGN(bs); | 483 | BYTE_ALIGN(bs); |
454 | break; | 484 | break; |
@@ -458,7 +488,8 @@ static int decode_octstr(struct bitstr *bs, const struct field_t *f, | |||
458 | 488 | ||
459 | PRINT("\n"); | 489 | PRINT("\n"); |
460 | 490 | ||
461 | CHECK_BOUND(bs, 0); | 491 | if (nf_h323_error_boundary(bs, 0, 0)) |
492 | return H323_ERROR_BOUND; | ||
462 | return H323_ERROR_NONE; | 493 | return H323_ERROR_NONE; |
463 | } | 494 | } |
464 | 495 | ||
@@ -473,10 +504,13 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, | |||
473 | switch (f->sz) { | 504 | switch (f->sz) { |
474 | case BYTE: /* Range == 256 */ | 505 | case BYTE: /* Range == 256 */ |
475 | BYTE_ALIGN(bs); | 506 | BYTE_ALIGN(bs); |
476 | CHECK_BOUND(bs, 1); | 507 | if (nf_h323_error_boundary(bs, 1, 0)) |
508 | return H323_ERROR_BOUND; | ||
477 | len = (*bs->cur++) + f->lb; | 509 | len = (*bs->cur++) + f->lb; |
478 | break; | 510 | break; |
479 | default: /* 2 <= Range <= 255 */ | 511 | default: /* 2 <= Range <= 255 */ |
512 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
513 | return H323_ERROR_BOUND; | ||
480 | len = get_bits(bs, f->sz) + f->lb; | 514 | len = get_bits(bs, f->sz) + f->lb; |
481 | BYTE_ALIGN(bs); | 515 | BYTE_ALIGN(bs); |
482 | break; | 516 | break; |
@@ -484,7 +518,8 @@ static int decode_bmpstr(struct bitstr *bs, const struct field_t *f, | |||
484 | 518 | ||
485 | bs->cur += len << 1; | 519 | bs->cur += len << 1; |
486 | 520 | ||
487 | CHECK_BOUND(bs, 0); | 521 | if (nf_h323_error_boundary(bs, 0, 0)) |
522 | return H323_ERROR_BOUND; | ||
488 | return H323_ERROR_NONE; | 523 | return H323_ERROR_NONE; |
489 | } | 524 | } |
490 | 525 | ||
@@ -503,9 +538,13 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
503 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; | 538 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; |
504 | 539 | ||
505 | /* Extensible? */ | 540 | /* Extensible? */ |
541 | if (nf_h323_error_boundary(bs, 0, 1)) | ||
542 | return H323_ERROR_BOUND; | ||
506 | ext = (f->attr & EXT) ? get_bit(bs) : 0; | 543 | ext = (f->attr & EXT) ? get_bit(bs) : 0; |
507 | 544 | ||
508 | /* Get fields bitmap */ | 545 | /* Get fields bitmap */ |
546 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
547 | return H323_ERROR_BOUND; | ||
509 | bmp = get_bitmap(bs, f->sz); | 548 | bmp = get_bitmap(bs, f->sz); |
510 | if (base) | 549 | if (base) |
511 | *(unsigned int *)base = bmp; | 550 | *(unsigned int *)base = bmp; |
@@ -525,9 +564,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
525 | 564 | ||
526 | /* Decode */ | 565 | /* Decode */ |
527 | if (son->attr & OPEN) { /* Open field */ | 566 | if (son->attr & OPEN) { /* Open field */ |
528 | CHECK_BOUND(bs, 2); | 567 | if (nf_h323_error_boundary(bs, 2, 0)) |
568 | return H323_ERROR_BOUND; | ||
529 | len = get_len(bs); | 569 | len = get_len(bs); |
530 | CHECK_BOUND(bs, len); | 570 | if (nf_h323_error_boundary(bs, len, 0)) |
571 | return H323_ERROR_BOUND; | ||
531 | if (!base || !(son->attr & DECODE)) { | 572 | if (!base || !(son->attr & DECODE)) { |
532 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, | 573 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, |
533 | " ", son->name); | 574 | " ", son->name); |
@@ -555,8 +596,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
555 | return H323_ERROR_NONE; | 596 | return H323_ERROR_NONE; |
556 | 597 | ||
557 | /* Get the extension bitmap */ | 598 | /* Get the extension bitmap */ |
599 | if (nf_h323_error_boundary(bs, 0, 7)) | ||
600 | return H323_ERROR_BOUND; | ||
558 | bmp2_len = get_bits(bs, 7) + 1; | 601 | bmp2_len = get_bits(bs, 7) + 1; |
559 | CHECK_BOUND(bs, (bmp2_len + 7) >> 3); | 602 | if (nf_h323_error_boundary(bs, 0, bmp2_len)) |
603 | return H323_ERROR_BOUND; | ||
560 | bmp2 = get_bitmap(bs, bmp2_len); | 604 | bmp2 = get_bitmap(bs, bmp2_len); |
561 | bmp |= bmp2 >> f->sz; | 605 | bmp |= bmp2 >> f->sz; |
562 | if (base) | 606 | if (base) |
@@ -567,9 +611,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
567 | for (opt = 0; opt < bmp2_len; opt++, i++, son++) { | 611 | for (opt = 0; opt < bmp2_len; opt++, i++, son++) { |
568 | /* Check Range */ | 612 | /* Check Range */ |
569 | if (i >= f->ub) { /* Newer Version? */ | 613 | if (i >= f->ub) { /* Newer Version? */ |
570 | CHECK_BOUND(bs, 2); | 614 | if (nf_h323_error_boundary(bs, 2, 0)) |
615 | return H323_ERROR_BOUND; | ||
571 | len = get_len(bs); | 616 | len = get_len(bs); |
572 | CHECK_BOUND(bs, len); | 617 | if (nf_h323_error_boundary(bs, len, 0)) |
618 | return H323_ERROR_BOUND; | ||
573 | bs->cur += len; | 619 | bs->cur += len; |
574 | continue; | 620 | continue; |
575 | } | 621 | } |
@@ -583,9 +629,11 @@ static int decode_seq(struct bitstr *bs, const struct field_t *f, | |||
583 | if (!((0x80000000 >> opt) & bmp2)) /* Not present */ | 629 | if (!((0x80000000 >> opt) & bmp2)) /* Not present */ |
584 | continue; | 630 | continue; |
585 | 631 | ||
586 | CHECK_BOUND(bs, 2); | 632 | if (nf_h323_error_boundary(bs, 2, 0)) |
633 | return H323_ERROR_BOUND; | ||
587 | len = get_len(bs); | 634 | len = get_len(bs); |
588 | CHECK_BOUND(bs, len); | 635 | if (nf_h323_error_boundary(bs, len, 0)) |
636 | return H323_ERROR_BOUND; | ||
589 | if (!base || !(son->attr & DECODE)) { | 637 | if (!base || !(son->attr & DECODE)) { |
590 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", | 638 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", |
591 | son->name); | 639 | son->name); |
@@ -623,22 +671,27 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f, | |||
623 | switch (f->sz) { | 671 | switch (f->sz) { |
624 | case BYTE: | 672 | case BYTE: |
625 | BYTE_ALIGN(bs); | 673 | BYTE_ALIGN(bs); |
626 | CHECK_BOUND(bs, 1); | 674 | if (nf_h323_error_boundary(bs, 1, 0)) |
675 | return H323_ERROR_BOUND; | ||
627 | count = *bs->cur++; | 676 | count = *bs->cur++; |
628 | break; | 677 | break; |
629 | case WORD: | 678 | case WORD: |
630 | BYTE_ALIGN(bs); | 679 | BYTE_ALIGN(bs); |
631 | CHECK_BOUND(bs, 2); | 680 | if (nf_h323_error_boundary(bs, 2, 0)) |
681 | return H323_ERROR_BOUND; | ||
632 | count = *bs->cur++; | 682 | count = *bs->cur++; |
633 | count <<= 8; | 683 | count <<= 8; |
634 | count += *bs->cur++; | 684 | count += *bs->cur++; |
635 | break; | 685 | break; |
636 | case SEMI: | 686 | case SEMI: |
637 | BYTE_ALIGN(bs); | 687 | BYTE_ALIGN(bs); |
638 | CHECK_BOUND(bs, 2); | 688 | if (nf_h323_error_boundary(bs, 2, 0)) |
689 | return H323_ERROR_BOUND; | ||
639 | count = get_len(bs); | 690 | count = get_len(bs); |
640 | break; | 691 | break; |
641 | default: | 692 | default: |
693 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
694 | return H323_ERROR_BOUND; | ||
642 | count = get_bits(bs, f->sz); | 695 | count = get_bits(bs, f->sz); |
643 | break; | 696 | break; |
644 | } | 697 | } |
@@ -658,8 +711,11 @@ static int decode_seqof(struct bitstr *bs, const struct field_t *f, | |||
658 | for (i = 0; i < count; i++) { | 711 | for (i = 0; i < count; i++) { |
659 | if (son->attr & OPEN) { | 712 | if (son->attr & OPEN) { |
660 | BYTE_ALIGN(bs); | 713 | BYTE_ALIGN(bs); |
714 | if (nf_h323_error_boundary(bs, 2, 0)) | ||
715 | return H323_ERROR_BOUND; | ||
661 | len = get_len(bs); | 716 | len = get_len(bs); |
662 | CHECK_BOUND(bs, len); | 717 | if (nf_h323_error_boundary(bs, len, 0)) |
718 | return H323_ERROR_BOUND; | ||
663 | if (!base || !(son->attr & DECODE)) { | 719 | if (!base || !(son->attr & DECODE)) { |
664 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, | 720 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, |
665 | " ", son->name); | 721 | " ", son->name); |
@@ -710,11 +766,17 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
710 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; | 766 | base = (base && (f->attr & DECODE)) ? base + f->offset : NULL; |
711 | 767 | ||
712 | /* Decode the choice index number */ | 768 | /* Decode the choice index number */ |
769 | if (nf_h323_error_boundary(bs, 0, 1)) | ||
770 | return H323_ERROR_BOUND; | ||
713 | if ((f->attr & EXT) && get_bit(bs)) { | 771 | if ((f->attr & EXT) && get_bit(bs)) { |
714 | ext = 1; | 772 | ext = 1; |
773 | if (nf_h323_error_boundary(bs, 0, 7)) | ||
774 | return H323_ERROR_BOUND; | ||
715 | type = get_bits(bs, 7) + f->lb; | 775 | type = get_bits(bs, 7) + f->lb; |
716 | } else { | 776 | } else { |
717 | ext = 0; | 777 | ext = 0; |
778 | if (nf_h323_error_boundary(bs, 0, f->sz)) | ||
779 | return H323_ERROR_BOUND; | ||
718 | type = get_bits(bs, f->sz); | 780 | type = get_bits(bs, f->sz); |
719 | if (type >= f->lb) | 781 | if (type >= f->lb) |
720 | return H323_ERROR_RANGE; | 782 | return H323_ERROR_RANGE; |
@@ -727,8 +789,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
727 | /* Check Range */ | 789 | /* Check Range */ |
728 | if (type >= f->ub) { /* Newer version? */ | 790 | if (type >= f->ub) { /* Newer version? */ |
729 | BYTE_ALIGN(bs); | 791 | BYTE_ALIGN(bs); |
792 | if (nf_h323_error_boundary(bs, 2, 0)) | ||
793 | return H323_ERROR_BOUND; | ||
730 | len = get_len(bs); | 794 | len = get_len(bs); |
731 | CHECK_BOUND(bs, len); | 795 | if (nf_h323_error_boundary(bs, len, 0)) |
796 | return H323_ERROR_BOUND; | ||
732 | bs->cur += len; | 797 | bs->cur += len; |
733 | return H323_ERROR_NONE; | 798 | return H323_ERROR_NONE; |
734 | } | 799 | } |
@@ -742,8 +807,11 @@ static int decode_choice(struct bitstr *bs, const struct field_t *f, | |||
742 | 807 | ||
743 | if (ext || (son->attr & OPEN)) { | 808 | if (ext || (son->attr & OPEN)) { |
744 | BYTE_ALIGN(bs); | 809 | BYTE_ALIGN(bs); |
810 | if (nf_h323_error_boundary(bs, len, 0)) | ||
811 | return H323_ERROR_BOUND; | ||
745 | len = get_len(bs); | 812 | len = get_len(bs); |
746 | CHECK_BOUND(bs, len); | 813 | if (nf_h323_error_boundary(bs, len, 0)) |
814 | return H323_ERROR_BOUND; | ||
747 | if (!base || !(son->attr & DECODE)) { | 815 | if (!base || !(son->attr & DECODE)) { |
748 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", | 816 | PRINT("%*.s%s\n", (level + 1) * TAB_SIZE, " ", |
749 | son->name); | 817 | son->name); |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 59c08997bfdf..382d49792f42 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <net/netfilter/nf_conntrack_zones.h> | 45 | #include <net/netfilter/nf_conntrack_zones.h> |
46 | #include <net/netfilter/nf_conntrack_timestamp.h> | 46 | #include <net/netfilter/nf_conntrack_timestamp.h> |
47 | #include <net/netfilter/nf_conntrack_labels.h> | 47 | #include <net/netfilter/nf_conntrack_labels.h> |
48 | #include <net/netfilter/nf_conntrack_seqadj.h> | ||
49 | #include <net/netfilter/nf_conntrack_synproxy.h> | 48 | #include <net/netfilter/nf_conntrack_synproxy.h> |
50 | #ifdef CONFIG_NF_NAT_NEEDED | 49 | #ifdef CONFIG_NF_NAT_NEEDED |
51 | #include <net/netfilter/nf_nat_core.h> | 50 | #include <net/netfilter/nf_nat_core.h> |
@@ -1566,9 +1565,11 @@ static int ctnetlink_change_helper(struct nf_conn *ct, | |||
1566 | static int ctnetlink_change_timeout(struct nf_conn *ct, | 1565 | static int ctnetlink_change_timeout(struct nf_conn *ct, |
1567 | const struct nlattr * const cda[]) | 1566 | const struct nlattr * const cda[]) |
1568 | { | 1567 | { |
1569 | u_int32_t timeout = ntohl(nla_get_be32(cda[CTA_TIMEOUT])); | 1568 | u64 timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; |
1570 | 1569 | ||
1571 | ct->timeout = nfct_time_stamp + timeout * HZ; | 1570 | if (timeout > INT_MAX) |
1571 | timeout = INT_MAX; | ||
1572 | ct->timeout = nfct_time_stamp + (u32)timeout; | ||
1572 | 1573 | ||
1573 | if (test_bit(IPS_DYING_BIT, &ct->status)) | 1574 | if (test_bit(IPS_DYING_BIT, &ct->status)) |
1574 | return -ETIME; | 1575 | return -ETIME; |
@@ -1768,6 +1769,7 @@ ctnetlink_create_conntrack(struct net *net, | |||
1768 | int err = -EINVAL; | 1769 | int err = -EINVAL; |
1769 | struct nf_conntrack_helper *helper; | 1770 | struct nf_conntrack_helper *helper; |
1770 | struct nf_conn_tstamp *tstamp; | 1771 | struct nf_conn_tstamp *tstamp; |
1772 | u64 timeout; | ||
1771 | 1773 | ||
1772 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); | 1774 | ct = nf_conntrack_alloc(net, zone, otuple, rtuple, GFP_ATOMIC); |
1773 | if (IS_ERR(ct)) | 1775 | if (IS_ERR(ct)) |
@@ -1776,7 +1778,10 @@ ctnetlink_create_conntrack(struct net *net, | |||
1776 | if (!cda[CTA_TIMEOUT]) | 1778 | if (!cda[CTA_TIMEOUT]) |
1777 | goto err1; | 1779 | goto err1; |
1778 | 1780 | ||
1779 | ct->timeout = nfct_time_stamp + ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; | 1781 | timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ; |
1782 | if (timeout > INT_MAX) | ||
1783 | timeout = INT_MAX; | ||
1784 | ct->timeout = (u32)timeout + nfct_time_stamp; | ||
1780 | 1785 | ||
1781 | rcu_read_lock(); | 1786 | rcu_read_lock(); |
1782 | if (cda[CTA_HELP]) { | 1787 | if (cda[CTA_HELP]) { |
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c b/net/netfilter/nf_conntrack_proto_tcp.c index b12fc07111d0..37ef35b861f2 100644 --- a/net/netfilter/nf_conntrack_proto_tcp.c +++ b/net/netfilter/nf_conntrack_proto_tcp.c | |||
@@ -1039,6 +1039,9 @@ static int tcp_packet(struct nf_conn *ct, | |||
1039 | IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && | 1039 | IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED && |
1040 | timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) | 1040 | timeouts[new_state] > timeouts[TCP_CONNTRACK_UNACK]) |
1041 | timeout = timeouts[TCP_CONNTRACK_UNACK]; | 1041 | timeout = timeouts[TCP_CONNTRACK_UNACK]; |
1042 | else if (ct->proto.tcp.last_win == 0 && | ||
1043 | timeouts[new_state] > timeouts[TCP_CONNTRACK_RETRANS]) | ||
1044 | timeout = timeouts[TCP_CONNTRACK_RETRANS]; | ||
1042 | else | 1045 | else |
1043 | timeout = timeouts[new_state]; | 1046 | timeout = timeouts[new_state]; |
1044 | spin_unlock_bh(&ct->lock); | 1047 | spin_unlock_bh(&ct->lock); |
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c index d8327b43e4dc..07bd4138c84e 100644 --- a/net/netfilter/nf_tables_api.c +++ b/net/netfilter/nf_tables_api.c | |||
@@ -2072,7 +2072,7 @@ static int nf_tables_dump_rules(struct sk_buff *skb, | |||
2072 | continue; | 2072 | continue; |
2073 | 2073 | ||
2074 | list_for_each_entry_rcu(chain, &table->chains, list) { | 2074 | list_for_each_entry_rcu(chain, &table->chains, list) { |
2075 | if (ctx && ctx->chain[0] && | 2075 | if (ctx && ctx->chain && |
2076 | strcmp(ctx->chain, chain->name) != 0) | 2076 | strcmp(ctx->chain, chain->name) != 0) |
2077 | continue; | 2077 | continue; |
2078 | 2078 | ||
@@ -4665,8 +4665,10 @@ static int nf_tables_dump_obj_done(struct netlink_callback *cb) | |||
4665 | { | 4665 | { |
4666 | struct nft_obj_filter *filter = cb->data; | 4666 | struct nft_obj_filter *filter = cb->data; |
4667 | 4667 | ||
4668 | kfree(filter->table); | 4668 | if (filter) { |
4669 | kfree(filter); | 4669 | kfree(filter->table); |
4670 | kfree(filter); | ||
4671 | } | ||
4670 | 4672 | ||
4671 | return 0; | 4673 | return 0; |
4672 | } | 4674 | } |
@@ -5847,6 +5849,12 @@ static int __net_init nf_tables_init_net(struct net *net) | |||
5847 | return 0; | 5849 | return 0; |
5848 | } | 5850 | } |
5849 | 5851 | ||
5852 | static void __net_exit nf_tables_exit_net(struct net *net) | ||
5853 | { | ||
5854 | WARN_ON_ONCE(!list_empty(&net->nft.af_info)); | ||
5855 | WARN_ON_ONCE(!list_empty(&net->nft.commit_list)); | ||
5856 | } | ||
5857 | |||
5850 | int __nft_release_basechain(struct nft_ctx *ctx) | 5858 | int __nft_release_basechain(struct nft_ctx *ctx) |
5851 | { | 5859 | { |
5852 | struct nft_rule *rule, *nr; | 5860 | struct nft_rule *rule, *nr; |
@@ -5917,6 +5925,7 @@ static void __nft_release_afinfo(struct net *net, struct nft_af_info *afi) | |||
5917 | 5925 | ||
5918 | static struct pernet_operations nf_tables_net_ops = { | 5926 | static struct pernet_operations nf_tables_net_ops = { |
5919 | .init = nf_tables_init_net, | 5927 | .init = nf_tables_init_net, |
5928 | .exit = nf_tables_exit_net, | ||
5920 | }; | 5929 | }; |
5921 | 5930 | ||
5922 | static int __init nf_tables_module_init(void) | 5931 | static int __init nf_tables_module_init(void) |
diff --git a/net/netfilter/nfnetlink_cthelper.c b/net/netfilter/nfnetlink_cthelper.c index 41628b393673..d33ce6d5ebce 100644 --- a/net/netfilter/nfnetlink_cthelper.c +++ b/net/netfilter/nfnetlink_cthelper.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/list.h> | 18 | #include <linux/list.h> |
19 | #include <linux/errno.h> | 19 | #include <linux/errno.h> |
20 | #include <linux/capability.h> | ||
20 | #include <net/netlink.h> | 21 | #include <net/netlink.h> |
21 | #include <net/sock.h> | 22 | #include <net/sock.h> |
22 | 23 | ||
@@ -407,6 +408,9 @@ static int nfnl_cthelper_new(struct net *net, struct sock *nfnl, | |||
407 | struct nfnl_cthelper *nlcth; | 408 | struct nfnl_cthelper *nlcth; |
408 | int ret = 0; | 409 | int ret = 0; |
409 | 410 | ||
411 | if (!capable(CAP_NET_ADMIN)) | ||
412 | return -EPERM; | ||
413 | |||
410 | if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE]) | 414 | if (!tb[NFCTH_NAME] || !tb[NFCTH_TUPLE]) |
411 | return -EINVAL; | 415 | return -EINVAL; |
412 | 416 | ||
@@ -611,6 +615,9 @@ static int nfnl_cthelper_get(struct net *net, struct sock *nfnl, | |||
611 | struct nfnl_cthelper *nlcth; | 615 | struct nfnl_cthelper *nlcth; |
612 | bool tuple_set = false; | 616 | bool tuple_set = false; |
613 | 617 | ||
618 | if (!capable(CAP_NET_ADMIN)) | ||
619 | return -EPERM; | ||
620 | |||
614 | if (nlh->nlmsg_flags & NLM_F_DUMP) { | 621 | if (nlh->nlmsg_flags & NLM_F_DUMP) { |
615 | struct netlink_dump_control c = { | 622 | struct netlink_dump_control c = { |
616 | .dump = nfnl_cthelper_dump_table, | 623 | .dump = nfnl_cthelper_dump_table, |
@@ -678,6 +685,9 @@ static int nfnl_cthelper_del(struct net *net, struct sock *nfnl, | |||
678 | struct nfnl_cthelper *nlcth, *n; | 685 | struct nfnl_cthelper *nlcth, *n; |
679 | int j = 0, ret; | 686 | int j = 0, ret; |
680 | 687 | ||
688 | if (!capable(CAP_NET_ADMIN)) | ||
689 | return -EPERM; | ||
690 | |||
681 | if (tb[NFCTH_NAME]) | 691 | if (tb[NFCTH_NAME]) |
682 | helper_name = nla_data(tb[NFCTH_NAME]); | 692 | helper_name = nla_data(tb[NFCTH_NAME]); |
683 | 693 | ||
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index e5afab86381c..e955bec0acc6 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
@@ -1093,10 +1093,15 @@ static int __net_init nfnl_log_net_init(struct net *net) | |||
1093 | 1093 | ||
1094 | static void __net_exit nfnl_log_net_exit(struct net *net) | 1094 | static void __net_exit nfnl_log_net_exit(struct net *net) |
1095 | { | 1095 | { |
1096 | struct nfnl_log_net *log = nfnl_log_pernet(net); | ||
1097 | unsigned int i; | ||
1098 | |||
1096 | #ifdef CONFIG_PROC_FS | 1099 | #ifdef CONFIG_PROC_FS |
1097 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); | 1100 | remove_proc_entry("nfnetlink_log", net->nf.proc_netfilter); |
1098 | #endif | 1101 | #endif |
1099 | nf_log_unset(net, &nfulnl_logger); | 1102 | nf_log_unset(net, &nfulnl_logger); |
1103 | for (i = 0; i < INSTANCE_BUCKETS; i++) | ||
1104 | WARN_ON_ONCE(!hlist_empty(&log->instance_table[i])); | ||
1100 | } | 1105 | } |
1101 | 1106 | ||
1102 | static struct pernet_operations nfnl_log_net_ops = { | 1107 | static struct pernet_operations nfnl_log_net_ops = { |
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index a16356cacec3..c09b36755ed7 100644 --- a/net/netfilter/nfnetlink_queue.c +++ b/net/netfilter/nfnetlink_queue.c | |||
@@ -1512,10 +1512,15 @@ static int __net_init nfnl_queue_net_init(struct net *net) | |||
1512 | 1512 | ||
1513 | static void __net_exit nfnl_queue_net_exit(struct net *net) | 1513 | static void __net_exit nfnl_queue_net_exit(struct net *net) |
1514 | { | 1514 | { |
1515 | struct nfnl_queue_net *q = nfnl_queue_pernet(net); | ||
1516 | unsigned int i; | ||
1517 | |||
1515 | nf_unregister_queue_handler(net); | 1518 | nf_unregister_queue_handler(net); |
1516 | #ifdef CONFIG_PROC_FS | 1519 | #ifdef CONFIG_PROC_FS |
1517 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); | 1520 | remove_proc_entry("nfnetlink_queue", net->nf.proc_netfilter); |
1518 | #endif | 1521 | #endif |
1522 | for (i = 0; i < INSTANCE_BUCKETS; i++) | ||
1523 | WARN_ON_ONCE(!hlist_empty(&q->instance_table[i])); | ||
1519 | } | 1524 | } |
1520 | 1525 | ||
1521 | static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) | 1526 | static void nfnl_queue_net_exit_batch(struct list_head *net_exit_list) |
diff --git a/net/netfilter/nft_exthdr.c b/net/netfilter/nft_exthdr.c index a0a93d987a3b..47ec1046ad11 100644 --- a/net/netfilter/nft_exthdr.c +++ b/net/netfilter/nft_exthdr.c | |||
@@ -214,6 +214,8 @@ static const struct nla_policy nft_exthdr_policy[NFTA_EXTHDR_MAX + 1] = { | |||
214 | [NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 }, | 214 | [NFTA_EXTHDR_OFFSET] = { .type = NLA_U32 }, |
215 | [NFTA_EXTHDR_LEN] = { .type = NLA_U32 }, | 215 | [NFTA_EXTHDR_LEN] = { .type = NLA_U32 }, |
216 | [NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 }, | 216 | [NFTA_EXTHDR_FLAGS] = { .type = NLA_U32 }, |
217 | [NFTA_EXTHDR_OP] = { .type = NLA_U32 }, | ||
218 | [NFTA_EXTHDR_SREG] = { .type = NLA_U32 }, | ||
217 | }; | 219 | }; |
218 | 220 | ||
219 | static int nft_exthdr_init(const struct nft_ctx *ctx, | 221 | static int nft_exthdr_init(const struct nft_ctx *ctx, |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index a77dd514297c..55802e97f906 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -1729,8 +1729,17 @@ static int __net_init xt_net_init(struct net *net) | |||
1729 | return 0; | 1729 | return 0; |
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | static void __net_exit xt_net_exit(struct net *net) | ||
1733 | { | ||
1734 | int i; | ||
1735 | |||
1736 | for (i = 0; i < NFPROTO_NUMPROTO; i++) | ||
1737 | WARN_ON_ONCE(!list_empty(&net->xt.tables[i])); | ||
1738 | } | ||
1739 | |||
1732 | static struct pernet_operations xt_net_ops = { | 1740 | static struct pernet_operations xt_net_ops = { |
1733 | .init = xt_net_init, | 1741 | .init = xt_net_init, |
1742 | .exit = xt_net_exit, | ||
1734 | }; | 1743 | }; |
1735 | 1744 | ||
1736 | static int __init xt_init(void) | 1745 | static int __init xt_init(void) |
diff --git a/net/netfilter/xt_bpf.c b/net/netfilter/xt_bpf.c index 041da0d9c06f..06b090d8e901 100644 --- a/net/netfilter/xt_bpf.c +++ b/net/netfilter/xt_bpf.c | |||
@@ -27,6 +27,9 @@ static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len, | |||
27 | { | 27 | { |
28 | struct sock_fprog_kern program; | 28 | struct sock_fprog_kern program; |
29 | 29 | ||
30 | if (len > XT_BPF_MAX_NUM_INSTR) | ||
31 | return -EINVAL; | ||
32 | |||
30 | program.len = len; | 33 | program.len = len; |
31 | program.filter = insns; | 34 | program.filter = insns; |
32 | 35 | ||
@@ -52,18 +55,11 @@ static int __bpf_mt_check_fd(int fd, struct bpf_prog **ret) | |||
52 | 55 | ||
53 | static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret) | 56 | static int __bpf_mt_check_path(const char *path, struct bpf_prog **ret) |
54 | { | 57 | { |
55 | mm_segment_t oldfs = get_fs(); | 58 | if (strnlen(path, XT_BPF_PATH_MAX) == XT_BPF_PATH_MAX) |
56 | int retval, fd; | 59 | return -EINVAL; |
57 | 60 | ||
58 | set_fs(KERNEL_DS); | 61 | *ret = bpf_prog_get_type_path(path, BPF_PROG_TYPE_SOCKET_FILTER); |
59 | fd = bpf_obj_get_user(path, 0); | 62 | return PTR_ERR_OR_ZERO(*ret); |
60 | set_fs(oldfs); | ||
61 | if (fd < 0) | ||
62 | return fd; | ||
63 | |||
64 | retval = __bpf_mt_check_fd(fd, ret); | ||
65 | sys_close(fd); | ||
66 | return retval; | ||
67 | } | 63 | } |
68 | 64 | ||
69 | static int bpf_mt_check(const struct xt_mtchk_param *par) | 65 | static int bpf_mt_check(const struct xt_mtchk_param *par) |
diff --git a/net/netfilter/xt_osf.c b/net/netfilter/xt_osf.c index 36e14b1f061d..a34f314a8c23 100644 --- a/net/netfilter/xt_osf.c +++ b/net/netfilter/xt_osf.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | 21 | ||
22 | #include <linux/capability.h> | ||
22 | #include <linux/if.h> | 23 | #include <linux/if.h> |
23 | #include <linux/inetdevice.h> | 24 | #include <linux/inetdevice.h> |
24 | #include <linux/ip.h> | 25 | #include <linux/ip.h> |
@@ -70,6 +71,9 @@ static int xt_osf_add_callback(struct net *net, struct sock *ctnl, | |||
70 | struct xt_osf_finger *kf = NULL, *sf; | 71 | struct xt_osf_finger *kf = NULL, *sf; |
71 | int err = 0; | 72 | int err = 0; |
72 | 73 | ||
74 | if (!capable(CAP_NET_ADMIN)) | ||
75 | return -EPERM; | ||
76 | |||
73 | if (!osf_attrs[OSF_ATTR_FINGER]) | 77 | if (!osf_attrs[OSF_ATTR_FINGER]) |
74 | return -EINVAL; | 78 | return -EINVAL; |
75 | 79 | ||
@@ -115,6 +119,9 @@ static int xt_osf_remove_callback(struct net *net, struct sock *ctnl, | |||
115 | struct xt_osf_finger *sf; | 119 | struct xt_osf_finger *sf; |
116 | int err = -ENOENT; | 120 | int err = -ENOENT; |
117 | 121 | ||
122 | if (!capable(CAP_NET_ADMIN)) | ||
123 | return -EPERM; | ||
124 | |||
118 | if (!osf_attrs[OSF_ATTR_FINGER]) | 125 | if (!osf_attrs[OSF_ATTR_FINGER]) |
119 | return -EINVAL; | 126 | return -EINVAL; |
120 | 127 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index b9e0ee4e22f5..84a4e4c3be4b 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -253,6 +253,9 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb, | |||
253 | struct sock *sk = skb->sk; | 253 | struct sock *sk = skb->sk; |
254 | int ret = -ENOMEM; | 254 | int ret = -ENOMEM; |
255 | 255 | ||
256 | if (!net_eq(dev_net(dev), sock_net(sk))) | ||
257 | return 0; | ||
258 | |||
256 | dev_hold(dev); | 259 | dev_hold(dev); |
257 | 260 | ||
258 | if (is_vmalloc_addr(skb->head)) | 261 | if (is_vmalloc_addr(skb->head)) |
@@ -2381,13 +2384,14 @@ int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *, | |||
2381 | struct nlmsghdr *, | 2384 | struct nlmsghdr *, |
2382 | struct netlink_ext_ack *)) | 2385 | struct netlink_ext_ack *)) |
2383 | { | 2386 | { |
2384 | struct netlink_ext_ack extack = {}; | 2387 | struct netlink_ext_ack extack; |
2385 | struct nlmsghdr *nlh; | 2388 | struct nlmsghdr *nlh; |
2386 | int err; | 2389 | int err; |
2387 | 2390 | ||
2388 | while (skb->len >= nlmsg_total_size(0)) { | 2391 | while (skb->len >= nlmsg_total_size(0)) { |
2389 | int msglen; | 2392 | int msglen; |
2390 | 2393 | ||
2394 | memset(&extack, 0, sizeof(extack)); | ||
2391 | nlh = nlmsg_hdr(skb); | 2395 | nlh = nlmsg_hdr(skb); |
2392 | err = 0; | 2396 | err = 0; |
2393 | 2397 | ||
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index dbe2379329c5..f039064ce922 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -579,6 +579,7 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
579 | return -EINVAL; | 579 | return -EINVAL; |
580 | 580 | ||
581 | skb_reset_network_header(skb); | 581 | skb_reset_network_header(skb); |
582 | key->eth.type = skb->protocol; | ||
582 | } else { | 583 | } else { |
583 | eth = eth_hdr(skb); | 584 | eth = eth_hdr(skb); |
584 | ether_addr_copy(key->eth.src, eth->h_source); | 585 | ether_addr_copy(key->eth.src, eth->h_source); |
@@ -592,15 +593,23 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) | |||
592 | if (unlikely(parse_vlan(skb, key))) | 593 | if (unlikely(parse_vlan(skb, key))) |
593 | return -ENOMEM; | 594 | return -ENOMEM; |
594 | 595 | ||
595 | skb->protocol = parse_ethertype(skb); | 596 | key->eth.type = parse_ethertype(skb); |
596 | if (unlikely(skb->protocol == htons(0))) | 597 | if (unlikely(key->eth.type == htons(0))) |
597 | return -ENOMEM; | 598 | return -ENOMEM; |
598 | 599 | ||
600 | /* Multiple tagged packets need to retain TPID to satisfy | ||
601 | * skb_vlan_pop(), which will later shift the ethertype into | ||
602 | * skb->protocol. | ||
603 | */ | ||
604 | if (key->eth.cvlan.tci & htons(VLAN_TAG_PRESENT)) | ||
605 | skb->protocol = key->eth.cvlan.tpid; | ||
606 | else | ||
607 | skb->protocol = key->eth.type; | ||
608 | |||
599 | skb_reset_network_header(skb); | 609 | skb_reset_network_header(skb); |
600 | __skb_push(skb, skb->data - skb_mac_header(skb)); | 610 | __skb_push(skb, skb->data - skb_mac_header(skb)); |
601 | } | 611 | } |
602 | skb_reset_mac_len(skb); | 612 | skb_reset_mac_len(skb); |
603 | key->eth.type = skb->protocol; | ||
604 | 613 | ||
605 | /* Network layer. */ | 614 | /* Network layer. */ |
606 | if (key->eth.type == htons(ETH_P_IP)) { | 615 | if (key->eth.type == htons(ETH_P_IP)) { |
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c index 624ea74353dd..f143908b651d 100644 --- a/net/openvswitch/flow_netlink.c +++ b/net/openvswitch/flow_netlink.c | |||
@@ -49,7 +49,6 @@ | |||
49 | #include <net/mpls.h> | 49 | #include <net/mpls.h> |
50 | #include <net/vxlan.h> | 50 | #include <net/vxlan.h> |
51 | #include <net/tun_proto.h> | 51 | #include <net/tun_proto.h> |
52 | #include <net/erspan.h> | ||
53 | 52 | ||
54 | #include "flow_netlink.h" | 53 | #include "flow_netlink.h" |
55 | 54 | ||
@@ -334,8 +333,7 @@ size_t ovs_tun_key_attr_size(void) | |||
334 | * OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it. | 333 | * OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS and covered by it. |
335 | */ | 334 | */ |
336 | + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */ | 335 | + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_SRC */ |
337 | + nla_total_size(2) /* OVS_TUNNEL_KEY_ATTR_TP_DST */ | 336 | + nla_total_size(2); /* OVS_TUNNEL_KEY_ATTR_TP_DST */ |
338 | + nla_total_size(4); /* OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS */ | ||
339 | } | 337 | } |
340 | 338 | ||
341 | static size_t ovs_nsh_key_attr_size(void) | 339 | static size_t ovs_nsh_key_attr_size(void) |
@@ -402,7 +400,6 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1] | |||
402 | .next = ovs_vxlan_ext_key_lens }, | 400 | .next = ovs_vxlan_ext_key_lens }, |
403 | [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) }, | 401 | [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) }, |
404 | [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) }, | 402 | [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) }, |
405 | [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = sizeof(u32) }, | ||
406 | }; | 403 | }; |
407 | 404 | ||
408 | static const struct ovs_len_tbl | 405 | static const struct ovs_len_tbl |
@@ -634,33 +631,6 @@ static int vxlan_tun_opt_from_nlattr(const struct nlattr *attr, | |||
634 | return 0; | 631 | return 0; |
635 | } | 632 | } |
636 | 633 | ||
637 | static int erspan_tun_opt_from_nlattr(const struct nlattr *attr, | ||
638 | struct sw_flow_match *match, bool is_mask, | ||
639 | bool log) | ||
640 | { | ||
641 | unsigned long opt_key_offset; | ||
642 | struct erspan_metadata opts; | ||
643 | |||
644 | BUILD_BUG_ON(sizeof(opts) > sizeof(match->key->tun_opts)); | ||
645 | |||
646 | memset(&opts, 0, sizeof(opts)); | ||
647 | opts.index = nla_get_be32(attr); | ||
648 | |||
649 | /* Index has only 20-bit */ | ||
650 | if (ntohl(opts.index) & ~INDEX_MASK) { | ||
651 | OVS_NLERR(log, "ERSPAN index number %x too large.", | ||
652 | ntohl(opts.index)); | ||
653 | return -EINVAL; | ||
654 | } | ||
655 | |||
656 | SW_FLOW_KEY_PUT(match, tun_opts_len, sizeof(opts), is_mask); | ||
657 | opt_key_offset = TUN_METADATA_OFFSET(sizeof(opts)); | ||
658 | SW_FLOW_KEY_MEMCPY_OFFSET(match, opt_key_offset, &opts, sizeof(opts), | ||
659 | is_mask); | ||
660 | |||
661 | return 0; | ||
662 | } | ||
663 | |||
664 | static int ip_tun_from_nlattr(const struct nlattr *attr, | 634 | static int ip_tun_from_nlattr(const struct nlattr *attr, |
665 | struct sw_flow_match *match, bool is_mask, | 635 | struct sw_flow_match *match, bool is_mask, |
666 | bool log) | 636 | bool log) |
@@ -768,19 +738,6 @@ static int ip_tun_from_nlattr(const struct nlattr *attr, | |||
768 | break; | 738 | break; |
769 | case OVS_TUNNEL_KEY_ATTR_PAD: | 739 | case OVS_TUNNEL_KEY_ATTR_PAD: |
770 | break; | 740 | break; |
771 | case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS: | ||
772 | if (opts_type) { | ||
773 | OVS_NLERR(log, "Multiple metadata blocks provided"); | ||
774 | return -EINVAL; | ||
775 | } | ||
776 | |||
777 | err = erspan_tun_opt_from_nlattr(a, match, is_mask, log); | ||
778 | if (err) | ||
779 | return err; | ||
780 | |||
781 | tun_flags |= TUNNEL_ERSPAN_OPT; | ||
782 | opts_type = type; | ||
783 | break; | ||
784 | default: | 741 | default: |
785 | OVS_NLERR(log, "Unknown IP tunnel attribute %d", | 742 | OVS_NLERR(log, "Unknown IP tunnel attribute %d", |
786 | type); | 743 | type); |
@@ -905,10 +862,6 @@ static int __ip_tun_to_nlattr(struct sk_buff *skb, | |||
905 | else if (output->tun_flags & TUNNEL_VXLAN_OPT && | 862 | else if (output->tun_flags & TUNNEL_VXLAN_OPT && |
906 | vxlan_opt_to_nlattr(skb, tun_opts, swkey_tun_opts_len)) | 863 | vxlan_opt_to_nlattr(skb, tun_opts, swkey_tun_opts_len)) |
907 | return -EMSGSIZE; | 864 | return -EMSGSIZE; |
908 | else if (output->tun_flags & TUNNEL_ERSPAN_OPT && | ||
909 | nla_put_be32(skb, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS, | ||
910 | ((struct erspan_metadata *)tun_opts)->index)) | ||
911 | return -EMSGSIZE; | ||
912 | } | 865 | } |
913 | 866 | ||
914 | return 0; | 867 | return 0; |
@@ -2533,8 +2486,6 @@ static int validate_and_copy_set_tun(const struct nlattr *attr, | |||
2533 | break; | 2486 | break; |
2534 | case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: | 2487 | case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: |
2535 | break; | 2488 | break; |
2536 | case OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS: | ||
2537 | break; | ||
2538 | } | 2489 | } |
2539 | }; | 2490 | }; |
2540 | 2491 | ||
diff --git a/net/rds/rdma.c b/net/rds/rdma.c index bc2f1e0977d6..634cfcb7bba6 100644 --- a/net/rds/rdma.c +++ b/net/rds/rdma.c | |||
@@ -525,6 +525,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args) | |||
525 | 525 | ||
526 | local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; | 526 | local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr; |
527 | 527 | ||
528 | if (args->nr_local == 0) | ||
529 | return -EINVAL; | ||
530 | |||
528 | /* figure out the number of pages in the vector */ | 531 | /* figure out the number of pages in the vector */ |
529 | for (i = 0; i < args->nr_local; i++) { | 532 | for (i = 0; i < args->nr_local; i++) { |
530 | if (copy_from_user(&vec, &local_vec[i], | 533 | if (copy_from_user(&vec, &local_vec[i], |
@@ -874,6 +877,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm, | |||
874 | err: | 877 | err: |
875 | if (page) | 878 | if (page) |
876 | put_page(page); | 879 | put_page(page); |
880 | rm->atomic.op_active = 0; | ||
877 | kfree(rm->atomic.op_notifier); | 881 | kfree(rm->atomic.op_notifier); |
878 | 882 | ||
879 | return ret; | 883 | return ret; |
diff --git a/net/rds/send.c b/net/rds/send.c index b52cdc8ae428..f72466c63f0c 100644 --- a/net/rds/send.c +++ b/net/rds/send.c | |||
@@ -1009,6 +1009,9 @@ static int rds_rdma_bytes(struct msghdr *msg, size_t *rdma_bytes) | |||
1009 | continue; | 1009 | continue; |
1010 | 1010 | ||
1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { | 1011 | if (cmsg->cmsg_type == RDS_CMSG_RDMA_ARGS) { |
1012 | if (cmsg->cmsg_len < | ||
1013 | CMSG_LEN(sizeof(struct rds_rdma_args))) | ||
1014 | return -EINVAL; | ||
1012 | args = CMSG_DATA(cmsg); | 1015 | args = CMSG_DATA(cmsg); |
1013 | *rdma_bytes += args->remote_vec.bytes; | 1016 | *rdma_bytes += args->remote_vec.bytes; |
1014 | } | 1017 | } |
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 6b7ee71f40c6..ab7356e0ba83 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -90,9 +90,10 @@ void rds_tcp_nonagle(struct socket *sock) | |||
90 | sizeof(val)); | 90 | sizeof(val)); |
91 | } | 91 | } |
92 | 92 | ||
93 | u32 rds_tcp_snd_nxt(struct rds_tcp_connection *tc) | 93 | u32 rds_tcp_write_seq(struct rds_tcp_connection *tc) |
94 | { | 94 | { |
95 | return tcp_sk(tc->t_sock->sk)->snd_nxt; | 95 | /* seq# of the last byte of data in tcp send buffer */ |
96 | return tcp_sk(tc->t_sock->sk)->write_seq; | ||
96 | } | 97 | } |
97 | 98 | ||
98 | u32 rds_tcp_snd_una(struct rds_tcp_connection *tc) | 99 | u32 rds_tcp_snd_una(struct rds_tcp_connection *tc) |
diff --git a/net/rds/tcp.h b/net/rds/tcp.h index 1aafbf7c3011..864ca7d8f019 100644 --- a/net/rds/tcp.h +++ b/net/rds/tcp.h | |||
@@ -54,7 +54,7 @@ void rds_tcp_set_callbacks(struct socket *sock, struct rds_conn_path *cp); | |||
54 | void rds_tcp_reset_callbacks(struct socket *sock, struct rds_conn_path *cp); | 54 | void rds_tcp_reset_callbacks(struct socket *sock, struct rds_conn_path *cp); |
55 | void rds_tcp_restore_callbacks(struct socket *sock, | 55 | void rds_tcp_restore_callbacks(struct socket *sock, |
56 | struct rds_tcp_connection *tc); | 56 | struct rds_tcp_connection *tc); |
57 | u32 rds_tcp_snd_nxt(struct rds_tcp_connection *tc); | 57 | u32 rds_tcp_write_seq(struct rds_tcp_connection *tc); |
58 | u32 rds_tcp_snd_una(struct rds_tcp_connection *tc); | 58 | u32 rds_tcp_snd_una(struct rds_tcp_connection *tc); |
59 | u64 rds_tcp_map_seq(struct rds_tcp_connection *tc, u32 seq); | 59 | u64 rds_tcp_map_seq(struct rds_tcp_connection *tc, u32 seq); |
60 | extern struct rds_transport rds_tcp_transport; | 60 | extern struct rds_transport rds_tcp_transport; |
diff --git a/net/rds/tcp_send.c b/net/rds/tcp_send.c index dc860d1bb608..9b76e0fa1722 100644 --- a/net/rds/tcp_send.c +++ b/net/rds/tcp_send.c | |||
@@ -86,7 +86,7 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
86 | * m_ack_seq is set to the sequence number of the last byte of | 86 | * m_ack_seq is set to the sequence number of the last byte of |
87 | * header and data. see rds_tcp_is_acked(). | 87 | * header and data. see rds_tcp_is_acked(). |
88 | */ | 88 | */ |
89 | tc->t_last_sent_nxt = rds_tcp_snd_nxt(tc); | 89 | tc->t_last_sent_nxt = rds_tcp_write_seq(tc); |
90 | rm->m_ack_seq = tc->t_last_sent_nxt + | 90 | rm->m_ack_seq = tc->t_last_sent_nxt + |
91 | sizeof(struct rds_header) + | 91 | sizeof(struct rds_header) + |
92 | be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1; | 92 | be32_to_cpu(rm->m_inc.i_hdr.h_len) - 1; |
@@ -98,7 +98,7 @@ int rds_tcp_xmit(struct rds_connection *conn, struct rds_message *rm, | |||
98 | rm->m_inc.i_hdr.h_flags |= RDS_FLAG_RETRANSMITTED; | 98 | rm->m_inc.i_hdr.h_flags |= RDS_FLAG_RETRANSMITTED; |
99 | 99 | ||
100 | rdsdebug("rm %p tcp nxt %u ack_seq %llu\n", | 100 | rdsdebug("rm %p tcp nxt %u ack_seq %llu\n", |
101 | rm, rds_tcp_snd_nxt(tc), | 101 | rm, rds_tcp_write_seq(tc), |
102 | (unsigned long long)rm->m_ack_seq); | 102 | (unsigned long long)rm->m_ack_seq); |
103 | } | 103 | } |
104 | 104 | ||
diff --git a/net/sched/act_gact.c b/net/sched/act_gact.c index e29a48ef7fc3..a0ac42b3ed06 100644 --- a/net/sched/act_gact.c +++ b/net/sched/act_gact.c | |||
@@ -159,7 +159,7 @@ static void tcf_gact_stats_update(struct tc_action *a, u64 bytes, u32 packets, | |||
159 | if (action == TC_ACT_SHOT) | 159 | if (action == TC_ACT_SHOT) |
160 | this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; | 160 | this_cpu_ptr(gact->common.cpu_qstats)->drops += packets; |
161 | 161 | ||
162 | tm->lastuse = lastuse; | 162 | tm->lastuse = max_t(u64, tm->lastuse, lastuse); |
163 | } | 163 | } |
164 | 164 | ||
165 | static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, | 165 | static int tcf_gact_dump(struct sk_buff *skb, struct tc_action *a, |
diff --git a/net/sched/act_meta_mark.c b/net/sched/act_meta_mark.c index 1e3f10e5da99..6445184b2759 100644 --- a/net/sched/act_meta_mark.c +++ b/net/sched/act_meta_mark.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
23 | #include <uapi/linux/tc_act/tc_ife.h> | 23 | #include <uapi/linux/tc_act/tc_ife.h> |
24 | #include <net/tc_act/tc_ife.h> | 24 | #include <net/tc_act/tc_ife.h> |
25 | #include <linux/rtnetlink.h> | ||
26 | 25 | ||
27 | static int skbmark_encode(struct sk_buff *skb, void *skbdata, | 26 | static int skbmark_encode(struct sk_buff *skb, void *skbdata, |
28 | struct tcf_meta_info *e) | 27 | struct tcf_meta_info *e) |
diff --git a/net/sched/act_meta_skbtcindex.c b/net/sched/act_meta_skbtcindex.c index 2ea1f26c9e96..7221437ca3a6 100644 --- a/net/sched/act_meta_skbtcindex.c +++ b/net/sched/act_meta_skbtcindex.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <net/pkt_sched.h> | 22 | #include <net/pkt_sched.h> |
23 | #include <uapi/linux/tc_act/tc_ife.h> | 23 | #include <uapi/linux/tc_act/tc_ife.h> |
24 | #include <net/tc_act/tc_ife.h> | 24 | #include <net/tc_act/tc_ife.h> |
25 | #include <linux/rtnetlink.h> | ||
26 | 25 | ||
27 | static int skbtcindex_encode(struct sk_buff *skb, void *skbdata, | 26 | static int skbtcindex_encode(struct sk_buff *skb, void *skbdata, |
28 | struct tcf_meta_info *e) | 27 | struct tcf_meta_info *e) |
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index 8b3e59388480..08b61849c2a2 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -239,7 +239,7 @@ static void tcf_stats_update(struct tc_action *a, u64 bytes, u32 packets, | |||
239 | struct tcf_t *tm = &m->tcf_tm; | 239 | struct tcf_t *tm = &m->tcf_tm; |
240 | 240 | ||
241 | _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); | 241 | _bstats_cpu_update(this_cpu_ptr(a->cpu_bstats), bytes, packets); |
242 | tm->lastuse = lastuse; | 242 | tm->lastuse = max_t(u64, tm->lastuse, lastuse); |
243 | } | 243 | } |
244 | 244 | ||
245 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, | 245 | static int tcf_mirred_dump(struct sk_buff *skb, struct tc_action *a, int bind, |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index ddcf04b4ab43..b9d63d2246e6 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include <linux/skbuff.h> | 23 | #include <linux/skbuff.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/kmod.h> | 25 | #include <linux/kmod.h> |
26 | #include <linux/err.h> | ||
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <net/net_namespace.h> | 27 | #include <net/net_namespace.h> |
29 | #include <net/sock.h> | 28 | #include <net/sock.h> |
@@ -352,6 +351,8 @@ void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, | |||
352 | { | 351 | { |
353 | struct tcf_chain *chain; | 352 | struct tcf_chain *chain; |
354 | 353 | ||
354 | if (!block) | ||
355 | return; | ||
355 | /* Hold a refcnt for all chains, except 0, so that they don't disappear | 356 | /* Hold a refcnt for all chains, except 0, so that they don't disappear |
356 | * while we are iterating. | 357 | * while we are iterating. |
357 | */ | 358 | */ |
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c index 6fe798c2df1a..a62586e2dbdb 100644 --- a/net/sched/cls_bpf.c +++ b/net/sched/cls_bpf.c | |||
@@ -42,7 +42,6 @@ struct cls_bpf_prog { | |||
42 | struct list_head link; | 42 | struct list_head link; |
43 | struct tcf_result res; | 43 | struct tcf_result res; |
44 | bool exts_integrated; | 44 | bool exts_integrated; |
45 | bool offloaded; | ||
46 | u32 gen_flags; | 45 | u32 gen_flags; |
47 | struct tcf_exts exts; | 46 | struct tcf_exts exts; |
48 | u32 handle; | 47 | u32 handle; |
@@ -148,73 +147,63 @@ static bool cls_bpf_is_ebpf(const struct cls_bpf_prog *prog) | |||
148 | } | 147 | } |
149 | 148 | ||
150 | static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, | 149 | static int cls_bpf_offload_cmd(struct tcf_proto *tp, struct cls_bpf_prog *prog, |
151 | enum tc_clsbpf_command cmd) | 150 | struct cls_bpf_prog *oldprog) |
152 | { | 151 | { |
153 | bool addorrep = cmd == TC_CLSBPF_ADD || cmd == TC_CLSBPF_REPLACE; | ||
154 | struct tcf_block *block = tp->chain->block; | 152 | struct tcf_block *block = tp->chain->block; |
155 | bool skip_sw = tc_skip_sw(prog->gen_flags); | ||
156 | struct tc_cls_bpf_offload cls_bpf = {}; | 153 | struct tc_cls_bpf_offload cls_bpf = {}; |
154 | struct cls_bpf_prog *obj; | ||
155 | bool skip_sw; | ||
157 | int err; | 156 | int err; |
158 | 157 | ||
158 | skip_sw = prog && tc_skip_sw(prog->gen_flags); | ||
159 | obj = prog ?: oldprog; | ||
160 | |||
159 | tc_cls_common_offload_init(&cls_bpf.common, tp); | 161 | tc_cls_common_offload_init(&cls_bpf.common, tp); |
160 | cls_bpf.command = cmd; | 162 | cls_bpf.command = TC_CLSBPF_OFFLOAD; |
161 | cls_bpf.exts = &prog->exts; | 163 | cls_bpf.exts = &obj->exts; |
162 | cls_bpf.prog = prog->filter; | 164 | cls_bpf.prog = prog ? prog->filter : NULL; |
163 | cls_bpf.name = prog->bpf_name; | 165 | cls_bpf.oldprog = oldprog ? oldprog->filter : NULL; |
164 | cls_bpf.exts_integrated = prog->exts_integrated; | 166 | cls_bpf.name = obj->bpf_name; |
165 | cls_bpf.gen_flags = prog->gen_flags; | 167 | cls_bpf.exts_integrated = obj->exts_integrated; |
168 | cls_bpf.gen_flags = obj->gen_flags; | ||
166 | 169 | ||
167 | err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw); | 170 | err = tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, skip_sw); |
168 | if (addorrep) { | 171 | if (prog) { |
169 | if (err < 0) { | 172 | if (err < 0) { |
170 | cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY); | 173 | cls_bpf_offload_cmd(tp, oldprog, prog); |
171 | return err; | 174 | return err; |
172 | } else if (err > 0) { | 175 | } else if (err > 0) { |
173 | prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; | 176 | prog->gen_flags |= TCA_CLS_FLAGS_IN_HW; |
174 | } | 177 | } |
175 | } | 178 | } |
176 | 179 | ||
177 | if (addorrep && skip_sw && !(prog->gen_flags & TCA_CLS_FLAGS_IN_HW)) | 180 | if (prog && skip_sw && !(prog->gen_flags & TCA_CLS_FLAGS_IN_HW)) |
178 | return -EINVAL; | 181 | return -EINVAL; |
179 | 182 | ||
180 | return 0; | 183 | return 0; |
181 | } | 184 | } |
182 | 185 | ||
186 | static u32 cls_bpf_flags(u32 flags) | ||
187 | { | ||
188 | return flags & CLS_BPF_SUPPORTED_GEN_FLAGS; | ||
189 | } | ||
190 | |||
183 | static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, | 191 | static int cls_bpf_offload(struct tcf_proto *tp, struct cls_bpf_prog *prog, |
184 | struct cls_bpf_prog *oldprog) | 192 | struct cls_bpf_prog *oldprog) |
185 | { | 193 | { |
186 | struct cls_bpf_prog *obj = prog; | 194 | if (prog && oldprog && |
187 | enum tc_clsbpf_command cmd; | 195 | cls_bpf_flags(prog->gen_flags) != |
188 | bool skip_sw; | 196 | cls_bpf_flags(oldprog->gen_flags)) |
189 | int ret; | 197 | return -EINVAL; |
190 | |||
191 | skip_sw = tc_skip_sw(prog->gen_flags) || | ||
192 | (oldprog && tc_skip_sw(oldprog->gen_flags)); | ||
193 | |||
194 | if (oldprog && oldprog->offloaded) { | ||
195 | if (!tc_skip_hw(prog->gen_flags)) { | ||
196 | cmd = TC_CLSBPF_REPLACE; | ||
197 | } else if (!tc_skip_sw(prog->gen_flags)) { | ||
198 | obj = oldprog; | ||
199 | cmd = TC_CLSBPF_DESTROY; | ||
200 | } else { | ||
201 | return -EINVAL; | ||
202 | } | ||
203 | } else { | ||
204 | if (tc_skip_hw(prog->gen_flags)) | ||
205 | return skip_sw ? -EINVAL : 0; | ||
206 | cmd = TC_CLSBPF_ADD; | ||
207 | } | ||
208 | |||
209 | ret = cls_bpf_offload_cmd(tp, obj, cmd); | ||
210 | if (ret) | ||
211 | return ret; | ||
212 | 198 | ||
213 | obj->offloaded = true; | 199 | if (prog && tc_skip_hw(prog->gen_flags)) |
214 | if (oldprog) | 200 | prog = NULL; |
215 | oldprog->offloaded = false; | 201 | if (oldprog && tc_skip_hw(oldprog->gen_flags)) |
202 | oldprog = NULL; | ||
203 | if (!prog && !oldprog) | ||
204 | return 0; | ||
216 | 205 | ||
217 | return 0; | 206 | return cls_bpf_offload_cmd(tp, prog, oldprog); |
218 | } | 207 | } |
219 | 208 | ||
220 | static void cls_bpf_stop_offload(struct tcf_proto *tp, | 209 | static void cls_bpf_stop_offload(struct tcf_proto *tp, |
@@ -222,25 +211,26 @@ static void cls_bpf_stop_offload(struct tcf_proto *tp, | |||
222 | { | 211 | { |
223 | int err; | 212 | int err; |
224 | 213 | ||
225 | if (!prog->offloaded) | 214 | err = cls_bpf_offload_cmd(tp, NULL, prog); |
226 | return; | 215 | if (err) |
227 | |||
228 | err = cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_DESTROY); | ||
229 | if (err) { | ||
230 | pr_err("Stopping hardware offload failed: %d\n", err); | 216 | pr_err("Stopping hardware offload failed: %d\n", err); |
231 | return; | ||
232 | } | ||
233 | |||
234 | prog->offloaded = false; | ||
235 | } | 217 | } |
236 | 218 | ||
237 | static void cls_bpf_offload_update_stats(struct tcf_proto *tp, | 219 | static void cls_bpf_offload_update_stats(struct tcf_proto *tp, |
238 | struct cls_bpf_prog *prog) | 220 | struct cls_bpf_prog *prog) |
239 | { | 221 | { |
240 | if (!prog->offloaded) | 222 | struct tcf_block *block = tp->chain->block; |
241 | return; | 223 | struct tc_cls_bpf_offload cls_bpf = {}; |
224 | |||
225 | tc_cls_common_offload_init(&cls_bpf.common, tp); | ||
226 | cls_bpf.command = TC_CLSBPF_STATS; | ||
227 | cls_bpf.exts = &prog->exts; | ||
228 | cls_bpf.prog = prog->filter; | ||
229 | cls_bpf.name = prog->bpf_name; | ||
230 | cls_bpf.exts_integrated = prog->exts_integrated; | ||
231 | cls_bpf.gen_flags = prog->gen_flags; | ||
242 | 232 | ||
243 | cls_bpf_offload_cmd(tp, prog, TC_CLSBPF_STATS); | 233 | tc_setup_cb_call(block, NULL, TC_SETUP_CLSBPF, &cls_bpf, false); |
244 | } | 234 | } |
245 | 235 | ||
246 | static int cls_bpf_init(struct tcf_proto *tp) | 236 | static int cls_bpf_init(struct tcf_proto *tp) |
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c index ac152b4f4247..507859cdd1cb 100644 --- a/net/sched/cls_u32.c +++ b/net/sched/cls_u32.c | |||
@@ -45,7 +45,6 @@ | |||
45 | #include <net/netlink.h> | 45 | #include <net/netlink.h> |
46 | #include <net/act_api.h> | 46 | #include <net/act_api.h> |
47 | #include <net/pkt_cls.h> | 47 | #include <net/pkt_cls.h> |
48 | #include <linux/netdevice.h> | ||
49 | #include <linux/idr.h> | 48 | #include <linux/idr.h> |
50 | 49 | ||
51 | struct tc_u_knode { | 50 | struct tc_u_knode { |
diff --git a/net/sched/em_nbyte.c b/net/sched/em_nbyte.c index df3110d69585..07c10bac06a0 100644 --- a/net/sched/em_nbyte.c +++ b/net/sched/em_nbyte.c | |||
@@ -51,7 +51,7 @@ static int em_nbyte_match(struct sk_buff *skb, struct tcf_ematch *em, | |||
51 | if (!tcf_valid_offset(skb, ptr, nbyte->hdr.len)) | 51 | if (!tcf_valid_offset(skb, ptr, nbyte->hdr.len)) |
52 | return 0; | 52 | return 0; |
53 | 53 | ||
54 | return !memcmp(ptr + nbyte->hdr.off, nbyte->pattern, nbyte->hdr.len); | 54 | return !memcmp(ptr, nbyte->pattern, nbyte->hdr.len); |
55 | } | 55 | } |
56 | 56 | ||
57 | static struct tcf_ematch_ops em_nbyte_ops = { | 57 | static struct tcf_ematch_ops em_nbyte_ops = { |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b6c4f536876b..52529b7f8d96 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -795,6 +795,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid, | |||
795 | tcm->tcm_info = refcount_read(&q->refcnt); | 795 | tcm->tcm_info = refcount_read(&q->refcnt); |
796 | if (nla_put_string(skb, TCA_KIND, q->ops->id)) | 796 | if (nla_put_string(skb, TCA_KIND, q->ops->id)) |
797 | goto nla_put_failure; | 797 | goto nla_put_failure; |
798 | if (nla_put_u8(skb, TCA_HW_OFFLOAD, !!(q->flags & TCQ_F_OFFLOADED))) | ||
799 | goto nla_put_failure; | ||
798 | if (q->ops->dump && q->ops->dump(q, skb) < 0) | 800 | if (q->ops->dump && q->ops->dump(q, skb) < 0) |
799 | goto nla_put_failure; | 801 | goto nla_put_failure; |
800 | qlen = q->q.qlen; | 802 | qlen = q->q.qlen; |
@@ -1061,17 +1063,6 @@ static struct Qdisc *qdisc_create(struct net_device *dev, | |||
1061 | } | 1063 | } |
1062 | 1064 | ||
1063 | if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) { | 1065 | if (!ops->init || (err = ops->init(sch, tca[TCA_OPTIONS])) == 0) { |
1064 | if (qdisc_is_percpu_stats(sch)) { | ||
1065 | sch->cpu_bstats = | ||
1066 | netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); | ||
1067 | if (!sch->cpu_bstats) | ||
1068 | goto err_out4; | ||
1069 | |||
1070 | sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue); | ||
1071 | if (!sch->cpu_qstats) | ||
1072 | goto err_out4; | ||
1073 | } | ||
1074 | |||
1075 | if (tca[TCA_STAB]) { | 1066 | if (tca[TCA_STAB]) { |
1076 | stab = qdisc_get_stab(tca[TCA_STAB]); | 1067 | stab = qdisc_get_stab(tca[TCA_STAB]); |
1077 | if (IS_ERR(stab)) { | 1068 | if (IS_ERR(stab)) { |
@@ -1113,7 +1104,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev, | |||
1113 | ops->destroy(sch); | 1104 | ops->destroy(sch); |
1114 | err_out3: | 1105 | err_out3: |
1115 | dev_put(dev); | 1106 | dev_put(dev); |
1116 | kfree((char *) sch - sch->padded); | 1107 | qdisc_free(sch); |
1117 | err_out2: | 1108 | err_out2: |
1118 | module_put(ops->owner); | 1109 | module_put(ops->owner); |
1119 | err_out: | 1110 | err_out: |
@@ -1121,8 +1112,6 @@ err_out: | |||
1121 | return NULL; | 1112 | return NULL; |
1122 | 1113 | ||
1123 | err_out4: | 1114 | err_out4: |
1124 | free_percpu(sch->cpu_bstats); | ||
1125 | free_percpu(sch->cpu_qstats); | ||
1126 | /* | 1115 | /* |
1127 | * Any broken qdiscs that would require a ops->reset() here? | 1116 | * Any broken qdiscs that would require a ops->reset() here? |
1128 | * The qdisc was never in action so it shouldn't be necessary. | 1117 | * The qdisc was never in action so it shouldn't be necessary. |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index cd1b200acae7..cac003fddf3e 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -633,6 +633,19 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
633 | qdisc_skb_head_init(&sch->q); | 633 | qdisc_skb_head_init(&sch->q); |
634 | spin_lock_init(&sch->q.lock); | 634 | spin_lock_init(&sch->q.lock); |
635 | 635 | ||
636 | if (ops->static_flags & TCQ_F_CPUSTATS) { | ||
637 | sch->cpu_bstats = | ||
638 | netdev_alloc_pcpu_stats(struct gnet_stats_basic_cpu); | ||
639 | if (!sch->cpu_bstats) | ||
640 | goto errout1; | ||
641 | |||
642 | sch->cpu_qstats = alloc_percpu(struct gnet_stats_queue); | ||
643 | if (!sch->cpu_qstats) { | ||
644 | free_percpu(sch->cpu_bstats); | ||
645 | goto errout1; | ||
646 | } | ||
647 | } | ||
648 | |||
636 | spin_lock_init(&sch->busylock); | 649 | spin_lock_init(&sch->busylock); |
637 | lockdep_set_class(&sch->busylock, | 650 | lockdep_set_class(&sch->busylock, |
638 | dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); | 651 | dev->qdisc_tx_busylock ?: &qdisc_tx_busylock); |
@@ -642,6 +655,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
642 | dev->qdisc_running_key ?: &qdisc_running_key); | 655 | dev->qdisc_running_key ?: &qdisc_running_key); |
643 | 656 | ||
644 | sch->ops = ops; | 657 | sch->ops = ops; |
658 | sch->flags = ops->static_flags; | ||
645 | sch->enqueue = ops->enqueue; | 659 | sch->enqueue = ops->enqueue; |
646 | sch->dequeue = ops->dequeue; | 660 | sch->dequeue = ops->dequeue; |
647 | sch->dev_queue = dev_queue; | 661 | sch->dev_queue = dev_queue; |
@@ -649,6 +663,8 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue, | |||
649 | refcount_set(&sch->refcnt, 1); | 663 | refcount_set(&sch->refcnt, 1); |
650 | 664 | ||
651 | return sch; | 665 | return sch; |
666 | errout1: | ||
667 | kfree(p); | ||
652 | errout: | 668 | errout: |
653 | return ERR_PTR(err); | 669 | return ERR_PTR(err); |
654 | } | 670 | } |
@@ -698,7 +714,7 @@ void qdisc_reset(struct Qdisc *qdisc) | |||
698 | } | 714 | } |
699 | EXPORT_SYMBOL(qdisc_reset); | 715 | EXPORT_SYMBOL(qdisc_reset); |
700 | 716 | ||
701 | static void qdisc_free(struct Qdisc *qdisc) | 717 | void qdisc_free(struct Qdisc *qdisc) |
702 | { | 718 | { |
703 | if (qdisc_is_percpu_stats(qdisc)) { | 719 | if (qdisc_is_percpu_stats(qdisc)) { |
704 | free_percpu(qdisc->cpu_bstats); | 720 | free_percpu(qdisc->cpu_bstats); |
@@ -1040,6 +1056,8 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1040 | 1056 | ||
1041 | if (!tp_head) { | 1057 | if (!tp_head) { |
1042 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); | 1058 | RCU_INIT_POINTER(*miniqp->p_miniq, NULL); |
1059 | /* Wait for flying RCU callback before it is freed. */ | ||
1060 | rcu_barrier_bh(); | ||
1043 | return; | 1061 | return; |
1044 | } | 1062 | } |
1045 | 1063 | ||
@@ -1055,7 +1073,7 @@ void mini_qdisc_pair_swap(struct mini_Qdisc_pair *miniqp, | |||
1055 | rcu_assign_pointer(*miniqp->p_miniq, miniq); | 1073 | rcu_assign_pointer(*miniqp->p_miniq, miniq); |
1056 | 1074 | ||
1057 | if (miniq_old) | 1075 | if (miniq_old) |
1058 | /* This is counterpart of the rcu barrier above. We need to | 1076 | /* This is counterpart of the rcu barriers above. We need to |
1059 | * block potential new user of miniq_old until all readers | 1077 | * block potential new user of miniq_old until all readers |
1060 | * are not seeing it. | 1078 | * are not seeing it. |
1061 | */ | 1079 | */ |
diff --git a/net/sched/sch_ingress.c b/net/sched/sch_ingress.c index 5ecc38f35d47..003e1b063447 100644 --- a/net/sched/sch_ingress.c +++ b/net/sched/sch_ingress.c | |||
@@ -66,7 +66,8 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) | |||
66 | { | 66 | { |
67 | struct ingress_sched_data *q = qdisc_priv(sch); | 67 | struct ingress_sched_data *q = qdisc_priv(sch); |
68 | struct net_device *dev = qdisc_dev(sch); | 68 | struct net_device *dev = qdisc_dev(sch); |
69 | int err; | 69 | |
70 | net_inc_ingress_queue(); | ||
70 | 71 | ||
71 | mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress); | 72 | mini_qdisc_pair_init(&q->miniqp, sch, &dev->miniq_ingress); |
72 | 73 | ||
@@ -74,14 +75,7 @@ static int ingress_init(struct Qdisc *sch, struct nlattr *opt) | |||
74 | q->block_info.chain_head_change = clsact_chain_head_change; | 75 | q->block_info.chain_head_change = clsact_chain_head_change; |
75 | q->block_info.chain_head_change_priv = &q->miniqp; | 76 | q->block_info.chain_head_change_priv = &q->miniqp; |
76 | 77 | ||
77 | err = tcf_block_get_ext(&q->block, sch, &q->block_info); | 78 | return tcf_block_get_ext(&q->block, sch, &q->block_info); |
78 | if (err) | ||
79 | return err; | ||
80 | |||
81 | net_inc_ingress_queue(); | ||
82 | sch->flags |= TCQ_F_CPUSTATS; | ||
83 | |||
84 | return 0; | ||
85 | } | 79 | } |
86 | 80 | ||
87 | static void ingress_destroy(struct Qdisc *sch) | 81 | static void ingress_destroy(struct Qdisc *sch) |
@@ -120,6 +114,7 @@ static struct Qdisc_ops ingress_qdisc_ops __read_mostly = { | |||
120 | .cl_ops = &ingress_class_ops, | 114 | .cl_ops = &ingress_class_ops, |
121 | .id = "ingress", | 115 | .id = "ingress", |
122 | .priv_size = sizeof(struct ingress_sched_data), | 116 | .priv_size = sizeof(struct ingress_sched_data), |
117 | .static_flags = TCQ_F_CPUSTATS, | ||
123 | .init = ingress_init, | 118 | .init = ingress_init, |
124 | .destroy = ingress_destroy, | 119 | .destroy = ingress_destroy, |
125 | .dump = ingress_dump, | 120 | .dump = ingress_dump, |
@@ -172,6 +167,9 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) | |||
172 | struct net_device *dev = qdisc_dev(sch); | 167 | struct net_device *dev = qdisc_dev(sch); |
173 | int err; | 168 | int err; |
174 | 169 | ||
170 | net_inc_ingress_queue(); | ||
171 | net_inc_egress_queue(); | ||
172 | |||
175 | mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress); | 173 | mini_qdisc_pair_init(&q->miniqp_ingress, sch, &dev->miniq_ingress); |
176 | 174 | ||
177 | q->ingress_block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; | 175 | q->ingress_block_info.binder_type = TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS; |
@@ -188,20 +186,7 @@ static int clsact_init(struct Qdisc *sch, struct nlattr *opt) | |||
188 | q->egress_block_info.chain_head_change = clsact_chain_head_change; | 186 | q->egress_block_info.chain_head_change = clsact_chain_head_change; |
189 | q->egress_block_info.chain_head_change_priv = &q->miniqp_egress; | 187 | q->egress_block_info.chain_head_change_priv = &q->miniqp_egress; |
190 | 188 | ||
191 | err = tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); | 189 | return tcf_block_get_ext(&q->egress_block, sch, &q->egress_block_info); |
192 | if (err) | ||
193 | goto err_egress_block_get; | ||
194 | |||
195 | net_inc_ingress_queue(); | ||
196 | net_inc_egress_queue(); | ||
197 | |||
198 | sch->flags |= TCQ_F_CPUSTATS; | ||
199 | |||
200 | return 0; | ||
201 | |||
202 | err_egress_block_get: | ||
203 | tcf_block_put_ext(q->ingress_block, sch, &q->ingress_block_info); | ||
204 | return err; | ||
205 | } | 190 | } |
206 | 191 | ||
207 | static void clsact_destroy(struct Qdisc *sch) | 192 | static void clsact_destroy(struct Qdisc *sch) |
@@ -228,6 +213,7 @@ static struct Qdisc_ops clsact_qdisc_ops __read_mostly = { | |||
228 | .cl_ops = &clsact_class_ops, | 213 | .cl_ops = &clsact_class_ops, |
229 | .id = "clsact", | 214 | .id = "clsact", |
230 | .priv_size = sizeof(struct clsact_sched_data), | 215 | .priv_size = sizeof(struct clsact_sched_data), |
216 | .static_flags = TCQ_F_CPUSTATS, | ||
231 | .init = clsact_init, | 217 | .init = clsact_init, |
232 | .destroy = clsact_destroy, | 218 | .destroy = clsact_destroy, |
233 | .dump = ingress_dump, | 219 | .dump = ingress_dump, |
diff --git a/net/sched/sch_red.c b/net/sched/sch_red.c index 9d874e60e032..f0747eb87dc4 100644 --- a/net/sched/sch_red.c +++ b/net/sched/sch_red.c | |||
@@ -157,6 +157,7 @@ static int red_offload(struct Qdisc *sch, bool enable) | |||
157 | .handle = sch->handle, | 157 | .handle = sch->handle, |
158 | .parent = sch->parent, | 158 | .parent = sch->parent, |
159 | }; | 159 | }; |
160 | int err; | ||
160 | 161 | ||
161 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) | 162 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) |
162 | return -EOPNOTSUPP; | 163 | return -EOPNOTSUPP; |
@@ -171,7 +172,14 @@ static int red_offload(struct Qdisc *sch, bool enable) | |||
171 | opt.command = TC_RED_DESTROY; | 172 | opt.command = TC_RED_DESTROY; |
172 | } | 173 | } |
173 | 174 | ||
174 | return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt); | 175 | err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, &opt); |
176 | |||
177 | if (!err && enable) | ||
178 | sch->flags |= TCQ_F_OFFLOADED; | ||
179 | else | ||
180 | sch->flags &= ~TCQ_F_OFFLOADED; | ||
181 | |||
182 | return err; | ||
175 | } | 183 | } |
176 | 184 | ||
177 | static void red_destroy(struct Qdisc *sch) | 185 | static void red_destroy(struct Qdisc *sch) |
@@ -274,7 +282,7 @@ static int red_init(struct Qdisc *sch, struct nlattr *opt) | |||
274 | return red_change(sch, opt); | 282 | return red_change(sch, opt); |
275 | } | 283 | } |
276 | 284 | ||
277 | static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) | 285 | static int red_dump_offload_stats(struct Qdisc *sch, struct tc_red_qopt *opt) |
278 | { | 286 | { |
279 | struct net_device *dev = qdisc_dev(sch); | 287 | struct net_device *dev = qdisc_dev(sch); |
280 | struct tc_red_qopt_offload hw_stats = { | 288 | struct tc_red_qopt_offload hw_stats = { |
@@ -286,21 +294,12 @@ static int red_dump_offload(struct Qdisc *sch, struct tc_red_qopt *opt) | |||
286 | .stats.qstats = &sch->qstats, | 294 | .stats.qstats = &sch->qstats, |
287 | }, | 295 | }, |
288 | }; | 296 | }; |
289 | int err; | ||
290 | 297 | ||
291 | opt->flags &= ~TC_RED_OFFLOADED; | 298 | if (!(sch->flags & TCQ_F_OFFLOADED)) |
292 | if (!tc_can_offload(dev) || !dev->netdev_ops->ndo_setup_tc) | ||
293 | return 0; | ||
294 | |||
295 | err = dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, | ||
296 | &hw_stats); | ||
297 | if (err == -EOPNOTSUPP) | ||
298 | return 0; | 299 | return 0; |
299 | 300 | ||
300 | if (!err) | 301 | return dev->netdev_ops->ndo_setup_tc(dev, TC_SETUP_QDISC_RED, |
301 | opt->flags |= TC_RED_OFFLOADED; | 302 | &hw_stats); |
302 | |||
303 | return err; | ||
304 | } | 303 | } |
305 | 304 | ||
306 | static int red_dump(struct Qdisc *sch, struct sk_buff *skb) | 305 | static int red_dump(struct Qdisc *sch, struct sk_buff *skb) |
@@ -319,7 +318,7 @@ static int red_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
319 | int err; | 318 | int err; |
320 | 319 | ||
321 | sch->qstats.backlog = q->qdisc->qstats.backlog; | 320 | sch->qstats.backlog = q->qdisc->qstats.backlog; |
322 | err = red_dump_offload(sch, &opt); | 321 | err = red_dump_offload_stats(sch, &opt); |
323 | if (err) | 322 | if (err) |
324 | goto nla_put_failure; | 323 | goto nla_put_failure; |
325 | 324 | ||
@@ -347,7 +346,7 @@ static int red_dump_stats(struct Qdisc *sch, struct gnet_dump *d) | |||
347 | .marked = q->stats.prob_mark + q->stats.forced_mark, | 346 | .marked = q->stats.prob_mark + q->stats.forced_mark, |
348 | }; | 347 | }; |
349 | 348 | ||
350 | if (tc_can_offload(dev) && dev->netdev_ops->ndo_setup_tc) { | 349 | if (sch->flags & TCQ_F_OFFLOADED) { |
351 | struct red_stats hw_stats = {0}; | 350 | struct red_stats hw_stats = {0}; |
352 | struct tc_red_qopt_offload hw_stats_request = { | 351 | struct tc_red_qopt_offload hw_stats_request = { |
353 | .command = TC_RED_XSTATS, | 352 | .command = TC_RED_XSTATS, |
diff --git a/net/sctp/debug.c b/net/sctp/debug.c index 3f619fdcbf0a..291c97b07058 100644 --- a/net/sctp/debug.c +++ b/net/sctp/debug.c | |||
@@ -78,6 +78,9 @@ const char *sctp_cname(const union sctp_subtype cid) | |||
78 | case SCTP_CID_AUTH: | 78 | case SCTP_CID_AUTH: |
79 | return "AUTH"; | 79 | return "AUTH"; |
80 | 80 | ||
81 | case SCTP_CID_RECONF: | ||
82 | return "RECONF"; | ||
83 | |||
81 | default: | 84 | default: |
82 | break; | 85 | break; |
83 | } | 86 | } |
diff --git a/net/sctp/input.c b/net/sctp/input.c index 621b5ca3fd1c..141c9c466ec1 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c | |||
@@ -399,20 +399,24 @@ void sctp_icmp_frag_needed(struct sock *sk, struct sctp_association *asoc, | |||
399 | return; | 399 | return; |
400 | } | 400 | } |
401 | 401 | ||
402 | if (t->param_flags & SPP_PMTUD_ENABLE) { | 402 | if (!(t->param_flags & SPP_PMTUD_ENABLE)) |
403 | /* Update transports view of the MTU */ | 403 | /* We can't allow retransmitting in such case, as the |
404 | sctp_transport_update_pmtu(t, pmtu); | 404 | * retransmission would be sized just as before, and thus we |
405 | 405 | * would get another icmp, and retransmit again. | |
406 | /* Update association pmtu. */ | 406 | */ |
407 | sctp_assoc_sync_pmtu(asoc); | 407 | return; |
408 | } | ||
409 | 408 | ||
410 | /* Retransmit with the new pmtu setting. | 409 | /* Update transports view of the MTU. Return if no update was needed. |
411 | * Normally, if PMTU discovery is disabled, an ICMP Fragmentation | 410 | * If an update wasn't needed/possible, it also doesn't make sense to |
412 | * Needed will never be sent, but if a message was sent before | 411 | * try to retransmit now. |
413 | * PMTU discovery was disabled that was larger than the PMTU, it | ||
414 | * would not be fragmented, so it must be re-transmitted fragmented. | ||
415 | */ | 412 | */ |
413 | if (!sctp_transport_update_pmtu(t, pmtu)) | ||
414 | return; | ||
415 | |||
416 | /* Update association pmtu. */ | ||
417 | sctp_assoc_sync_pmtu(asoc); | ||
418 | |||
419 | /* Retransmit with the new pmtu setting. */ | ||
416 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); | 420 | sctp_retransmit(&asoc->outqueue, t, SCTP_RTXR_PMTUD); |
417 | } | 421 | } |
418 | 422 | ||
diff --git a/net/sctp/ipv6.c b/net/sctp/ipv6.c index 3b18085e3b10..5d4c15bf66d2 100644 --- a/net/sctp/ipv6.c +++ b/net/sctp/ipv6.c | |||
@@ -826,6 +826,7 @@ static int sctp_inet6_af_supported(sa_family_t family, struct sctp_sock *sp) | |||
826 | case AF_INET: | 826 | case AF_INET: |
827 | if (!__ipv6_only_sock(sctp_opt2sk(sp))) | 827 | if (!__ipv6_only_sock(sctp_opt2sk(sp))) |
828 | return 1; | 828 | return 1; |
829 | /* fallthru */ | ||
829 | default: | 830 | default: |
830 | return 0; | 831 | return 0; |
831 | } | 832 | } |
diff --git a/net/sctp/offload.c b/net/sctp/offload.c index 275925b93b29..35bc7106d182 100644 --- a/net/sctp/offload.c +++ b/net/sctp/offload.c | |||
@@ -45,6 +45,9 @@ static struct sk_buff *sctp_gso_segment(struct sk_buff *skb, | |||
45 | struct sk_buff *segs = ERR_PTR(-EINVAL); | 45 | struct sk_buff *segs = ERR_PTR(-EINVAL); |
46 | struct sctphdr *sh; | 46 | struct sctphdr *sh; |
47 | 47 | ||
48 | if (!(skb_shinfo(skb)->gso_type & SKB_GSO_SCTP)) | ||
49 | goto out; | ||
50 | |||
48 | sh = sctp_hdr(skb); | 51 | sh = sctp_hdr(skb); |
49 | if (!pskb_may_pull(skb, sizeof(*sh))) | 52 | if (!pskb_may_pull(skb, sizeof(*sh))) |
50 | goto out; | 53 | goto out; |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 7d67feeeffc1..c4ec99b20150 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -918,9 +918,9 @@ static void sctp_outq_flush(struct sctp_outq *q, int rtx_timeout, gfp_t gfp) | |||
918 | break; | 918 | break; |
919 | 919 | ||
920 | case SCTP_CID_ABORT: | 920 | case SCTP_CID_ABORT: |
921 | if (sctp_test_T_bit(chunk)) { | 921 | if (sctp_test_T_bit(chunk)) |
922 | packet->vtag = asoc->c.my_vtag; | 922 | packet->vtag = asoc->c.my_vtag; |
923 | } | 923 | /* fallthru */ |
924 | /* The following chunks are "response" chunks, i.e. | 924 | /* The following chunks are "response" chunks, i.e. |
925 | * they are generated in response to something we | 925 | * they are generated in response to something we |
926 | * received. If we are sending these, then we can | 926 | * received. If we are sending these, then we can |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index eb17a911aa29..039fcb618c34 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -85,7 +85,7 @@ | |||
85 | static int sctp_writeable(struct sock *sk); | 85 | static int sctp_writeable(struct sock *sk); |
86 | static void sctp_wfree(struct sk_buff *skb); | 86 | static void sctp_wfree(struct sk_buff *skb); |
87 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | 87 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, |
88 | size_t msg_len, struct sock **orig_sk); | 88 | size_t msg_len); |
89 | static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p); | 89 | static int sctp_wait_for_packet(struct sock *sk, int *err, long *timeo_p); |
90 | static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p); | 90 | static int sctp_wait_for_connect(struct sctp_association *, long *timeo_p); |
91 | static int sctp_wait_for_accept(struct sock *sk, long timeo); | 91 | static int sctp_wait_for_accept(struct sock *sk, long timeo); |
@@ -335,16 +335,14 @@ static struct sctp_af *sctp_sockaddr_af(struct sctp_sock *opt, | |||
335 | if (len < sizeof (struct sockaddr)) | 335 | if (len < sizeof (struct sockaddr)) |
336 | return NULL; | 336 | return NULL; |
337 | 337 | ||
338 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | ||
339 | return NULL; | ||
340 | |||
338 | /* V4 mapped address are really of AF_INET family */ | 341 | /* V4 mapped address are really of AF_INET family */ |
339 | if (addr->sa.sa_family == AF_INET6 && | 342 | if (addr->sa.sa_family == AF_INET6 && |
340 | ipv6_addr_v4mapped(&addr->v6.sin6_addr)) { | 343 | ipv6_addr_v4mapped(&addr->v6.sin6_addr) && |
341 | if (!opt->pf->af_supported(AF_INET, opt)) | 344 | !opt->pf->af_supported(AF_INET, opt)) |
342 | return NULL; | 345 | return NULL; |
343 | } else { | ||
344 | /* Does this PF support this AF? */ | ||
345 | if (!opt->pf->af_supported(addr->sa.sa_family, opt)) | ||
346 | return NULL; | ||
347 | } | ||
348 | 346 | ||
349 | /* If we get this far, af is valid. */ | 347 | /* If we get this far, af is valid. */ |
350 | af = sctp_get_af_specific(addr->sa.sa_family); | 348 | af = sctp_get_af_specific(addr->sa.sa_family); |
@@ -1883,8 +1881,14 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1883 | */ | 1881 | */ |
1884 | if (sinit) { | 1882 | if (sinit) { |
1885 | if (sinit->sinit_num_ostreams) { | 1883 | if (sinit->sinit_num_ostreams) { |
1886 | asoc->c.sinit_num_ostreams = | 1884 | __u16 outcnt = sinit->sinit_num_ostreams; |
1887 | sinit->sinit_num_ostreams; | 1885 | |
1886 | asoc->c.sinit_num_ostreams = outcnt; | ||
1887 | /* outcnt has been changed, so re-init stream */ | ||
1888 | err = sctp_stream_init(&asoc->stream, outcnt, 0, | ||
1889 | GFP_KERNEL); | ||
1890 | if (err) | ||
1891 | goto out_free; | ||
1888 | } | 1892 | } |
1889 | if (sinit->sinit_max_instreams) { | 1893 | if (sinit->sinit_max_instreams) { |
1890 | asoc->c.sinit_max_instreams = | 1894 | asoc->c.sinit_max_instreams = |
@@ -1971,7 +1975,7 @@ static int sctp_sendmsg(struct sock *sk, struct msghdr *msg, size_t msg_len) | |||
1971 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); | 1975 | timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); |
1972 | if (!sctp_wspace(asoc)) { | 1976 | if (!sctp_wspace(asoc)) { |
1973 | /* sk can be changed by peel off when waiting for buf. */ | 1977 | /* sk can be changed by peel off when waiting for buf. */ |
1974 | err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len, &sk); | 1978 | err = sctp_wait_for_sndbuf(asoc, &timeo, msg_len); |
1975 | if (err) { | 1979 | if (err) { |
1976 | if (err == -ESRCH) { | 1980 | if (err == -ESRCH) { |
1977 | /* asoc is already dead. */ | 1981 | /* asoc is already dead. */ |
@@ -2277,7 +2281,7 @@ static int sctp_setsockopt_events(struct sock *sk, char __user *optval, | |||
2277 | 2281 | ||
2278 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { | 2282 | if (asoc && sctp_outq_is_empty(&asoc->outqueue)) { |
2279 | event = sctp_ulpevent_make_sender_dry_event(asoc, | 2283 | event = sctp_ulpevent_make_sender_dry_event(asoc, |
2280 | GFP_ATOMIC); | 2284 | GFP_USER | __GFP_NOWARN); |
2281 | if (!event) | 2285 | if (!event) |
2282 | return -ENOMEM; | 2286 | return -ENOMEM; |
2283 | 2287 | ||
@@ -3498,6 +3502,8 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk, | |||
3498 | 3502 | ||
3499 | if (optlen < sizeof(struct sctp_hmacalgo)) | 3503 | if (optlen < sizeof(struct sctp_hmacalgo)) |
3500 | return -EINVAL; | 3504 | return -EINVAL; |
3505 | optlen = min_t(unsigned int, optlen, sizeof(struct sctp_hmacalgo) + | ||
3506 | SCTP_AUTH_NUM_HMACS * sizeof(u16)); | ||
3501 | 3507 | ||
3502 | hmacs = memdup_user(optval, optlen); | 3508 | hmacs = memdup_user(optval, optlen); |
3503 | if (IS_ERR(hmacs)) | 3509 | if (IS_ERR(hmacs)) |
@@ -3536,6 +3542,11 @@ static int sctp_setsockopt_auth_key(struct sock *sk, | |||
3536 | 3542 | ||
3537 | if (optlen <= sizeof(struct sctp_authkey)) | 3543 | if (optlen <= sizeof(struct sctp_authkey)) |
3538 | return -EINVAL; | 3544 | return -EINVAL; |
3545 | /* authkey->sca_keylength is u16, so optlen can't be bigger than | ||
3546 | * this. | ||
3547 | */ | ||
3548 | optlen = min_t(unsigned int, optlen, USHRT_MAX + | ||
3549 | sizeof(struct sctp_authkey)); | ||
3539 | 3550 | ||
3540 | authkey = memdup_user(optval, optlen); | 3551 | authkey = memdup_user(optval, optlen); |
3541 | if (IS_ERR(authkey)) | 3552 | if (IS_ERR(authkey)) |
@@ -3891,13 +3902,20 @@ static int sctp_setsockopt_reset_streams(struct sock *sk, | |||
3891 | struct sctp_association *asoc; | 3902 | struct sctp_association *asoc; |
3892 | int retval = -EINVAL; | 3903 | int retval = -EINVAL; |
3893 | 3904 | ||
3894 | if (optlen < sizeof(struct sctp_reset_streams)) | 3905 | if (optlen < sizeof(*params)) |
3895 | return -EINVAL; | 3906 | return -EINVAL; |
3907 | /* srs_number_streams is u16, so optlen can't be bigger than this. */ | ||
3908 | optlen = min_t(unsigned int, optlen, USHRT_MAX + | ||
3909 | sizeof(__u16) * sizeof(*params)); | ||
3896 | 3910 | ||
3897 | params = memdup_user(optval, optlen); | 3911 | params = memdup_user(optval, optlen); |
3898 | if (IS_ERR(params)) | 3912 | if (IS_ERR(params)) |
3899 | return PTR_ERR(params); | 3913 | return PTR_ERR(params); |
3900 | 3914 | ||
3915 | if (params->srs_number_streams * sizeof(__u16) > | ||
3916 | optlen - sizeof(*params)) | ||
3917 | goto out; | ||
3918 | |||
3901 | asoc = sctp_id2assoc(sk, params->srs_assoc_id); | 3919 | asoc = sctp_id2assoc(sk, params->srs_assoc_id); |
3902 | if (!asoc) | 3920 | if (!asoc) |
3903 | goto out; | 3921 | goto out; |
@@ -4494,7 +4512,7 @@ static int sctp_init_sock(struct sock *sk) | |||
4494 | SCTP_DBG_OBJCNT_INC(sock); | 4512 | SCTP_DBG_OBJCNT_INC(sock); |
4495 | 4513 | ||
4496 | local_bh_disable(); | 4514 | local_bh_disable(); |
4497 | percpu_counter_inc(&sctp_sockets_allocated); | 4515 | sk_sockets_allocated_inc(sk); |
4498 | sock_prot_inuse_add(net, sk->sk_prot, 1); | 4516 | sock_prot_inuse_add(net, sk->sk_prot, 1); |
4499 | 4517 | ||
4500 | /* Nothing can fail after this block, otherwise | 4518 | /* Nothing can fail after this block, otherwise |
@@ -4538,7 +4556,7 @@ static void sctp_destroy_sock(struct sock *sk) | |||
4538 | } | 4556 | } |
4539 | sctp_endpoint_free(sp->ep); | 4557 | sctp_endpoint_free(sp->ep); |
4540 | local_bh_disable(); | 4558 | local_bh_disable(); |
4541 | percpu_counter_dec(&sctp_sockets_allocated); | 4559 | sk_sockets_allocated_dec(sk); |
4542 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); | 4560 | sock_prot_inuse_add(sock_net(sk), sk->sk_prot, -1); |
4543 | local_bh_enable(); | 4561 | local_bh_enable(); |
4544 | } | 4562 | } |
@@ -5011,7 +5029,7 @@ static int sctp_getsockopt_autoclose(struct sock *sk, int len, char __user *optv | |||
5011 | len = sizeof(int); | 5029 | len = sizeof(int); |
5012 | if (put_user(len, optlen)) | 5030 | if (put_user(len, optlen)) |
5013 | return -EFAULT; | 5031 | return -EFAULT; |
5014 | if (copy_to_user(optval, &sctp_sk(sk)->autoclose, sizeof(int))) | 5032 | if (copy_to_user(optval, &sctp_sk(sk)->autoclose, len)) |
5015 | return -EFAULT; | 5033 | return -EFAULT; |
5016 | return 0; | 5034 | return 0; |
5017 | } | 5035 | } |
@@ -5641,6 +5659,9 @@ copy_getaddrs: | |||
5641 | err = -EFAULT; | 5659 | err = -EFAULT; |
5642 | goto out; | 5660 | goto out; |
5643 | } | 5661 | } |
5662 | /* XXX: We should have accounted for sizeof(struct sctp_getaddrs) too, | ||
5663 | * but we can't change it anymore. | ||
5664 | */ | ||
5644 | if (put_user(bytes_copied, optlen)) | 5665 | if (put_user(bytes_copied, optlen)) |
5645 | err = -EFAULT; | 5666 | err = -EFAULT; |
5646 | out: | 5667 | out: |
@@ -6077,7 +6098,7 @@ static int sctp_getsockopt_maxseg(struct sock *sk, int len, | |||
6077 | params.assoc_id = 0; | 6098 | params.assoc_id = 0; |
6078 | } else if (len >= sizeof(struct sctp_assoc_value)) { | 6099 | } else if (len >= sizeof(struct sctp_assoc_value)) { |
6079 | len = sizeof(struct sctp_assoc_value); | 6100 | len = sizeof(struct sctp_assoc_value); |
6080 | if (copy_from_user(¶ms, optval, sizeof(params))) | 6101 | if (copy_from_user(¶ms, optval, len)) |
6081 | return -EFAULT; | 6102 | return -EFAULT; |
6082 | } else | 6103 | } else |
6083 | return -EINVAL; | 6104 | return -EINVAL; |
@@ -6247,7 +6268,9 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
6247 | 6268 | ||
6248 | if (len < sizeof(struct sctp_authkeyid)) | 6269 | if (len < sizeof(struct sctp_authkeyid)) |
6249 | return -EINVAL; | 6270 | return -EINVAL; |
6250 | if (copy_from_user(&val, optval, sizeof(struct sctp_authkeyid))) | 6271 | |
6272 | len = sizeof(struct sctp_authkeyid); | ||
6273 | if (copy_from_user(&val, optval, len)) | ||
6251 | return -EFAULT; | 6274 | return -EFAULT; |
6252 | 6275 | ||
6253 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); | 6276 | asoc = sctp_id2assoc(sk, val.scact_assoc_id); |
@@ -6259,7 +6282,6 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len, | |||
6259 | else | 6282 | else |
6260 | val.scact_keynumber = ep->active_key_id; | 6283 | val.scact_keynumber = ep->active_key_id; |
6261 | 6284 | ||
6262 | len = sizeof(struct sctp_authkeyid); | ||
6263 | if (put_user(len, optlen)) | 6285 | if (put_user(len, optlen)) |
6264 | return -EFAULT; | 6286 | return -EFAULT; |
6265 | if (copy_to_user(optval, &val, len)) | 6287 | if (copy_to_user(optval, &val, len)) |
@@ -6285,7 +6307,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len, | |||
6285 | if (len < sizeof(struct sctp_authchunks)) | 6307 | if (len < sizeof(struct sctp_authchunks)) |
6286 | return -EINVAL; | 6308 | return -EINVAL; |
6287 | 6309 | ||
6288 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | 6310 | if (copy_from_user(&val, optval, sizeof(val))) |
6289 | return -EFAULT; | 6311 | return -EFAULT; |
6290 | 6312 | ||
6291 | to = p->gauth_chunks; | 6313 | to = p->gauth_chunks; |
@@ -6330,7 +6352,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len, | |||
6330 | if (len < sizeof(struct sctp_authchunks)) | 6352 | if (len < sizeof(struct sctp_authchunks)) |
6331 | return -EINVAL; | 6353 | return -EINVAL; |
6332 | 6354 | ||
6333 | if (copy_from_user(&val, optval, sizeof(struct sctp_authchunks))) | 6355 | if (copy_from_user(&val, optval, sizeof(val))) |
6334 | return -EFAULT; | 6356 | return -EFAULT; |
6335 | 6357 | ||
6336 | to = p->gauth_chunks; | 6358 | to = p->gauth_chunks; |
@@ -7998,12 +8020,12 @@ void sctp_sock_rfree(struct sk_buff *skb) | |||
7998 | 8020 | ||
7999 | /* Helper function to wait for space in the sndbuf. */ | 8021 | /* Helper function to wait for space in the sndbuf. */ |
8000 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | 8022 | static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, |
8001 | size_t msg_len, struct sock **orig_sk) | 8023 | size_t msg_len) |
8002 | { | 8024 | { |
8003 | struct sock *sk = asoc->base.sk; | 8025 | struct sock *sk = asoc->base.sk; |
8004 | int err = 0; | ||
8005 | long current_timeo = *timeo_p; | 8026 | long current_timeo = *timeo_p; |
8006 | DEFINE_WAIT(wait); | 8027 | DEFINE_WAIT(wait); |
8028 | int err = 0; | ||
8007 | 8029 | ||
8008 | pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, | 8030 | pr_debug("%s: asoc:%p, timeo:%ld, msg_len:%zu\n", __func__, asoc, |
8009 | *timeo_p, msg_len); | 8031 | *timeo_p, msg_len); |
@@ -8032,17 +8054,13 @@ static int sctp_wait_for_sndbuf(struct sctp_association *asoc, long *timeo_p, | |||
8032 | release_sock(sk); | 8054 | release_sock(sk); |
8033 | current_timeo = schedule_timeout(current_timeo); | 8055 | current_timeo = schedule_timeout(current_timeo); |
8034 | lock_sock(sk); | 8056 | lock_sock(sk); |
8035 | if (sk != asoc->base.sk) { | 8057 | if (sk != asoc->base.sk) |
8036 | release_sock(sk); | 8058 | goto do_error; |
8037 | sk = asoc->base.sk; | ||
8038 | lock_sock(sk); | ||
8039 | } | ||
8040 | 8059 | ||
8041 | *timeo_p = current_timeo; | 8060 | *timeo_p = current_timeo; |
8042 | } | 8061 | } |
8043 | 8062 | ||
8044 | out: | 8063 | out: |
8045 | *orig_sk = sk; | ||
8046 | finish_wait(&asoc->wait, &wait); | 8064 | finish_wait(&asoc->wait, &wait); |
8047 | 8065 | ||
8048 | /* Release the association's refcnt. */ | 8066 | /* Release the association's refcnt. */ |
diff --git a/net/sctp/stream.c b/net/sctp/stream.c index 76ea66be0bbe..524dfeb94c41 100644 --- a/net/sctp/stream.c +++ b/net/sctp/stream.c | |||
@@ -156,9 +156,9 @@ int sctp_stream_init(struct sctp_stream *stream, __u16 outcnt, __u16 incnt, | |||
156 | sctp_stream_outq_migrate(stream, NULL, outcnt); | 156 | sctp_stream_outq_migrate(stream, NULL, outcnt); |
157 | sched->sched_all(stream); | 157 | sched->sched_all(stream); |
158 | 158 | ||
159 | i = sctp_stream_alloc_out(stream, outcnt, gfp); | 159 | ret = sctp_stream_alloc_out(stream, outcnt, gfp); |
160 | if (i) | 160 | if (ret) |
161 | return i; | 161 | goto out; |
162 | 162 | ||
163 | stream->outcnt = outcnt; | 163 | stream->outcnt = outcnt; |
164 | for (i = 0; i < stream->outcnt; i++) | 164 | for (i = 0; i < stream->outcnt; i++) |
@@ -170,19 +170,17 @@ in: | |||
170 | if (!incnt) | 170 | if (!incnt) |
171 | goto out; | 171 | goto out; |
172 | 172 | ||
173 | i = sctp_stream_alloc_in(stream, incnt, gfp); | 173 | ret = sctp_stream_alloc_in(stream, incnt, gfp); |
174 | if (i) { | 174 | if (ret) { |
175 | ret = -ENOMEM; | 175 | sched->free(stream); |
176 | goto free; | 176 | kfree(stream->out); |
177 | stream->out = NULL; | ||
178 | stream->outcnt = 0; | ||
179 | goto out; | ||
177 | } | 180 | } |
178 | 181 | ||
179 | stream->incnt = incnt; | 182 | stream->incnt = incnt; |
180 | goto out; | ||
181 | 183 | ||
182 | free: | ||
183 | sched->free(stream); | ||
184 | kfree(stream->out); | ||
185 | stream->out = NULL; | ||
186 | out: | 184 | out: |
187 | return ret; | 185 | return ret; |
188 | } | 186 | } |
diff --git a/net/sctp/transport.c b/net/sctp/transport.c index 1e5a22430cf5..47f82bd794d9 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c | |||
@@ -248,28 +248,37 @@ void sctp_transport_pmtu(struct sctp_transport *transport, struct sock *sk) | |||
248 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; | 248 | transport->pathmtu = SCTP_DEFAULT_MAXSEGMENT; |
249 | } | 249 | } |
250 | 250 | ||
251 | void sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) | 251 | bool sctp_transport_update_pmtu(struct sctp_transport *t, u32 pmtu) |
252 | { | 252 | { |
253 | struct dst_entry *dst = sctp_transport_dst_check(t); | 253 | struct dst_entry *dst = sctp_transport_dst_check(t); |
254 | bool change = true; | ||
254 | 255 | ||
255 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { | 256 | if (unlikely(pmtu < SCTP_DEFAULT_MINSEGMENT)) { |
256 | pr_warn("%s: Reported pmtu %d too low, using default minimum of %d\n", | 257 | pr_warn_ratelimited("%s: Reported pmtu %d too low, using default minimum of %d\n", |
257 | __func__, pmtu, SCTP_DEFAULT_MINSEGMENT); | 258 | __func__, pmtu, SCTP_DEFAULT_MINSEGMENT); |
258 | /* Use default minimum segment size and disable | 259 | /* Use default minimum segment instead */ |
259 | * pmtu discovery on this transport. | 260 | pmtu = SCTP_DEFAULT_MINSEGMENT; |
260 | */ | ||
261 | t->pathmtu = SCTP_DEFAULT_MINSEGMENT; | ||
262 | } else { | ||
263 | t->pathmtu = pmtu; | ||
264 | } | 261 | } |
262 | pmtu = SCTP_TRUNC4(pmtu); | ||
265 | 263 | ||
266 | if (dst) { | 264 | if (dst) { |
267 | dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu); | 265 | dst->ops->update_pmtu(dst, t->asoc->base.sk, NULL, pmtu); |
268 | dst = sctp_transport_dst_check(t); | 266 | dst = sctp_transport_dst_check(t); |
269 | } | 267 | } |
270 | 268 | ||
271 | if (!dst) | 269 | if (!dst) { |
272 | t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk); | 270 | t->af_specific->get_dst(t, &t->saddr, &t->fl, t->asoc->base.sk); |
271 | dst = t->dst; | ||
272 | } | ||
273 | |||
274 | if (dst) { | ||
275 | /* Re-fetch, as under layers may have a higher minimum size */ | ||
276 | pmtu = SCTP_TRUNC4(dst_mtu(dst)); | ||
277 | change = t->pathmtu != pmtu; | ||
278 | } | ||
279 | t->pathmtu = pmtu; | ||
280 | |||
281 | return change; | ||
273 | } | 282 | } |
274 | 283 | ||
275 | /* Caches the dst entry and source address for a transport's destination | 284 | /* Caches the dst entry and source address for a transport's destination |
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c index a71be33f3afe..e36ec5dd64c6 100644 --- a/net/sctp/ulpqueue.c +++ b/net/sctp/ulpqueue.c | |||
@@ -1084,29 +1084,21 @@ void sctp_ulpq_partial_delivery(struct sctp_ulpq *ulpq, | |||
1084 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, | 1084 | void sctp_ulpq_renege(struct sctp_ulpq *ulpq, struct sctp_chunk *chunk, |
1085 | gfp_t gfp) | 1085 | gfp_t gfp) |
1086 | { | 1086 | { |
1087 | struct sctp_association *asoc; | 1087 | struct sctp_association *asoc = ulpq->asoc; |
1088 | __u16 needed, freed; | 1088 | __u32 freed = 0; |
1089 | 1089 | __u16 needed; | |
1090 | asoc = ulpq->asoc; | ||
1091 | 1090 | ||
1092 | if (chunk) { | 1091 | needed = ntohs(chunk->chunk_hdr->length) - |
1093 | needed = ntohs(chunk->chunk_hdr->length); | 1092 | sizeof(struct sctp_data_chunk); |
1094 | needed -= sizeof(struct sctp_data_chunk); | ||
1095 | } else | ||
1096 | needed = SCTP_DEFAULT_MAXWINDOW; | ||
1097 | |||
1098 | freed = 0; | ||
1099 | 1093 | ||
1100 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { | 1094 | if (skb_queue_empty(&asoc->base.sk->sk_receive_queue)) { |
1101 | freed = sctp_ulpq_renege_order(ulpq, needed); | 1095 | freed = sctp_ulpq_renege_order(ulpq, needed); |
1102 | if (freed < needed) { | 1096 | if (freed < needed) |
1103 | freed += sctp_ulpq_renege_frags(ulpq, needed - freed); | 1097 | freed += sctp_ulpq_renege_frags(ulpq, needed - freed); |
1104 | } | ||
1105 | } | 1098 | } |
1106 | /* If able to free enough room, accept this chunk. */ | 1099 | /* If able to free enough room, accept this chunk. */ |
1107 | if (chunk && (freed >= needed)) { | 1100 | if (freed >= needed) { |
1108 | int retval; | 1101 | int retval = sctp_ulpq_tail_data(ulpq, chunk, gfp); |
1109 | retval = sctp_ulpq_tail_data(ulpq, chunk, gfp); | ||
1110 | /* | 1102 | /* |
1111 | * Enter partial delivery if chunk has not been | 1103 | * Enter partial delivery if chunk has not been |
1112 | * delivered; otherwise, drain the reassembly queue. | 1104 | * delivered; otherwise, drain the reassembly queue. |
diff --git a/net/socket.c b/net/socket.c index 05f361faec45..6f05d5c4bf30 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -436,8 +436,10 @@ static int sock_map_fd(struct socket *sock, int flags) | |||
436 | { | 436 | { |
437 | struct file *newfile; | 437 | struct file *newfile; |
438 | int fd = get_unused_fd_flags(flags); | 438 | int fd = get_unused_fd_flags(flags); |
439 | if (unlikely(fd < 0)) | 439 | if (unlikely(fd < 0)) { |
440 | sock_release(sock); | ||
440 | return fd; | 441 | return fd; |
442 | } | ||
441 | 443 | ||
442 | newfile = sock_alloc_file(sock, flags, NULL); | 444 | newfile = sock_alloc_file(sock, flags, NULL); |
443 | if (likely(!IS_ERR(newfile))) { | 445 | if (likely(!IS_ERR(newfile))) { |
@@ -2619,6 +2621,15 @@ out_fs: | |||
2619 | 2621 | ||
2620 | core_initcall(sock_init); /* early initcall */ | 2622 | core_initcall(sock_init); /* early initcall */ |
2621 | 2623 | ||
2624 | static int __init jit_init(void) | ||
2625 | { | ||
2626 | #ifdef CONFIG_BPF_JIT_ALWAYS_ON | ||
2627 | bpf_jit_enable = 1; | ||
2628 | #endif | ||
2629 | return 0; | ||
2630 | } | ||
2631 | pure_initcall(jit_init); | ||
2632 | |||
2622 | #ifdef CONFIG_PROC_FS | 2633 | #ifdef CONFIG_PROC_FS |
2623 | void socket_seq_show(struct seq_file *seq) | 2634 | void socket_seq_show(struct seq_file *seq) |
2624 | { | 2635 | { |
diff --git a/net/strparser/strparser.c b/net/strparser/strparser.c index c5fda15ba319..1fdab5c4eda8 100644 --- a/net/strparser/strparser.c +++ b/net/strparser/strparser.c | |||
@@ -401,7 +401,7 @@ void strp_data_ready(struct strparser *strp) | |||
401 | * allows a thread in BH context to safely check if the process | 401 | * allows a thread in BH context to safely check if the process |
402 | * lock is held. In this case, if the lock is held, queue work. | 402 | * lock is held. In this case, if the lock is held, queue work. |
403 | */ | 403 | */ |
404 | if (sock_owned_by_user(strp->sk)) { | 404 | if (sock_owned_by_user_nocheck(strp->sk)) { |
405 | queue_work(strp_wq, &strp->work); | 405 | queue_work(strp_wq, &strp->work); |
406 | return; | 406 | return; |
407 | } | 407 | } |
diff --git a/net/sunrpc/auth_gss/gss_rpc_xdr.c b/net/sunrpc/auth_gss/gss_rpc_xdr.c index c4778cae58ef..444380f968f1 100644 --- a/net/sunrpc/auth_gss/gss_rpc_xdr.c +++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c | |||
@@ -231,6 +231,7 @@ static int gssx_dec_linux_creds(struct xdr_stream *xdr, | |||
231 | goto out_free_groups; | 231 | goto out_free_groups; |
232 | creds->cr_group_info->gid[i] = kgid; | 232 | creds->cr_group_info->gid[i] = kgid; |
233 | } | 233 | } |
234 | groups_sort(creds->cr_group_info); | ||
234 | 235 | ||
235 | return 0; | 236 | return 0; |
236 | out_free_groups: | 237 | out_free_groups: |
diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index 5dd4e6c9fef2..26531193fce4 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c | |||
@@ -481,6 +481,7 @@ static int rsc_parse(struct cache_detail *cd, | |||
481 | goto out; | 481 | goto out; |
482 | rsci.cred.cr_group_info->gid[i] = kgid; | 482 | rsci.cred.cr_group_info->gid[i] = kgid; |
483 | } | 483 | } |
484 | groups_sort(rsci.cred.cr_group_info); | ||
484 | 485 | ||
485 | /* mech name */ | 486 | /* mech name */ |
486 | len = qword_get(&mesg, buf, mlen); | 487 | len = qword_get(&mesg, buf, mlen); |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 740b67d5a733..af7f28fb8102 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -520,6 +520,7 @@ static int unix_gid_parse(struct cache_detail *cd, | |||
520 | ug.gi->gid[i] = kgid; | 520 | ug.gi->gid[i] = kgid; |
521 | } | 521 | } |
522 | 522 | ||
523 | groups_sort(ug.gi); | ||
523 | ugp = unix_gid_lookup(cd, uid); | 524 | ugp = unix_gid_lookup(cd, uid); |
524 | if (ugp) { | 525 | if (ugp) { |
525 | struct cache_head *ch; | 526 | struct cache_head *ch; |
@@ -819,6 +820,7 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
819 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); | 820 | kgid_t kgid = make_kgid(&init_user_ns, svc_getnl(argv)); |
820 | cred->cr_group_info->gid[i] = kgid; | 821 | cred->cr_group_info->gid[i] = kgid; |
821 | } | 822 | } |
823 | groups_sort(cred->cr_group_info); | ||
822 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { | 824 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { |
823 | *authp = rpc_autherr_badverf; | 825 | *authp = rpc_autherr_badverf; |
824 | return SVC_DENIED; | 826 | return SVC_DENIED; |
diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c index 333b9d697ae5..33b74fd84051 100644 --- a/net/sunrpc/xprt.c +++ b/net/sunrpc/xprt.c | |||
@@ -1001,6 +1001,7 @@ void xprt_transmit(struct rpc_task *task) | |||
1001 | { | 1001 | { |
1002 | struct rpc_rqst *req = task->tk_rqstp; | 1002 | struct rpc_rqst *req = task->tk_rqstp; |
1003 | struct rpc_xprt *xprt = req->rq_xprt; | 1003 | struct rpc_xprt *xprt = req->rq_xprt; |
1004 | unsigned int connect_cookie; | ||
1004 | int status, numreqs; | 1005 | int status, numreqs; |
1005 | 1006 | ||
1006 | dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); | 1007 | dprintk("RPC: %5u xprt_transmit(%u)\n", task->tk_pid, req->rq_slen); |
@@ -1024,6 +1025,7 @@ void xprt_transmit(struct rpc_task *task) | |||
1024 | } else if (!req->rq_bytes_sent) | 1025 | } else if (!req->rq_bytes_sent) |
1025 | return; | 1026 | return; |
1026 | 1027 | ||
1028 | connect_cookie = xprt->connect_cookie; | ||
1027 | req->rq_xtime = ktime_get(); | 1029 | req->rq_xtime = ktime_get(); |
1028 | status = xprt->ops->send_request(task); | 1030 | status = xprt->ops->send_request(task); |
1029 | trace_xprt_transmit(xprt, req->rq_xid, status); | 1031 | trace_xprt_transmit(xprt, req->rq_xid, status); |
@@ -1047,20 +1049,28 @@ void xprt_transmit(struct rpc_task *task) | |||
1047 | xprt->stat.bklog_u += xprt->backlog.qlen; | 1049 | xprt->stat.bklog_u += xprt->backlog.qlen; |
1048 | xprt->stat.sending_u += xprt->sending.qlen; | 1050 | xprt->stat.sending_u += xprt->sending.qlen; |
1049 | xprt->stat.pending_u += xprt->pending.qlen; | 1051 | xprt->stat.pending_u += xprt->pending.qlen; |
1052 | spin_unlock_bh(&xprt->transport_lock); | ||
1050 | 1053 | ||
1051 | /* Don't race with disconnect */ | 1054 | req->rq_connect_cookie = connect_cookie; |
1052 | if (!xprt_connected(xprt)) | 1055 | if (rpc_reply_expected(task) && !READ_ONCE(req->rq_reply_bytes_recvd)) { |
1053 | task->tk_status = -ENOTCONN; | ||
1054 | else { | ||
1055 | /* | 1056 | /* |
1056 | * Sleep on the pending queue since | 1057 | * Sleep on the pending queue if we're expecting a reply. |
1057 | * we're expecting a reply. | 1058 | * The spinlock ensures atomicity between the test of |
1059 | * req->rq_reply_bytes_recvd, and the call to rpc_sleep_on(). | ||
1058 | */ | 1060 | */ |
1059 | if (!req->rq_reply_bytes_recvd && rpc_reply_expected(task)) | 1061 | spin_lock(&xprt->recv_lock); |
1062 | if (!req->rq_reply_bytes_recvd) { | ||
1060 | rpc_sleep_on(&xprt->pending, task, xprt_timer); | 1063 | rpc_sleep_on(&xprt->pending, task, xprt_timer); |
1061 | req->rq_connect_cookie = xprt->connect_cookie; | 1064 | /* |
1065 | * Send an extra queue wakeup call if the | ||
1066 | * connection was dropped in case the call to | ||
1067 | * rpc_sleep_on() raced. | ||
1068 | */ | ||
1069 | if (!xprt_connected(xprt)) | ||
1070 | xprt_wake_pending_tasks(xprt, -ENOTCONN); | ||
1071 | } | ||
1072 | spin_unlock(&xprt->recv_lock); | ||
1062 | } | 1073 | } |
1063 | spin_unlock_bh(&xprt->transport_lock); | ||
1064 | } | 1074 | } |
1065 | 1075 | ||
1066 | static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task) | 1076 | static void xprt_add_backlog(struct rpc_xprt *xprt, struct rpc_task *task) |
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c index ed34dc0f144c..a3f2ab283aeb 100644 --- a/net/sunrpc/xprtrdma/rpc_rdma.c +++ b/net/sunrpc/xprtrdma/rpc_rdma.c | |||
@@ -1408,11 +1408,7 @@ void rpcrdma_reply_handler(struct rpcrdma_rep *rep) | |||
1408 | dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n", | 1408 | dprintk("RPC: %s: reply %p completes request %p (xid 0x%08x)\n", |
1409 | __func__, rep, req, be32_to_cpu(rep->rr_xid)); | 1409 | __func__, rep, req, be32_to_cpu(rep->rr_xid)); |
1410 | 1410 | ||
1411 | if (list_empty(&req->rl_registered) && | 1411 | queue_work_on(req->rl_cpu, rpcrdma_receive_wq, &rep->rr_work); |
1412 | !test_bit(RPCRDMA_REQ_F_TX_RESOURCES, &req->rl_flags)) | ||
1413 | rpcrdma_complete_rqst(rep); | ||
1414 | else | ||
1415 | queue_work(rpcrdma_receive_wq, &rep->rr_work); | ||
1416 | return; | 1412 | return; |
1417 | 1413 | ||
1418 | out_badstatus: | 1414 | out_badstatus: |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index 646c24494ea7..6ee1ad8978f3 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include <linux/slab.h> | 52 | #include <linux/slab.h> |
53 | #include <linux/seq_file.h> | 53 | #include <linux/seq_file.h> |
54 | #include <linux/sunrpc/addr.h> | 54 | #include <linux/sunrpc/addr.h> |
55 | #include <linux/smp.h> | ||
55 | 56 | ||
56 | #include "xprt_rdma.h" | 57 | #include "xprt_rdma.h" |
57 | 58 | ||
@@ -656,6 +657,7 @@ xprt_rdma_allocate(struct rpc_task *task) | |||
656 | task->tk_pid, __func__, rqst->rq_callsize, | 657 | task->tk_pid, __func__, rqst->rq_callsize, |
657 | rqst->rq_rcvsize, req); | 658 | rqst->rq_rcvsize, req); |
658 | 659 | ||
660 | req->rl_cpu = smp_processor_id(); | ||
659 | req->rl_connect_cookie = 0; /* our reserved value */ | 661 | req->rl_connect_cookie = 0; /* our reserved value */ |
660 | rpcrdma_set_xprtdata(rqst, req); | 662 | rpcrdma_set_xprtdata(rqst, req); |
661 | rqst->rq_buffer = req->rl_sendbuf->rg_base; | 663 | rqst->rq_buffer = req->rl_sendbuf->rg_base; |
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c index 710b3f77db82..8607c029c0dd 100644 --- a/net/sunrpc/xprtrdma/verbs.c +++ b/net/sunrpc/xprtrdma/verbs.c | |||
@@ -83,7 +83,7 @@ rpcrdma_alloc_wq(void) | |||
83 | struct workqueue_struct *recv_wq; | 83 | struct workqueue_struct *recv_wq; |
84 | 84 | ||
85 | recv_wq = alloc_workqueue("xprtrdma_receive", | 85 | recv_wq = alloc_workqueue("xprtrdma_receive", |
86 | WQ_MEM_RECLAIM | WQ_UNBOUND | WQ_HIGHPRI, | 86 | WQ_MEM_RECLAIM | WQ_HIGHPRI, |
87 | 0); | 87 | 0); |
88 | if (!recv_wq) | 88 | if (!recv_wq) |
89 | return -ENOMEM; | 89 | return -ENOMEM; |
diff --git a/net/sunrpc/xprtrdma/xprt_rdma.h b/net/sunrpc/xprtrdma/xprt_rdma.h index 51686d9eac5f..1342f743f1c4 100644 --- a/net/sunrpc/xprtrdma/xprt_rdma.h +++ b/net/sunrpc/xprtrdma/xprt_rdma.h | |||
@@ -342,6 +342,7 @@ enum { | |||
342 | struct rpcrdma_buffer; | 342 | struct rpcrdma_buffer; |
343 | struct rpcrdma_req { | 343 | struct rpcrdma_req { |
344 | struct list_head rl_list; | 344 | struct list_head rl_list; |
345 | int rl_cpu; | ||
345 | unsigned int rl_connect_cookie; | 346 | unsigned int rl_connect_cookie; |
346 | struct rpcrdma_buffer *rl_buffer; | 347 | struct rpcrdma_buffer *rl_buffer; |
347 | struct rpcrdma_rep *rl_reply; | 348 | struct rpcrdma_rep *rl_reply; |
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 47ec121574ce..c8001471da6c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c | |||
@@ -324,6 +324,7 @@ restart: | |||
324 | if (res) { | 324 | if (res) { |
325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", | 325 | pr_warn("Bearer <%s> rejected, enable failure (%d)\n", |
326 | name, -res); | 326 | name, -res); |
327 | kfree(b); | ||
327 | return -EINVAL; | 328 | return -EINVAL; |
328 | } | 329 | } |
329 | 330 | ||
@@ -347,8 +348,10 @@ restart: | |||
347 | if (skb) | 348 | if (skb) |
348 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); | 349 | tipc_bearer_xmit_skb(net, bearer_id, skb, &b->bcast_addr); |
349 | 350 | ||
350 | if (tipc_mon_create(net, bearer_id)) | 351 | if (tipc_mon_create(net, bearer_id)) { |
352 | bearer_disable(net, b); | ||
351 | return -ENOMEM; | 353 | return -ENOMEM; |
354 | } | ||
352 | 355 | ||
353 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", | 356 | pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n", |
354 | name, | 357 | name, |
diff --git a/net/tipc/group.c b/net/tipc/group.c index 95fec2c057d6..5f4ffae807ee 100644 --- a/net/tipc/group.c +++ b/net/tipc/group.c | |||
@@ -109,7 +109,8 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
109 | static void tipc_group_decr_active(struct tipc_group *grp, | 109 | static void tipc_group_decr_active(struct tipc_group *grp, |
110 | struct tipc_member *m) | 110 | struct tipc_member *m) |
111 | { | 111 | { |
112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING) | 112 | if (m->state == MBR_ACTIVE || m->state == MBR_RECLAIMING || |
113 | m->state == MBR_REMITTED) | ||
113 | grp->active_cnt--; | 114 | grp->active_cnt--; |
114 | } | 115 | } |
115 | 116 | ||
@@ -351,8 +352,7 @@ void tipc_group_update_member(struct tipc_member *m, int len) | |||
351 | if (m->window >= ADV_IDLE) | 352 | if (m->window >= ADV_IDLE) |
352 | return; | 353 | return; |
353 | 354 | ||
354 | if (!list_empty(&m->congested)) | 355 | list_del_init(&m->congested); |
355 | return; | ||
356 | 356 | ||
357 | /* Sort member into congested members' list */ | 357 | /* Sort member into congested members' list */ |
358 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { | 358 | list_for_each_entry_safe(_m, tmp, &grp->congested, congested) { |
@@ -369,18 +369,20 @@ void tipc_group_update_bc_members(struct tipc_group *grp, int len, bool ack) | |||
369 | u16 prev = grp->bc_snd_nxt - 1; | 369 | u16 prev = grp->bc_snd_nxt - 1; |
370 | struct tipc_member *m; | 370 | struct tipc_member *m; |
371 | struct rb_node *n; | 371 | struct rb_node *n; |
372 | u16 ackers = 0; | ||
372 | 373 | ||
373 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { | 374 | for (n = rb_first(&grp->members); n; n = rb_next(n)) { |
374 | m = container_of(n, struct tipc_member, tree_node); | 375 | m = container_of(n, struct tipc_member, tree_node); |
375 | if (tipc_group_is_enabled(m)) { | 376 | if (tipc_group_is_enabled(m)) { |
376 | tipc_group_update_member(m, len); | 377 | tipc_group_update_member(m, len); |
377 | m->bc_acked = prev; | 378 | m->bc_acked = prev; |
379 | ackers++; | ||
378 | } | 380 | } |
379 | } | 381 | } |
380 | 382 | ||
381 | /* Mark number of acknowledges to expect, if any */ | 383 | /* Mark number of acknowledges to expect, if any */ |
382 | if (ack) | 384 | if (ack) |
383 | grp->bc_ackers = grp->member_cnt; | 385 | grp->bc_ackers = ackers; |
384 | grp->bc_snd_nxt++; | 386 | grp->bc_snd_nxt++; |
385 | } | 387 | } |
386 | 388 | ||
@@ -561,7 +563,7 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
561 | int max_active = grp->max_active; | 563 | int max_active = grp->max_active; |
562 | int reclaim_limit = max_active * 3 / 4; | 564 | int reclaim_limit = max_active * 3 / 4; |
563 | int active_cnt = grp->active_cnt; | 565 | int active_cnt = grp->active_cnt; |
564 | struct tipc_member *m, *rm; | 566 | struct tipc_member *m, *rm, *pm; |
565 | 567 | ||
566 | m = tipc_group_find_member(grp, node, port); | 568 | m = tipc_group_find_member(grp, node, port); |
567 | if (!m) | 569 | if (!m) |
@@ -604,6 +606,17 @@ void tipc_group_update_rcv_win(struct tipc_group *grp, int blks, u32 node, | |||
604 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); | 606 | pr_warn_ratelimited("Rcv unexpected msg after REMIT\n"); |
605 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 607 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
606 | } | 608 | } |
609 | grp->active_cnt--; | ||
610 | list_del_init(&m->list); | ||
611 | if (list_empty(&grp->pending)) | ||
612 | return; | ||
613 | |||
614 | /* Set oldest pending member to active and advertise */ | ||
615 | pm = list_first_entry(&grp->pending, struct tipc_member, list); | ||
616 | pm->state = MBR_ACTIVE; | ||
617 | list_move_tail(&pm->list, &grp->active); | ||
618 | grp->active_cnt++; | ||
619 | tipc_group_proto_xmit(grp, pm, GRP_ADV_MSG, xmitq); | ||
607 | break; | 620 | break; |
608 | case MBR_RECLAIMING: | 621 | case MBR_RECLAIMING: |
609 | case MBR_DISCOVERED: | 622 | case MBR_DISCOVERED: |
@@ -648,6 +661,7 @@ static void tipc_group_proto_xmit(struct tipc_group *grp, struct tipc_member *m, | |||
648 | } else if (mtyp == GRP_REMIT_MSG) { | 661 | } else if (mtyp == GRP_REMIT_MSG) { |
649 | msg_set_grp_remitted(hdr, m->window); | 662 | msg_set_grp_remitted(hdr, m->window); |
650 | } | 663 | } |
664 | msg_set_dest_droppable(hdr, true); | ||
651 | __skb_queue_tail(xmitq, skb); | 665 | __skb_queue_tail(xmitq, skb); |
652 | } | 666 | } |
653 | 667 | ||
@@ -689,15 +703,16 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
689 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 703 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
690 | __skb_queue_tail(inputq, m->event_msg); | 704 | __skb_queue_tail(inputq, m->event_msg); |
691 | } | 705 | } |
692 | if (m->window < ADV_IDLE) | 706 | list_del_init(&m->congested); |
693 | tipc_group_update_member(m, 0); | 707 | tipc_group_update_member(m, 0); |
694 | else | ||
695 | list_del_init(&m->congested); | ||
696 | return; | 708 | return; |
697 | case GRP_LEAVE_MSG: | 709 | case GRP_LEAVE_MSG: |
698 | if (!m) | 710 | if (!m) |
699 | return; | 711 | return; |
700 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); | 712 | m->bc_syncpt = msg_grp_bc_syncpt(hdr); |
713 | list_del_init(&m->list); | ||
714 | list_del_init(&m->congested); | ||
715 | *usr_wakeup = true; | ||
701 | 716 | ||
702 | /* Wait until WITHDRAW event is received */ | 717 | /* Wait until WITHDRAW event is received */ |
703 | if (m->state != MBR_LEAVING) { | 718 | if (m->state != MBR_LEAVING) { |
@@ -709,8 +724,6 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
709 | ehdr = buf_msg(m->event_msg); | 724 | ehdr = buf_msg(m->event_msg); |
710 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); | 725 | msg_set_grp_bc_seqno(ehdr, m->bc_syncpt); |
711 | __skb_queue_tail(inputq, m->event_msg); | 726 | __skb_queue_tail(inputq, m->event_msg); |
712 | *usr_wakeup = true; | ||
713 | list_del_init(&m->congested); | ||
714 | return; | 727 | return; |
715 | case GRP_ADV_MSG: | 728 | case GRP_ADV_MSG: |
716 | if (!m) | 729 | if (!m) |
@@ -741,14 +754,14 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
741 | if (!m || m->state != MBR_RECLAIMING) | 754 | if (!m || m->state != MBR_RECLAIMING) |
742 | return; | 755 | return; |
743 | 756 | ||
744 | list_del_init(&m->list); | ||
745 | grp->active_cnt--; | ||
746 | remitted = msg_grp_remitted(hdr); | 757 | remitted = msg_grp_remitted(hdr); |
747 | 758 | ||
748 | /* Messages preceding the REMIT still in receive queue */ | 759 | /* Messages preceding the REMIT still in receive queue */ |
749 | if (m->advertised > remitted) { | 760 | if (m->advertised > remitted) { |
750 | m->state = MBR_REMITTED; | 761 | m->state = MBR_REMITTED; |
751 | in_flight = m->advertised - remitted; | 762 | in_flight = m->advertised - remitted; |
763 | m->advertised = ADV_IDLE + in_flight; | ||
764 | return; | ||
752 | } | 765 | } |
753 | /* All messages preceding the REMIT have been read */ | 766 | /* All messages preceding the REMIT have been read */ |
754 | if (m->advertised <= remitted) { | 767 | if (m->advertised <= remitted) { |
@@ -760,6 +773,8 @@ void tipc_group_proto_rcv(struct tipc_group *grp, bool *usr_wakeup, | |||
760 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); | 773 | tipc_group_proto_xmit(grp, m, GRP_ADV_MSG, xmitq); |
761 | 774 | ||
762 | m->advertised = ADV_IDLE + in_flight; | 775 | m->advertised = ADV_IDLE + in_flight; |
776 | grp->active_cnt--; | ||
777 | list_del_init(&m->list); | ||
763 | 778 | ||
764 | /* Set oldest pending member to active and advertise */ | 779 | /* Set oldest pending member to active and advertise */ |
765 | if (list_empty(&grp->pending)) | 780 | if (list_empty(&grp->pending)) |
@@ -849,19 +864,29 @@ void tipc_group_member_evt(struct tipc_group *grp, | |||
849 | *usr_wakeup = true; | 864 | *usr_wakeup = true; |
850 | m->usr_pending = false; | 865 | m->usr_pending = false; |
851 | node_up = tipc_node_is_up(net, node); | 866 | node_up = tipc_node_is_up(net, node); |
852 | 867 | m->event_msg = NULL; | |
853 | /* Hold back event if more messages might be expected */ | 868 | |
854 | if (m->state != MBR_LEAVING && node_up) { | 869 | if (node_up) { |
855 | m->event_msg = skb; | 870 | /* Hold back event if a LEAVE msg should be expected */ |
856 | tipc_group_decr_active(grp, m); | 871 | if (m->state != MBR_LEAVING) { |
857 | m->state = MBR_LEAVING; | 872 | m->event_msg = skb; |
858 | } else { | 873 | tipc_group_decr_active(grp, m); |
859 | if (node_up) | 874 | m->state = MBR_LEAVING; |
875 | } else { | ||
860 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | 876 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); |
861 | else | 877 | __skb_queue_tail(inputq, skb); |
878 | } | ||
879 | } else { | ||
880 | if (m->state != MBR_LEAVING) { | ||
881 | tipc_group_decr_active(grp, m); | ||
882 | m->state = MBR_LEAVING; | ||
862 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); | 883 | msg_set_grp_bc_seqno(hdr, m->bc_rcv_nxt); |
884 | } else { | ||
885 | msg_set_grp_bc_seqno(hdr, m->bc_syncpt); | ||
886 | } | ||
863 | __skb_queue_tail(inputq, skb); | 887 | __skb_queue_tail(inputq, skb); |
864 | } | 888 | } |
889 | list_del_init(&m->list); | ||
865 | list_del_init(&m->congested); | 890 | list_del_init(&m->congested); |
866 | } | 891 | } |
867 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); | 892 | *sk_rcvbuf = tipc_group_rcvbuf_limit(grp); |
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 8e884ed06d4b..32dc33a94bc7 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c | |||
@@ -642,9 +642,13 @@ void tipc_mon_delete(struct net *net, int bearer_id) | |||
642 | { | 642 | { |
643 | struct tipc_net *tn = tipc_net(net); | 643 | struct tipc_net *tn = tipc_net(net); |
644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); | 644 | struct tipc_monitor *mon = tipc_monitor(net, bearer_id); |
645 | struct tipc_peer *self = get_self(net, bearer_id); | 645 | struct tipc_peer *self; |
646 | struct tipc_peer *peer, *tmp; | 646 | struct tipc_peer *peer, *tmp; |
647 | 647 | ||
648 | if (!mon) | ||
649 | return; | ||
650 | |||
651 | self = get_self(net, bearer_id); | ||
648 | write_lock_bh(&mon->lock); | 652 | write_lock_bh(&mon->lock); |
649 | tn->monitors[bearer_id] = NULL; | 653 | tn->monitors[bearer_id] = NULL; |
650 | list_for_each_entry_safe(peer, tmp, &self->list, list) { | 654 | list_for_each_entry_safe(peer, tmp, &self->list, list) { |
diff --git a/net/tipc/node.c b/net/tipc/node.c index 507017fe0f1b..9036d8756e73 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c | |||
@@ -1880,36 +1880,38 @@ int tipc_nl_node_get_link(struct sk_buff *skb, struct genl_info *info) | |||
1880 | 1880 | ||
1881 | if (strcmp(name, tipc_bclink_name) == 0) { | 1881 | if (strcmp(name, tipc_bclink_name) == 0) { |
1882 | err = tipc_nl_add_bc_link(net, &msg); | 1882 | err = tipc_nl_add_bc_link(net, &msg); |
1883 | if (err) { | 1883 | if (err) |
1884 | nlmsg_free(msg.skb); | 1884 | goto err_free; |
1885 | return err; | ||
1886 | } | ||
1887 | } else { | 1885 | } else { |
1888 | int bearer_id; | 1886 | int bearer_id; |
1889 | struct tipc_node *node; | 1887 | struct tipc_node *node; |
1890 | struct tipc_link *link; | 1888 | struct tipc_link *link; |
1891 | 1889 | ||
1892 | node = tipc_node_find_by_name(net, name, &bearer_id); | 1890 | node = tipc_node_find_by_name(net, name, &bearer_id); |
1893 | if (!node) | 1891 | if (!node) { |
1894 | return -EINVAL; | 1892 | err = -EINVAL; |
1893 | goto err_free; | ||
1894 | } | ||
1895 | 1895 | ||
1896 | tipc_node_read_lock(node); | 1896 | tipc_node_read_lock(node); |
1897 | link = node->links[bearer_id].link; | 1897 | link = node->links[bearer_id].link; |
1898 | if (!link) { | 1898 | if (!link) { |
1899 | tipc_node_read_unlock(node); | 1899 | tipc_node_read_unlock(node); |
1900 | nlmsg_free(msg.skb); | 1900 | err = -EINVAL; |
1901 | return -EINVAL; | 1901 | goto err_free; |
1902 | } | 1902 | } |
1903 | 1903 | ||
1904 | err = __tipc_nl_add_link(net, &msg, link, 0); | 1904 | err = __tipc_nl_add_link(net, &msg, link, 0); |
1905 | tipc_node_read_unlock(node); | 1905 | tipc_node_read_unlock(node); |
1906 | if (err) { | 1906 | if (err) |
1907 | nlmsg_free(msg.skb); | 1907 | goto err_free; |
1908 | return err; | ||
1909 | } | ||
1910 | } | 1908 | } |
1911 | 1909 | ||
1912 | return genlmsg_reply(msg.skb, info); | 1910 | return genlmsg_reply(msg.skb, info); |
1911 | |||
1912 | err_free: | ||
1913 | nlmsg_free(msg.skb); | ||
1914 | return err; | ||
1913 | } | 1915 | } |
1914 | 1916 | ||
1915 | int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info) | 1917 | int tipc_nl_node_reset_link_stats(struct sk_buff *skb, struct genl_info *info) |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 5d18c0caa92b..3b4084480377 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
@@ -727,11 +727,11 @@ static unsigned int tipc_poll(struct file *file, struct socket *sock, | |||
727 | 727 | ||
728 | switch (sk->sk_state) { | 728 | switch (sk->sk_state) { |
729 | case TIPC_ESTABLISHED: | 729 | case TIPC_ESTABLISHED: |
730 | case TIPC_CONNECTING: | ||
730 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) | 731 | if (!tsk->cong_link_cnt && !tsk_conn_cong(tsk)) |
731 | revents |= POLLOUT; | 732 | revents |= POLLOUT; |
732 | /* fall thru' */ | 733 | /* fall thru' */ |
733 | case TIPC_LISTEN: | 734 | case TIPC_LISTEN: |
734 | case TIPC_CONNECTING: | ||
735 | if (!skb_queue_empty(&sk->sk_receive_queue)) | 735 | if (!skb_queue_empty(&sk->sk_receive_queue)) |
736 | revents |= POLLIN | POLLRDNORM; | 736 | revents |= POLLIN | POLLRDNORM; |
737 | break; | 737 | break; |
@@ -1140,7 +1140,7 @@ void tipc_sk_mcast_rcv(struct net *net, struct sk_buff_head *arrvq, | |||
1140 | __skb_dequeue(arrvq); | 1140 | __skb_dequeue(arrvq); |
1141 | __skb_queue_tail(inputq, skb); | 1141 | __skb_queue_tail(inputq, skb); |
1142 | } | 1142 | } |
1143 | refcount_dec(&skb->users); | 1143 | kfree_skb(skb); |
1144 | spin_unlock_bh(&inputq->lock); | 1144 | spin_unlock_bh(&inputq->lock); |
1145 | continue; | 1145 | continue; |
1146 | } | 1146 | } |
diff --git a/net/tls/tls_main.c b/net/tls/tls_main.c index e07ee3ae0023..736719c8314e 100644 --- a/net/tls/tls_main.c +++ b/net/tls/tls_main.c | |||
@@ -367,8 +367,10 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | |||
367 | 367 | ||
368 | crypto_info = &ctx->crypto_send; | 368 | crypto_info = &ctx->crypto_send; |
369 | /* Currently we don't support set crypto info more than one time */ | 369 | /* Currently we don't support set crypto info more than one time */ |
370 | if (TLS_CRYPTO_INFO_READY(crypto_info)) | 370 | if (TLS_CRYPTO_INFO_READY(crypto_info)) { |
371 | rc = -EBUSY; | ||
371 | goto out; | 372 | goto out; |
373 | } | ||
372 | 374 | ||
373 | rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info)); | 375 | rc = copy_from_user(crypto_info, optval, sizeof(*crypto_info)); |
374 | if (rc) { | 376 | if (rc) { |
@@ -386,7 +388,7 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | |||
386 | case TLS_CIPHER_AES_GCM_128: { | 388 | case TLS_CIPHER_AES_GCM_128: { |
387 | if (optlen != sizeof(struct tls12_crypto_info_aes_gcm_128)) { | 389 | if (optlen != sizeof(struct tls12_crypto_info_aes_gcm_128)) { |
388 | rc = -EINVAL; | 390 | rc = -EINVAL; |
389 | goto out; | 391 | goto err_crypto_info; |
390 | } | 392 | } |
391 | rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info), | 393 | rc = copy_from_user(crypto_info + 1, optval + sizeof(*crypto_info), |
392 | optlen - sizeof(*crypto_info)); | 394 | optlen - sizeof(*crypto_info)); |
@@ -398,7 +400,7 @@ static int do_tls_setsockopt_tx(struct sock *sk, char __user *optval, | |||
398 | } | 400 | } |
399 | default: | 401 | default: |
400 | rc = -EINVAL; | 402 | rc = -EINVAL; |
401 | goto out; | 403 | goto err_crypto_info; |
402 | } | 404 | } |
403 | 405 | ||
404 | /* currently SW is default, we will have ethtool in future */ | 406 | /* currently SW is default, we will have ethtool in future */ |
@@ -454,6 +456,15 @@ static int tls_init(struct sock *sk) | |||
454 | struct tls_context *ctx; | 456 | struct tls_context *ctx; |
455 | int rc = 0; | 457 | int rc = 0; |
456 | 458 | ||
459 | /* The TLS ulp is currently supported only for TCP sockets | ||
460 | * in ESTABLISHED state. | ||
461 | * Supporting sockets in LISTEN state will require us | ||
462 | * to modify the accept implementation to clone rather then | ||
463 | * share the ulp context. | ||
464 | */ | ||
465 | if (sk->sk_state != TCP_ESTABLISHED) | ||
466 | return -ENOTSUPP; | ||
467 | |||
457 | /* allocate tls context */ | 468 | /* allocate tls context */ |
458 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); | 469 | ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); |
459 | if (!ctx) { | 470 | if (!ctx) { |
diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 73d19210dd49..0a9b72fbd761 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c | |||
@@ -391,7 +391,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) | |||
391 | 391 | ||
392 | while (msg_data_left(msg)) { | 392 | while (msg_data_left(msg)) { |
393 | if (sk->sk_err) { | 393 | if (sk->sk_err) { |
394 | ret = sk->sk_err; | 394 | ret = -sk->sk_err; |
395 | goto send_end; | 395 | goto send_end; |
396 | } | 396 | } |
397 | 397 | ||
@@ -544,7 +544,7 @@ int tls_sw_sendpage(struct sock *sk, struct page *page, | |||
544 | size_t copy, required_size; | 544 | size_t copy, required_size; |
545 | 545 | ||
546 | if (sk->sk_err) { | 546 | if (sk->sk_err) { |
547 | ret = sk->sk_err; | 547 | ret = -sk->sk_err; |
548 | goto sendpage_end; | 548 | goto sendpage_end; |
549 | } | 549 | } |
550 | 550 | ||
@@ -577,6 +577,8 @@ alloc_payload: | |||
577 | get_page(page); | 577 | get_page(page); |
578 | sg = ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem; | 578 | sg = ctx->sg_plaintext_data + ctx->sg_plaintext_num_elem; |
579 | sg_set_page(sg, page, copy, offset); | 579 | sg_set_page(sg, page, copy, offset); |
580 | sg_unmark_end(sg); | ||
581 | |||
580 | ctx->sg_plaintext_num_elem++; | 582 | ctx->sg_plaintext_num_elem++; |
581 | 583 | ||
582 | sk_mem_charge(sk, copy); | 584 | sk_mem_charge(sk, copy); |
@@ -681,18 +683,17 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx) | |||
681 | } | 683 | } |
682 | default: | 684 | default: |
683 | rc = -EINVAL; | 685 | rc = -EINVAL; |
684 | goto out; | 686 | goto free_priv; |
685 | } | 687 | } |
686 | 688 | ||
687 | ctx->prepend_size = TLS_HEADER_SIZE + nonce_size; | 689 | ctx->prepend_size = TLS_HEADER_SIZE + nonce_size; |
688 | ctx->tag_size = tag_size; | 690 | ctx->tag_size = tag_size; |
689 | ctx->overhead_size = ctx->prepend_size + ctx->tag_size; | 691 | ctx->overhead_size = ctx->prepend_size + ctx->tag_size; |
690 | ctx->iv_size = iv_size; | 692 | ctx->iv_size = iv_size; |
691 | ctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, | 693 | ctx->iv = kmalloc(iv_size + TLS_CIPHER_AES_GCM_128_SALT_SIZE, GFP_KERNEL); |
692 | GFP_KERNEL); | ||
693 | if (!ctx->iv) { | 694 | if (!ctx->iv) { |
694 | rc = -ENOMEM; | 695 | rc = -ENOMEM; |
695 | goto out; | 696 | goto free_priv; |
696 | } | 697 | } |
697 | memcpy(ctx->iv, gcm_128_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE); | 698 | memcpy(ctx->iv, gcm_128_info->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE); |
698 | memcpy(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size); | 699 | memcpy(ctx->iv + TLS_CIPHER_AES_GCM_128_SALT_SIZE, iv, iv_size); |
@@ -740,7 +741,7 @@ int tls_set_sw_offload(struct sock *sk, struct tls_context *ctx) | |||
740 | 741 | ||
741 | rc = crypto_aead_setauthsize(sw_ctx->aead_send, ctx->tag_size); | 742 | rc = crypto_aead_setauthsize(sw_ctx->aead_send, ctx->tag_size); |
742 | if (!rc) | 743 | if (!rc) |
743 | goto out; | 744 | return 0; |
744 | 745 | ||
745 | free_aead: | 746 | free_aead: |
746 | crypto_free_aead(sw_ctx->aead_send); | 747 | crypto_free_aead(sw_ctx->aead_send); |
@@ -751,6 +752,9 @@ free_rec_seq: | |||
751 | free_iv: | 752 | free_iv: |
752 | kfree(ctx->iv); | 753 | kfree(ctx->iv); |
753 | ctx->iv = NULL; | 754 | ctx->iv = NULL; |
755 | free_priv: | ||
756 | kfree(ctx->priv_ctx); | ||
757 | ctx->priv_ctx = NULL; | ||
754 | out: | 758 | out: |
755 | return rc; | 759 | return rc; |
756 | } | 760 | } |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5d28abf87fbf..c9473d698525 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -951,7 +951,7 @@ static unsigned int vsock_poll(struct file *file, struct socket *sock, | |||
951 | * POLLOUT|POLLWRNORM when peer is closed and nothing to read, | 951 | * POLLOUT|POLLWRNORM when peer is closed and nothing to read, |
952 | * but local send is not shutdown. | 952 | * but local send is not shutdown. |
953 | */ | 953 | */ |
954 | if (sk->sk_state == TCP_CLOSE) { | 954 | if (sk->sk_state == TCP_CLOSE || sk->sk_state == TCP_CLOSING) { |
955 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) | 955 | if (!(sk->sk_shutdown & SEND_SHUTDOWN)) |
956 | mask |= POLLOUT | POLLWRNORM; | 956 | mask |= POLLOUT | POLLWRNORM; |
957 | 957 | ||
diff --git a/net/wireless/Makefile b/net/wireless/Makefile index 278d979c211a..1d84f91bbfb0 100644 --- a/net/wireless/Makefile +++ b/net/wireless/Makefile | |||
@@ -23,19 +23,36 @@ ifneq ($(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR),) | |||
23 | cfg80211-y += extra-certs.o | 23 | cfg80211-y += extra-certs.o |
24 | endif | 24 | endif |
25 | 25 | ||
26 | $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.x509) | 26 | $(obj)/shipped-certs.c: $(wildcard $(srctree)/$(src)/certs/*.hex) |
27 | @$(kecho) " GEN $@" | 27 | @$(kecho) " GEN $@" |
28 | @echo '#include "reg.h"' > $@ | 28 | @(echo '#include "reg.h"'; \ |
29 | @echo 'const u8 shipped_regdb_certs[] = {' >> $@ | 29 | echo 'const u8 shipped_regdb_certs[] = {'; \ |
30 | @for f in $^ ; do hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ ; done | 30 | cat $^ ; \ |
31 | @echo '};' >> $@ | 31 | echo '};'; \ |
32 | @echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);' >> $@ | 32 | echo 'unsigned int shipped_regdb_certs_len = sizeof(shipped_regdb_certs);'; \ |
33 | ) > $@ | ||
33 | 34 | ||
34 | $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \ | 35 | $(obj)/extra-certs.c: $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%) \ |
35 | $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509) | 36 | $(wildcard $(CONFIG_CFG80211_EXTRA_REGDB_KEYDIR:"%"=%)/*.x509) |
36 | @$(kecho) " GEN $@" | 37 | @$(kecho) " GEN $@" |
37 | @echo '#include "reg.h"' > $@ | 38 | @(set -e; \ |
38 | @echo 'const u8 extra_regdb_certs[] = {' >> $@ | 39 | allf=""; \ |
39 | @for f in $^ ; do test -f $$f && hexdump -v -e '1/1 "0x%.2x," "\n"' < $$f >> $@ || true ; done | 40 | for f in $^ ; do \ |
40 | @echo '};' >> $@ | 41 | # similar to hexdump -v -e '1/1 "0x%.2x," "\n"' \ |
41 | @echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);' >> $@ | 42 | thisf=$$(od -An -v -tx1 < $$f | \ |
43 | sed -e 's/ /\n/g' | \ | ||
44 | sed -e 's/^[0-9a-f]\+$$/\0/;t;d' | \ | ||
45 | sed -e 's/^/0x/;s/$$/,/'); \ | ||
46 | # file should not be empty - maybe command substitution failed? \ | ||
47 | test ! -z "$$thisf";\ | ||
48 | allf=$$allf$$thisf;\ | ||
49 | done; \ | ||
50 | ( \ | ||
51 | echo '#include "reg.h"'; \ | ||
52 | echo 'const u8 extra_regdb_certs[] = {'; \ | ||
53 | echo "$$allf"; \ | ||
54 | echo '};'; \ | ||
55 | echo 'unsigned int extra_regdb_certs_len = sizeof(extra_regdb_certs);'; \ | ||
56 | ) > $@) | ||
57 | |||
58 | clean-files += shipped-certs.c extra-certs.c | ||
diff --git a/net/wireless/certs/sforshee.hex b/net/wireless/certs/sforshee.hex new file mode 100644 index 000000000000..14ea66643ffa --- /dev/null +++ b/net/wireless/certs/sforshee.hex | |||
@@ -0,0 +1,86 @@ | |||
1 | /* Seth Forshee's regdb certificate */ | ||
2 | 0x30, 0x82, 0x02, 0xa4, 0x30, 0x82, 0x01, 0x8c, | ||
3 | 0x02, 0x09, 0x00, 0xb2, 0x8d, 0xdf, 0x47, 0xae, | ||
4 | 0xf9, 0xce, 0xa7, 0x30, 0x0d, 0x06, 0x09, 0x2a, | ||
5 | 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, | ||
6 | 0x05, 0x00, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, | ||
7 | 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x73, | ||
8 | 0x66, 0x6f, 0x72, 0x73, 0x68, 0x65, 0x65, 0x30, | ||
9 | 0x20, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x30, 0x30, | ||
10 | 0x36, 0x31, 0x39, 0x34, 0x30, 0x33, 0x35, 0x5a, | ||
11 | 0x18, 0x0f, 0x32, 0x31, 0x31, 0x37, 0x30, 0x39, | ||
12 | 0x31, 0x32, 0x31, 0x39, 0x34, 0x30, 0x33, 0x35, | ||
13 | 0x5a, 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, | ||
14 | 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x73, 0x66, | ||
15 | 0x6f, 0x72, 0x73, 0x68, 0x65, 0x65, 0x30, 0x82, | ||
16 | 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, | ||
17 | 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, | ||
18 | 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, | ||
19 | 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb5, | ||
20 | 0x40, 0xe3, 0x9c, 0x28, 0x84, 0x39, 0x03, 0xf2, | ||
21 | 0x39, 0xd7, 0x66, 0x2c, 0x41, 0x38, 0x15, 0xac, | ||
22 | 0x7e, 0xa5, 0x83, 0x71, 0x25, 0x7e, 0x90, 0x7c, | ||
23 | 0x68, 0xdd, 0x6f, 0x3f, 0xd9, 0xd7, 0x59, 0x38, | ||
24 | 0x9f, 0x7c, 0x6a, 0x52, 0xc2, 0x03, 0x2a, 0x2d, | ||
25 | 0x7e, 0x66, 0xf4, 0x1e, 0xb3, 0x12, 0x70, 0x20, | ||
26 | 0x5b, 0xd4, 0x97, 0x32, 0x3d, 0x71, 0x8b, 0x3b, | ||
27 | 0x1b, 0x08, 0x17, 0x14, 0x6b, 0x61, 0xc4, 0x57, | ||
28 | 0x8b, 0x96, 0x16, 0x1c, 0xfd, 0x24, 0xd5, 0x0b, | ||
29 | 0x09, 0xf9, 0x68, 0x11, 0x84, 0xfb, 0xca, 0x51, | ||
30 | 0x0c, 0xd1, 0x45, 0x19, 0xda, 0x10, 0x44, 0x8a, | ||
31 | 0xd9, 0xfe, 0x76, 0xa9, 0xfd, 0x60, 0x2d, 0x18, | ||
32 | 0x0b, 0x28, 0x95, 0xb2, 0x2d, 0xea, 0x88, 0x98, | ||
33 | 0xb8, 0xd1, 0x56, 0x21, 0xf0, 0x53, 0x1f, 0xf1, | ||
34 | 0x02, 0x6f, 0xe9, 0x46, 0x9b, 0x93, 0x5f, 0x28, | ||
35 | 0x90, 0x0f, 0xac, 0x36, 0xfa, 0x68, 0x23, 0x71, | ||
36 | 0x57, 0x56, 0xf6, 0xcc, 0xd3, 0xdf, 0x7d, 0x2a, | ||
37 | 0xd9, 0x1b, 0x73, 0x45, 0xeb, 0xba, 0x27, 0x85, | ||
38 | 0xef, 0x7a, 0x7f, 0xa5, 0xcb, 0x80, 0xc7, 0x30, | ||
39 | 0x36, 0xd2, 0x53, 0xee, 0xec, 0xac, 0x1e, 0xe7, | ||
40 | 0x31, 0xf1, 0x36, 0xa2, 0x9c, 0x63, 0xc6, 0x65, | ||
41 | 0x5b, 0x7f, 0x25, 0x75, 0x68, 0xa1, 0xea, 0xd3, | ||
42 | 0x7e, 0x00, 0x5c, 0x9a, 0x5e, 0xd8, 0x20, 0x18, | ||
43 | 0x32, 0x77, 0x07, 0x29, 0x12, 0x66, 0x1e, 0x36, | ||
44 | 0x73, 0xe7, 0x97, 0x04, 0x41, 0x37, 0xb1, 0xb1, | ||
45 | 0x72, 0x2b, 0xf4, 0xa1, 0x29, 0x20, 0x7c, 0x96, | ||
46 | 0x79, 0x0b, 0x2b, 0xd0, 0xd8, 0xde, 0xc8, 0x6c, | ||
47 | 0x3f, 0x93, 0xfb, 0xc5, 0xee, 0x78, 0x52, 0x11, | ||
48 | 0x15, 0x1b, 0x7a, 0xf6, 0xe2, 0x68, 0x99, 0xe7, | ||
49 | 0xfb, 0x46, 0x16, 0x84, 0xe3, 0xc7, 0xa1, 0xe6, | ||
50 | 0xe0, 0xd2, 0x46, 0xd5, 0xe1, 0xc4, 0x5f, 0xa0, | ||
51 | 0x66, 0xf4, 0xda, 0xc4, 0xff, 0x95, 0x1d, 0x02, | ||
52 | 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 0x06, 0x09, | ||
53 | 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, | ||
54 | 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, | ||
55 | 0x87, 0x03, 0xda, 0xf2, 0x82, 0xc2, 0xdd, 0xaf, | ||
56 | 0x7c, 0x44, 0x2f, 0x86, 0xd3, 0x5f, 0x4c, 0x93, | ||
57 | 0x48, 0xb9, 0xfe, 0x07, 0x17, 0xbb, 0x21, 0xf7, | ||
58 | 0x25, 0x23, 0x4e, 0xaa, 0x22, 0x0c, 0x16, 0xb9, | ||
59 | 0x73, 0xae, 0x9d, 0x46, 0x7c, 0x75, 0xd9, 0xc3, | ||
60 | 0x49, 0x57, 0x47, 0xbf, 0x33, 0xb7, 0x97, 0xec, | ||
61 | 0xf5, 0x40, 0x75, 0xc0, 0x46, 0x22, 0xf0, 0xa0, | ||
62 | 0x5d, 0x9c, 0x79, 0x13, 0xa1, 0xff, 0xb8, 0xa3, | ||
63 | 0x2f, 0x7b, 0x8e, 0x06, 0x3f, 0xc8, 0xb6, 0xe4, | ||
64 | 0x6a, 0x28, 0xf2, 0x34, 0x5c, 0x23, 0x3f, 0x32, | ||
65 | 0xc0, 0xe6, 0xad, 0x0f, 0xac, 0xcf, 0x55, 0x74, | ||
66 | 0x47, 0x73, 0xd3, 0x01, 0x85, 0xb7, 0x0b, 0x22, | ||
67 | 0x56, 0x24, 0x7d, 0x9f, 0x09, 0xa9, 0x0e, 0x86, | ||
68 | 0x9e, 0x37, 0x5b, 0x9c, 0x6d, 0x02, 0xd9, 0x8c, | ||
69 | 0xc8, 0x50, 0x6a, 0xe2, 0x59, 0xf3, 0x16, 0x06, | ||
70 | 0xea, 0xb2, 0x42, 0xb5, 0x58, 0xfe, 0xba, 0xd1, | ||
71 | 0x81, 0x57, 0x1a, 0xef, 0xb2, 0x38, 0x88, 0x58, | ||
72 | 0xf6, 0xaa, 0xc4, 0x2e, 0x8b, 0x5a, 0x27, 0xe4, | ||
73 | 0xa5, 0xe8, 0xa4, 0xca, 0x67, 0x5c, 0xac, 0x72, | ||
74 | 0x67, 0xc3, 0x6f, 0x13, 0xc3, 0x2d, 0x35, 0x79, | ||
75 | 0xd7, 0x8a, 0xe7, 0xf5, 0xd4, 0x21, 0x30, 0x4a, | ||
76 | 0xd5, 0xf6, 0xa3, 0xd9, 0x79, 0x56, 0xf2, 0x0f, | ||
77 | 0x10, 0xf7, 0x7d, 0xd0, 0x51, 0x93, 0x2f, 0x47, | ||
78 | 0xf8, 0x7d, 0x4b, 0x0a, 0x84, 0x55, 0x12, 0x0a, | ||
79 | 0x7d, 0x4e, 0x3b, 0x1f, 0x2b, 0x2f, 0xfc, 0x28, | ||
80 | 0xb3, 0x69, 0x34, 0xe1, 0x80, 0x80, 0xbb, 0xe2, | ||
81 | 0xaf, 0xb9, 0xd6, 0x30, 0xf1, 0x1d, 0x54, 0x87, | ||
82 | 0x23, 0x99, 0x9f, 0x51, 0x03, 0x4c, 0x45, 0x7d, | ||
83 | 0x02, 0x65, 0x73, 0xab, 0xfd, 0xcf, 0x94, 0xcc, | ||
84 | 0x0d, 0x3a, 0x60, 0xfd, 0x3c, 0x14, 0x2f, 0x16, | ||
85 | 0x33, 0xa9, 0x21, 0x1f, 0xcb, 0x50, 0xb1, 0x8f, | ||
86 | 0x03, 0xee, 0xa0, 0x66, 0xa9, 0x16, 0x79, 0x14, | ||
diff --git a/net/wireless/certs/sforshee.x509 b/net/wireless/certs/sforshee.x509 deleted file mode 100644 index c6f8f9d6b988..000000000000 --- a/net/wireless/certs/sforshee.x509 +++ /dev/null | |||
Binary files differ | |||
diff --git a/net/wireless/core.c b/net/wireless/core.c index fdde0d98fde1..a6f3cac8c640 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -439,6 +439,8 @@ struct wiphy *wiphy_new_nm(const struct cfg80211_ops *ops, int sizeof_priv, | |||
439 | if (rv) | 439 | if (rv) |
440 | goto use_default_name; | 440 | goto use_default_name; |
441 | } else { | 441 | } else { |
442 | int rv; | ||
443 | |||
442 | use_default_name: | 444 | use_default_name: |
443 | /* NOTE: This is *probably* safe w/out holding rtnl because of | 445 | /* NOTE: This is *probably* safe w/out holding rtnl because of |
444 | * the restrictions on phy names. Probably this call could | 446 | * the restrictions on phy names. Probably this call could |
@@ -446,7 +448,11 @@ use_default_name: | |||
446 | * phyX. But, might should add some locking and check return | 448 | * phyX. But, might should add some locking and check return |
447 | * value, and use a different name if this one exists? | 449 | * value, and use a different name if this one exists? |
448 | */ | 450 | */ |
449 | dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); | 451 | rv = dev_set_name(&rdev->wiphy.dev, PHY_NAME "%d", rdev->wiphy_idx); |
452 | if (rv < 0) { | ||
453 | kfree(rdev); | ||
454 | return NULL; | ||
455 | } | ||
450 | } | 456 | } |
451 | 457 | ||
452 | INIT_LIST_HEAD(&rdev->wiphy.wdev_list); | 458 | INIT_LIST_HEAD(&rdev->wiphy.wdev_list); |
diff --git a/net/wireless/core.h b/net/wireless/core.h index d2f7e8b8a097..eaff636169c2 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -507,8 +507,6 @@ void cfg80211_stop_p2p_device(struct cfg80211_registered_device *rdev, | |||
507 | void cfg80211_stop_nan(struct cfg80211_registered_device *rdev, | 507 | void cfg80211_stop_nan(struct cfg80211_registered_device *rdev, |
508 | struct wireless_dev *wdev); | 508 | struct wireless_dev *wdev); |
509 | 509 | ||
510 | #define CFG80211_MAX_NUM_DIFFERENT_CHANNELS 10 | ||
511 | |||
512 | #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS | 510 | #ifdef CONFIG_CFG80211_DEVELOPER_WARNINGS |
513 | #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) | 511 | #define CFG80211_DEV_WARN_ON(cond) WARN_ON(cond) |
514 | #else | 512 | #else |
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index b1ac23ca20c8..542a4fc0a8d7 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2610,7 +2610,7 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2610 | case NL80211_IFTYPE_AP: | 2610 | case NL80211_IFTYPE_AP: |
2611 | if (wdev->ssid_len && | 2611 | if (wdev->ssid_len && |
2612 | nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) | 2612 | nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid)) |
2613 | goto nla_put_failure; | 2613 | goto nla_put_failure_locked; |
2614 | break; | 2614 | break; |
2615 | case NL80211_IFTYPE_STATION: | 2615 | case NL80211_IFTYPE_STATION: |
2616 | case NL80211_IFTYPE_P2P_CLIENT: | 2616 | case NL80211_IFTYPE_P2P_CLIENT: |
@@ -2618,12 +2618,13 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2618 | const u8 *ssid_ie; | 2618 | const u8 *ssid_ie; |
2619 | if (!wdev->current_bss) | 2619 | if (!wdev->current_bss) |
2620 | break; | 2620 | break; |
2621 | rcu_read_lock(); | ||
2621 | ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, | 2622 | ssid_ie = ieee80211_bss_get_ie(&wdev->current_bss->pub, |
2622 | WLAN_EID_SSID); | 2623 | WLAN_EID_SSID); |
2623 | if (!ssid_ie) | 2624 | if (ssid_ie && |
2624 | break; | 2625 | nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) |
2625 | if (nla_put(msg, NL80211_ATTR_SSID, ssid_ie[1], ssid_ie + 2)) | 2626 | goto nla_put_failure_rcu_locked; |
2626 | goto nla_put_failure; | 2627 | rcu_read_unlock(); |
2627 | break; | 2628 | break; |
2628 | } | 2629 | } |
2629 | default: | 2630 | default: |
@@ -2635,6 +2636,10 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
2635 | genlmsg_end(msg, hdr); | 2636 | genlmsg_end(msg, hdr); |
2636 | return 0; | 2637 | return 0; |
2637 | 2638 | ||
2639 | nla_put_failure_rcu_locked: | ||
2640 | rcu_read_unlock(); | ||
2641 | nla_put_failure_locked: | ||
2642 | wdev_unlock(wdev); | ||
2638 | nla_put_failure: | 2643 | nla_put_failure: |
2639 | genlmsg_cancel(msg, hdr); | 2644 | genlmsg_cancel(msg, hdr); |
2640 | return -EMSGSIZE; | 2645 | return -EMSGSIZE; |
@@ -9804,7 +9809,7 @@ static int cfg80211_cqm_rssi_update(struct cfg80211_registered_device *rdev, | |||
9804 | */ | 9809 | */ |
9805 | if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss && | 9810 | if (!wdev->cqm_config->last_rssi_event_value && wdev->current_bss && |
9806 | rdev->ops->get_station) { | 9811 | rdev->ops->get_station) { |
9807 | struct station_info sinfo; | 9812 | struct station_info sinfo = {}; |
9808 | u8 *mac_addr; | 9813 | u8 *mac_addr; |
9809 | 9814 | ||
9810 | mac_addr = wdev->current_bss->pub.bssid; | 9815 | mac_addr = wdev->current_bss->pub.bssid; |
@@ -11359,7 +11364,8 @@ static int nl80211_nan_add_func(struct sk_buff *skb, | |||
11359 | break; | 11364 | break; |
11360 | case NL80211_NAN_FUNC_FOLLOW_UP: | 11365 | case NL80211_NAN_FUNC_FOLLOW_UP: |
11361 | if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] || | 11366 | if (!tb[NL80211_NAN_FUNC_FOLLOW_UP_ID] || |
11362 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID]) { | 11367 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_REQ_ID] || |
11368 | !tb[NL80211_NAN_FUNC_FOLLOW_UP_DEST]) { | ||
11363 | err = -EINVAL; | 11369 | err = -EINVAL; |
11364 | goto out; | 11370 | goto out; |
11365 | } | 11371 | } |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 78e71b0390be..7b42f0bacfd8 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
@@ -1769,8 +1769,7 @@ static void handle_reg_beacon(struct wiphy *wiphy, unsigned int chan_idx, | |||
1769 | if (wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS) | 1769 | if (wiphy->regulatory_flags & REGULATORY_DISABLE_BEACON_HINTS) |
1770 | return; | 1770 | return; |
1771 | 1771 | ||
1772 | chan_before.center_freq = chan->center_freq; | 1772 | chan_before = *chan; |
1773 | chan_before.flags = chan->flags; | ||
1774 | 1773 | ||
1775 | if (chan->flags & IEEE80211_CHAN_NO_IR) { | 1774 | if (chan->flags & IEEE80211_CHAN_NO_IR) { |
1776 | chan->flags &= ~IEEE80211_CHAN_NO_IR; | 1775 | chan->flags &= ~IEEE80211_CHAN_NO_IR; |
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 7ca04a7de85a..05186a47878f 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -1254,8 +1254,7 @@ static int cfg80211_wext_giwrate(struct net_device *dev, | |||
1254 | { | 1254 | { |
1255 | struct wireless_dev *wdev = dev->ieee80211_ptr; | 1255 | struct wireless_dev *wdev = dev->ieee80211_ptr; |
1256 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); | 1256 | struct cfg80211_registered_device *rdev = wiphy_to_rdev(wdev->wiphy); |
1257 | /* we are under RTNL - globally locked - so can use a static struct */ | 1257 | struct station_info sinfo = {}; |
1258 | static struct station_info sinfo; | ||
1259 | u8 addr[ETH_ALEN]; | 1258 | u8 addr[ETH_ALEN]; |
1260 | int err; | 1259 | int err; |
1261 | 1260 | ||
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 30e5746085b8..ac9477189d1c 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c | |||
@@ -102,6 +102,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, | |||
102 | 102 | ||
103 | err = dev->xfrmdev_ops->xdo_dev_state_add(x); | 103 | err = dev->xfrmdev_ops->xdo_dev_state_add(x); |
104 | if (err) { | 104 | if (err) { |
105 | xso->dev = NULL; | ||
105 | dev_put(dev); | 106 | dev_put(dev); |
106 | return err; | 107 | return err; |
107 | } | 108 | } |
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index 347ab31574d5..5b2409746ae0 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c | |||
@@ -8,15 +8,29 @@ | |||
8 | * | 8 | * |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #include <linux/bottom_half.h> | ||
12 | #include <linux/interrupt.h> | ||
11 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
12 | #include <linux/module.h> | 14 | #include <linux/module.h> |
13 | #include <linux/netdevice.h> | 15 | #include <linux/netdevice.h> |
16 | #include <linux/percpu.h> | ||
14 | #include <net/dst.h> | 17 | #include <net/dst.h> |
15 | #include <net/ip.h> | 18 | #include <net/ip.h> |
16 | #include <net/xfrm.h> | 19 | #include <net/xfrm.h> |
17 | #include <net/ip_tunnels.h> | 20 | #include <net/ip_tunnels.h> |
18 | #include <net/ip6_tunnel.h> | 21 | #include <net/ip6_tunnel.h> |
19 | 22 | ||
23 | struct xfrm_trans_tasklet { | ||
24 | struct tasklet_struct tasklet; | ||
25 | struct sk_buff_head queue; | ||
26 | }; | ||
27 | |||
28 | struct xfrm_trans_cb { | ||
29 | int (*finish)(struct net *net, struct sock *sk, struct sk_buff *skb); | ||
30 | }; | ||
31 | |||
32 | #define XFRM_TRANS_SKB_CB(__skb) ((struct xfrm_trans_cb *)&((__skb)->cb[0])) | ||
33 | |||
20 | static struct kmem_cache *secpath_cachep __read_mostly; | 34 | static struct kmem_cache *secpath_cachep __read_mostly; |
21 | 35 | ||
22 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); | 36 | static DEFINE_SPINLOCK(xfrm_input_afinfo_lock); |
@@ -25,6 +39,8 @@ static struct xfrm_input_afinfo const __rcu *xfrm_input_afinfo[AF_INET6 + 1]; | |||
25 | static struct gro_cells gro_cells; | 39 | static struct gro_cells gro_cells; |
26 | static struct net_device xfrm_napi_dev; | 40 | static struct net_device xfrm_napi_dev; |
27 | 41 | ||
42 | static DEFINE_PER_CPU(struct xfrm_trans_tasklet, xfrm_trans_tasklet); | ||
43 | |||
28 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) | 44 | int xfrm_input_register_afinfo(const struct xfrm_input_afinfo *afinfo) |
29 | { | 45 | { |
30 | int err = 0; | 46 | int err = 0; |
@@ -207,7 +223,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
207 | xfrm_address_t *daddr; | 223 | xfrm_address_t *daddr; |
208 | struct xfrm_mode *inner_mode; | 224 | struct xfrm_mode *inner_mode; |
209 | u32 mark = skb->mark; | 225 | u32 mark = skb->mark; |
210 | unsigned int family; | 226 | unsigned int family = AF_UNSPEC; |
211 | int decaps = 0; | 227 | int decaps = 0; |
212 | int async = 0; | 228 | int async = 0; |
213 | bool xfrm_gro = false; | 229 | bool xfrm_gro = false; |
@@ -216,6 +232,16 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) | |||
216 | 232 | ||
217 | if (encap_type < 0) { | 233 | if (encap_type < 0) { |
218 | x = xfrm_input_state(skb); | 234 | x = xfrm_input_state(skb); |
235 | |||
236 | if (unlikely(x->km.state != XFRM_STATE_VALID)) { | ||
237 | if (x->km.state == XFRM_STATE_ACQ) | ||
238 | XFRM_INC_STATS(net, LINUX_MIB_XFRMACQUIREERROR); | ||
239 | else | ||
240 | XFRM_INC_STATS(net, | ||
241 | LINUX_MIB_XFRMINSTATEINVALID); | ||
242 | goto drop; | ||
243 | } | ||
244 | |||
219 | family = x->outer_mode->afinfo->family; | 245 | family = x->outer_mode->afinfo->family; |
220 | 246 | ||
221 | /* An encap_type of -1 indicates async resumption. */ | 247 | /* An encap_type of -1 indicates async resumption. */ |
@@ -467,9 +493,41 @@ int xfrm_input_resume(struct sk_buff *skb, int nexthdr) | |||
467 | } | 493 | } |
468 | EXPORT_SYMBOL(xfrm_input_resume); | 494 | EXPORT_SYMBOL(xfrm_input_resume); |
469 | 495 | ||
496 | static void xfrm_trans_reinject(unsigned long data) | ||
497 | { | ||
498 | struct xfrm_trans_tasklet *trans = (void *)data; | ||
499 | struct sk_buff_head queue; | ||
500 | struct sk_buff *skb; | ||
501 | |||
502 | __skb_queue_head_init(&queue); | ||
503 | skb_queue_splice_init(&trans->queue, &queue); | ||
504 | |||
505 | while ((skb = __skb_dequeue(&queue))) | ||
506 | XFRM_TRANS_SKB_CB(skb)->finish(dev_net(skb->dev), NULL, skb); | ||
507 | } | ||
508 | |||
509 | int xfrm_trans_queue(struct sk_buff *skb, | ||
510 | int (*finish)(struct net *, struct sock *, | ||
511 | struct sk_buff *)) | ||
512 | { | ||
513 | struct xfrm_trans_tasklet *trans; | ||
514 | |||
515 | trans = this_cpu_ptr(&xfrm_trans_tasklet); | ||
516 | |||
517 | if (skb_queue_len(&trans->queue) >= netdev_max_backlog) | ||
518 | return -ENOBUFS; | ||
519 | |||
520 | XFRM_TRANS_SKB_CB(skb)->finish = finish; | ||
521 | __skb_queue_tail(&trans->queue, skb); | ||
522 | tasklet_schedule(&trans->tasklet); | ||
523 | return 0; | ||
524 | } | ||
525 | EXPORT_SYMBOL(xfrm_trans_queue); | ||
526 | |||
470 | void __init xfrm_input_init(void) | 527 | void __init xfrm_input_init(void) |
471 | { | 528 | { |
472 | int err; | 529 | int err; |
530 | int i; | ||
473 | 531 | ||
474 | init_dummy_netdev(&xfrm_napi_dev); | 532 | init_dummy_netdev(&xfrm_napi_dev); |
475 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); | 533 | err = gro_cells_init(&gro_cells, &xfrm_napi_dev); |
@@ -480,4 +538,13 @@ void __init xfrm_input_init(void) | |||
480 | sizeof(struct sec_path), | 538 | sizeof(struct sec_path), |
481 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, | 539 | 0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, |
482 | NULL); | 540 | NULL); |
541 | |||
542 | for_each_possible_cpu(i) { | ||
543 | struct xfrm_trans_tasklet *trans; | ||
544 | |||
545 | trans = &per_cpu(xfrm_trans_tasklet, i); | ||
546 | __skb_queue_head_init(&trans->queue); | ||
547 | tasklet_init(&trans->tasklet, xfrm_trans_reinject, | ||
548 | (unsigned long)trans); | ||
549 | } | ||
483 | } | 550 | } |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 9542975eb2f9..bd6b0e7a0ee4 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -609,7 +609,8 @@ static void xfrm_hash_rebuild(struct work_struct *work) | |||
609 | 609 | ||
610 | /* re-insert all policies by order of creation */ | 610 | /* re-insert all policies by order of creation */ |
611 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { | 611 | list_for_each_entry_reverse(policy, &net->xfrm.policy_all, walk.all) { |
612 | if (xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) { | 612 | if (policy->walk.dead || |
613 | xfrm_policy_id2dir(policy->index) >= XFRM_POLICY_MAX) { | ||
613 | /* skip socket policies */ | 614 | /* skip socket policies */ |
614 | continue; | 615 | continue; |
615 | } | 616 | } |
@@ -974,8 +975,6 @@ int xfrm_policy_flush(struct net *net, u8 type, bool task_valid) | |||
974 | } | 975 | } |
975 | if (!cnt) | 976 | if (!cnt) |
976 | err = -ESRCH; | 977 | err = -ESRCH; |
977 | else | ||
978 | xfrm_policy_cache_flush(); | ||
979 | out: | 978 | out: |
980 | spin_unlock_bh(&net->xfrm.xfrm_policy_lock); | 979 | spin_unlock_bh(&net->xfrm.xfrm_policy_lock); |
981 | return err; | 980 | return err; |
@@ -1168,9 +1167,15 @@ static struct xfrm_policy *xfrm_sk_policy_lookup(const struct sock *sk, int dir, | |||
1168 | again: | 1167 | again: |
1169 | pol = rcu_dereference(sk->sk_policy[dir]); | 1168 | pol = rcu_dereference(sk->sk_policy[dir]); |
1170 | if (pol != NULL) { | 1169 | if (pol != NULL) { |
1171 | bool match = xfrm_selector_match(&pol->selector, fl, family); | 1170 | bool match; |
1172 | int err = 0; | 1171 | int err = 0; |
1173 | 1172 | ||
1173 | if (pol->family != family) { | ||
1174 | pol = NULL; | ||
1175 | goto out; | ||
1176 | } | ||
1177 | |||
1178 | match = xfrm_selector_match(&pol->selector, fl, family); | ||
1174 | if (match) { | 1179 | if (match) { |
1175 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { | 1180 | if ((sk->sk_mark & pol->mark.m) != pol->mark.v) { |
1176 | pol = NULL; | 1181 | pol = NULL; |
@@ -1737,6 +1742,8 @@ void xfrm_policy_cache_flush(void) | |||
1737 | bool found = 0; | 1742 | bool found = 0; |
1738 | int cpu; | 1743 | int cpu; |
1739 | 1744 | ||
1745 | might_sleep(); | ||
1746 | |||
1740 | local_bh_disable(); | 1747 | local_bh_disable(); |
1741 | rcu_read_lock(); | 1748 | rcu_read_lock(); |
1742 | for_each_possible_cpu(cpu) { | 1749 | for_each_possible_cpu(cpu) { |
@@ -1833,6 +1840,7 @@ xfrm_resolve_and_create_bundle(struct xfrm_policy **pols, int num_pols, | |||
1833 | sizeof(struct xfrm_policy *) * num_pols) == 0 && | 1840 | sizeof(struct xfrm_policy *) * num_pols) == 0 && |
1834 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { | 1841 | xfrm_xdst_can_reuse(xdst, xfrm, err)) { |
1835 | dst_hold(&xdst->u.dst); | 1842 | dst_hold(&xdst->u.dst); |
1843 | xfrm_pols_put(pols, num_pols); | ||
1836 | while (err > 0) | 1844 | while (err > 0) |
1837 | xfrm_state_put(xfrm[--err]); | 1845 | xfrm_state_put(xfrm[--err]); |
1838 | return xdst; | 1846 | return xdst; |
@@ -2055,8 +2063,11 @@ xfrm_bundle_lookup(struct net *net, const struct flowi *fl, u16 family, u8 dir, | |||
2055 | if (num_xfrms <= 0) | 2063 | if (num_xfrms <= 0) |
2056 | goto make_dummy_bundle; | 2064 | goto make_dummy_bundle; |
2057 | 2065 | ||
2066 | local_bh_disable(); | ||
2058 | xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, | 2067 | xdst = xfrm_resolve_and_create_bundle(pols, num_pols, fl, family, |
2059 | xflo->dst_orig); | 2068 | xflo->dst_orig); |
2069 | local_bh_enable(); | ||
2070 | |||
2060 | if (IS_ERR(xdst)) { | 2071 | if (IS_ERR(xdst)) { |
2061 | err = PTR_ERR(xdst); | 2072 | err = PTR_ERR(xdst); |
2062 | if (err != -EAGAIN) | 2073 | if (err != -EAGAIN) |
@@ -2143,9 +2154,12 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, | |||
2143 | goto no_transform; | 2154 | goto no_transform; |
2144 | } | 2155 | } |
2145 | 2156 | ||
2157 | local_bh_disable(); | ||
2146 | xdst = xfrm_resolve_and_create_bundle( | 2158 | xdst = xfrm_resolve_and_create_bundle( |
2147 | pols, num_pols, fl, | 2159 | pols, num_pols, fl, |
2148 | family, dst_orig); | 2160 | family, dst_orig); |
2161 | local_bh_enable(); | ||
2162 | |||
2149 | if (IS_ERR(xdst)) { | 2163 | if (IS_ERR(xdst)) { |
2150 | xfrm_pols_put(pols, num_pols); | 2164 | xfrm_pols_put(pols, num_pols); |
2151 | err = PTR_ERR(xdst); | 2165 | err = PTR_ERR(xdst); |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 065d89606888..a3785f538018 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
@@ -313,13 +313,14 @@ retry: | |||
313 | if ((type && !try_module_get(type->owner))) | 313 | if ((type && !try_module_get(type->owner))) |
314 | type = NULL; | 314 | type = NULL; |
315 | 315 | ||
316 | rcu_read_unlock(); | ||
317 | |||
316 | if (!type && try_load) { | 318 | if (!type && try_load) { |
317 | request_module("xfrm-offload-%d-%d", family, proto); | 319 | request_module("xfrm-offload-%d-%d", family, proto); |
318 | try_load = 0; | 320 | try_load = false; |
319 | goto retry; | 321 | goto retry; |
320 | } | 322 | } |
321 | 323 | ||
322 | rcu_read_unlock(); | ||
323 | return type; | 324 | return type; |
324 | } | 325 | } |
325 | 326 | ||
@@ -1343,6 +1344,7 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, | |||
1343 | 1344 | ||
1344 | if (orig->aead) { | 1345 | if (orig->aead) { |
1345 | x->aead = xfrm_algo_aead_clone(orig->aead); | 1346 | x->aead = xfrm_algo_aead_clone(orig->aead); |
1347 | x->geniv = orig->geniv; | ||
1346 | if (!x->aead) | 1348 | if (!x->aead) |
1347 | goto error; | 1349 | goto error; |
1348 | } | 1350 | } |
@@ -1533,8 +1535,12 @@ out: | |||
1533 | err = -EINVAL; | 1535 | err = -EINVAL; |
1534 | spin_lock_bh(&x1->lock); | 1536 | spin_lock_bh(&x1->lock); |
1535 | if (likely(x1->km.state == XFRM_STATE_VALID)) { | 1537 | if (likely(x1->km.state == XFRM_STATE_VALID)) { |
1536 | if (x->encap && x1->encap) | 1538 | if (x->encap && x1->encap && |
1539 | x->encap->encap_type == x1->encap->encap_type) | ||
1537 | memcpy(x1->encap, x->encap, sizeof(*x1->encap)); | 1540 | memcpy(x1->encap, x->encap, sizeof(*x1->encap)); |
1541 | else if (x->encap || x1->encap) | ||
1542 | goto fail; | ||
1543 | |||
1538 | if (x->coaddr && x1->coaddr) { | 1544 | if (x->coaddr && x1->coaddr) { |
1539 | memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr)); | 1545 | memcpy(x1->coaddr, x->coaddr, sizeof(*x1->coaddr)); |
1540 | } | 1546 | } |
@@ -1551,6 +1557,8 @@ out: | |||
1551 | x->km.state = XFRM_STATE_DEAD; | 1557 | x->km.state = XFRM_STATE_DEAD; |
1552 | __xfrm_state_put(x); | 1558 | __xfrm_state_put(x); |
1553 | } | 1559 | } |
1560 | |||
1561 | fail: | ||
1554 | spin_unlock_bh(&x1->lock); | 1562 | spin_unlock_bh(&x1->lock); |
1555 | 1563 | ||
1556 | xfrm_state_put(x1); | 1564 | xfrm_state_put(x1); |
@@ -2264,8 +2272,6 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload) | |||
2264 | goto error; | 2272 | goto error; |
2265 | } | 2273 | } |
2266 | 2274 | ||
2267 | x->km.state = XFRM_STATE_VALID; | ||
2268 | |||
2269 | error: | 2275 | error: |
2270 | return err; | 2276 | return err; |
2271 | } | 2277 | } |
@@ -2274,7 +2280,13 @@ EXPORT_SYMBOL(__xfrm_init_state); | |||
2274 | 2280 | ||
2275 | int xfrm_init_state(struct xfrm_state *x) | 2281 | int xfrm_init_state(struct xfrm_state *x) |
2276 | { | 2282 | { |
2277 | return __xfrm_init_state(x, true, false); | 2283 | int err; |
2284 | |||
2285 | err = __xfrm_init_state(x, true, false); | ||
2286 | if (!err) | ||
2287 | x->km.state = XFRM_STATE_VALID; | ||
2288 | |||
2289 | return err; | ||
2278 | } | 2290 | } |
2279 | 2291 | ||
2280 | EXPORT_SYMBOL(xfrm_init_state); | 2292 | EXPORT_SYMBOL(xfrm_init_state); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 983b0233767b..7f52b8eb177d 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -598,13 +598,6 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
598 | goto error; | 598 | goto error; |
599 | } | 599 | } |
600 | 600 | ||
601 | if (attrs[XFRMA_OFFLOAD_DEV]) { | ||
602 | err = xfrm_dev_state_add(net, x, | ||
603 | nla_data(attrs[XFRMA_OFFLOAD_DEV])); | ||
604 | if (err) | ||
605 | goto error; | ||
606 | } | ||
607 | |||
608 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, | 601 | if ((err = xfrm_alloc_replay_state_esn(&x->replay_esn, &x->preplay_esn, |
609 | attrs[XFRMA_REPLAY_ESN_VAL]))) | 602 | attrs[XFRMA_REPLAY_ESN_VAL]))) |
610 | goto error; | 603 | goto error; |
@@ -620,6 +613,14 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, | |||
620 | /* override default values from above */ | 613 | /* override default values from above */ |
621 | xfrm_update_ae_params(x, attrs, 0); | 614 | xfrm_update_ae_params(x, attrs, 0); |
622 | 615 | ||
616 | /* configure the hardware if offload is requested */ | ||
617 | if (attrs[XFRMA_OFFLOAD_DEV]) { | ||
618 | err = xfrm_dev_state_add(net, x, | ||
619 | nla_data(attrs[XFRMA_OFFLOAD_DEV])); | ||
620 | if (err) | ||
621 | goto error; | ||
622 | } | ||
623 | |||
623 | return x; | 624 | return x; |
624 | 625 | ||
625 | error: | 626 | error: |
@@ -662,6 +663,9 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
662 | goto out; | 663 | goto out; |
663 | } | 664 | } |
664 | 665 | ||
666 | if (x->km.state == XFRM_STATE_VOID) | ||
667 | x->km.state = XFRM_STATE_VALID; | ||
668 | |||
665 | c.seq = nlh->nlmsg_seq; | 669 | c.seq = nlh->nlmsg_seq; |
666 | c.portid = nlh->nlmsg_pid; | 670 | c.portid = nlh->nlmsg_pid; |
667 | c.event = nlh->nlmsg_type; | 671 | c.event = nlh->nlmsg_type; |
@@ -1419,11 +1423,14 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut, | |||
1419 | 1423 | ||
1420 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | 1424 | static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) |
1421 | { | 1425 | { |
1426 | u16 prev_family; | ||
1422 | int i; | 1427 | int i; |
1423 | 1428 | ||
1424 | if (nr > XFRM_MAX_DEPTH) | 1429 | if (nr > XFRM_MAX_DEPTH) |
1425 | return -EINVAL; | 1430 | return -EINVAL; |
1426 | 1431 | ||
1432 | prev_family = family; | ||
1433 | |||
1427 | for (i = 0; i < nr; i++) { | 1434 | for (i = 0; i < nr; i++) { |
1428 | /* We never validated the ut->family value, so many | 1435 | /* We never validated the ut->family value, so many |
1429 | * applications simply leave it at zero. The check was | 1436 | * applications simply leave it at zero. The check was |
@@ -1435,6 +1442,12 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1435 | if (!ut[i].family) | 1442 | if (!ut[i].family) |
1436 | ut[i].family = family; | 1443 | ut[i].family = family; |
1437 | 1444 | ||
1445 | if ((ut[i].mode == XFRM_MODE_TRANSPORT) && | ||
1446 | (ut[i].family != prev_family)) | ||
1447 | return -EINVAL; | ||
1448 | |||
1449 | prev_family = ut[i].family; | ||
1450 | |||
1438 | switch (ut[i].family) { | 1451 | switch (ut[i].family) { |
1439 | case AF_INET: | 1452 | case AF_INET: |
1440 | break; | 1453 | break; |
@@ -1445,6 +1458,21 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
1445 | default: | 1458 | default: |
1446 | return -EINVAL; | 1459 | return -EINVAL; |
1447 | } | 1460 | } |
1461 | |||
1462 | switch (ut[i].id.proto) { | ||
1463 | case IPPROTO_AH: | ||
1464 | case IPPROTO_ESP: | ||
1465 | case IPPROTO_COMP: | ||
1466 | #if IS_ENABLED(CONFIG_IPV6) | ||
1467 | case IPPROTO_ROUTING: | ||
1468 | case IPPROTO_DSTOPTS: | ||
1469 | #endif | ||
1470 | case IPSEC_PROTO_ANY: | ||
1471 | break; | ||
1472 | default: | ||
1473 | return -EINVAL; | ||
1474 | } | ||
1475 | |||
1448 | } | 1476 | } |
1449 | 1477 | ||
1450 | return 0; | 1478 | return 0; |
@@ -2470,7 +2498,7 @@ static const struct nla_policy xfrma_policy[XFRMA_MAX+1] = { | |||
2470 | [XFRMA_PROTO] = { .type = NLA_U8 }, | 2498 | [XFRMA_PROTO] = { .type = NLA_U8 }, |
2471 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, | 2499 | [XFRMA_ADDRESS_FILTER] = { .len = sizeof(struct xfrm_address_filter) }, |
2472 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, | 2500 | [XFRMA_OFFLOAD_DEV] = { .len = sizeof(struct xfrm_user_offload) }, |
2473 | [XFRMA_OUTPUT_MARK] = { .len = NLA_U32 }, | 2501 | [XFRMA_OUTPUT_MARK] = { .type = NLA_U32 }, |
2474 | }; | 2502 | }; |
2475 | 2503 | ||
2476 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { | 2504 | static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = { |