diff options
Diffstat (limited to 'net')
52 files changed, 460 insertions, 234 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 8eb75425e6e6..addc116cecf0 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -562,36 +562,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | |||
562 | 562 | ||
563 | if (!p9_is_proto_dotl(c)) { | 563 | if (!p9_is_proto_dotl(c)) { |
564 | /* Error is reported in string format */ | 564 | /* Error is reported in string format */ |
565 | uint16_t len; | 565 | int len; |
566 | /* 7 = header size for RERROR, 2 is the size of string len; */ | 566 | /* 7 = header size for RERROR; */ |
567 | int inline_len = in_hdrlen - (7 + 2); | 567 | int inline_len = in_hdrlen - 7; |
568 | 568 | ||
569 | /* Read the size of error string */ | 569 | len = req->rc->size - req->rc->offset; |
570 | err = p9pdu_readf(req->rc, c->proto_version, "w", &len); | 570 | if (len > (P9_ZC_HDR_SZ - 7)) { |
571 | if (err) | 571 | err = -EFAULT; |
572 | goto out_err; | ||
573 | |||
574 | ename = kmalloc(len + 1, GFP_NOFS); | ||
575 | if (!ename) { | ||
576 | err = -ENOMEM; | ||
577 | goto out_err; | 572 | goto out_err; |
578 | } | 573 | } |
579 | if (len <= inline_len) { | ||
580 | /* We have error in protocol buffer itself */ | ||
581 | if (pdu_read(req->rc, ename, len)) { | ||
582 | err = -EFAULT; | ||
583 | goto out_free; | ||
584 | 574 | ||
585 | } | 575 | ename = &req->rc->sdata[req->rc->offset]; |
586 | } else { | 576 | if (len > inline_len) { |
587 | /* | 577 | /* We have error in external buffer */ |
588 | * Part of the data is in user space buffer. | ||
589 | */ | ||
590 | if (pdu_read(req->rc, ename, inline_len)) { | ||
591 | err = -EFAULT; | ||
592 | goto out_free; | ||
593 | |||
594 | } | ||
595 | if (kern_buf) { | 578 | if (kern_buf) { |
596 | memcpy(ename + inline_len, uidata, | 579 | memcpy(ename + inline_len, uidata, |
597 | len - inline_len); | 580 | len - inline_len); |
@@ -600,19 +583,19 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | |||
600 | uidata, len - inline_len); | 583 | uidata, len - inline_len); |
601 | if (err) { | 584 | if (err) { |
602 | err = -EFAULT; | 585 | err = -EFAULT; |
603 | goto out_free; | 586 | goto out_err; |
604 | } | 587 | } |
605 | } | 588 | } |
606 | } | 589 | } |
607 | ename[len] = 0; | 590 | ename = NULL; |
608 | if (p9_is_proto_dotu(c)) { | 591 | err = p9pdu_readf(req->rc, c->proto_version, "s?d", |
609 | /* For dotu we also have error code */ | 592 | &ename, &ecode); |
610 | err = p9pdu_readf(req->rc, | 593 | if (err) |
611 | c->proto_version, "d", &ecode); | 594 | goto out_err; |
612 | if (err) | 595 | |
613 | goto out_free; | 596 | if (p9_is_proto_dotu(c)) |
614 | err = -ecode; | 597 | err = -ecode; |
615 | } | 598 | |
616 | if (!err || !IS_ERR_VALUE(err)) { | 599 | if (!err || !IS_ERR_VALUE(err)) { |
617 | err = p9_errstr2errno(ename, strlen(ename)); | 600 | err = p9_errstr2errno(ename, strlen(ename)); |
618 | 601 | ||
@@ -628,8 +611,6 @@ static int p9_check_zc_errors(struct p9_client *c, struct p9_req_t *req, | |||
628 | } | 611 | } |
629 | return err; | 612 | return err; |
630 | 613 | ||
631 | out_free: | ||
632 | kfree(ename); | ||
633 | out_err: | 614 | out_err: |
634 | p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err); | 615 | p9_debug(P9_DEBUG_ERROR, "couldn't parse error%d\n", err); |
635 | return err; | 616 | return err; |
diff --git a/net/batman-adv/bat_iv_ogm.c b/net/batman-adv/bat_iv_ogm.c index 071f288b77a8..f680ee101878 100644 --- a/net/batman-adv/bat_iv_ogm.c +++ b/net/batman-adv/bat_iv_ogm.c | |||
@@ -29,6 +29,21 @@ | |||
29 | #include "bat_algo.h" | 29 | #include "bat_algo.h" |
30 | #include "network-coding.h" | 30 | #include "network-coding.h" |
31 | 31 | ||
32 | /** | ||
33 | * batadv_dup_status - duplicate status | ||
34 | * @BATADV_NO_DUP: the packet is a duplicate | ||
35 | * @BATADV_ORIG_DUP: OGM is a duplicate in the originator (but not for the | ||
36 | * neighbor) | ||
37 | * @BATADV_NEIGH_DUP: OGM is a duplicate for the neighbor | ||
38 | * @BATADV_PROTECTED: originator is currently protected (after reboot) | ||
39 | */ | ||
40 | enum batadv_dup_status { | ||
41 | BATADV_NO_DUP = 0, | ||
42 | BATADV_ORIG_DUP, | ||
43 | BATADV_NEIGH_DUP, | ||
44 | BATADV_PROTECTED, | ||
45 | }; | ||
46 | |||
32 | static struct batadv_neigh_node * | 47 | static struct batadv_neigh_node * |
33 | batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, | 48 | batadv_iv_ogm_neigh_new(struct batadv_hard_iface *hard_iface, |
34 | const uint8_t *neigh_addr, | 49 | const uint8_t *neigh_addr, |
@@ -650,7 +665,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
650 | const struct batadv_ogm_packet *batadv_ogm_packet, | 665 | const struct batadv_ogm_packet *batadv_ogm_packet, |
651 | struct batadv_hard_iface *if_incoming, | 666 | struct batadv_hard_iface *if_incoming, |
652 | const unsigned char *tt_buff, | 667 | const unsigned char *tt_buff, |
653 | int is_duplicate) | 668 | enum batadv_dup_status dup_status) |
654 | { | 669 | { |
655 | struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; | 670 | struct batadv_neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; |
656 | struct batadv_neigh_node *router = NULL; | 671 | struct batadv_neigh_node *router = NULL; |
@@ -676,7 +691,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
676 | continue; | 691 | continue; |
677 | } | 692 | } |
678 | 693 | ||
679 | if (is_duplicate) | 694 | if (dup_status != BATADV_NO_DUP) |
680 | continue; | 695 | continue; |
681 | 696 | ||
682 | spin_lock_bh(&tmp_neigh_node->lq_update_lock); | 697 | spin_lock_bh(&tmp_neigh_node->lq_update_lock); |
@@ -718,7 +733,7 @@ batadv_iv_ogm_orig_update(struct batadv_priv *bat_priv, | |||
718 | neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); | 733 | neigh_node->tq_avg = batadv_ring_buffer_avg(neigh_node->tq_recv); |
719 | spin_unlock_bh(&neigh_node->lq_update_lock); | 734 | spin_unlock_bh(&neigh_node->lq_update_lock); |
720 | 735 | ||
721 | if (!is_duplicate) { | 736 | if (dup_status == BATADV_NO_DUP) { |
722 | orig_node->last_ttl = batadv_ogm_packet->header.ttl; | 737 | orig_node->last_ttl = batadv_ogm_packet->header.ttl; |
723 | neigh_node->last_ttl = batadv_ogm_packet->header.ttl; | 738 | neigh_node->last_ttl = batadv_ogm_packet->header.ttl; |
724 | } | 739 | } |
@@ -902,15 +917,16 @@ out: | |||
902 | return ret; | 917 | return ret; |
903 | } | 918 | } |
904 | 919 | ||
905 | /* processes a batman packet for all interfaces, adjusts the sequence number and | 920 | /** |
906 | * finds out whether it is a duplicate. | 921 | * batadv_iv_ogm_update_seqnos - process a batman packet for all interfaces, |
907 | * returns: | 922 | * adjust the sequence number and find out whether it is a duplicate |
908 | * 1 the packet is a duplicate | 923 | * @ethhdr: ethernet header of the packet |
909 | * 0 the packet has not yet been received | 924 | * @batadv_ogm_packet: OGM packet to be considered |
910 | * -1 the packet is old and has been received while the seqno window | 925 | * @if_incoming: interface on which the OGM packet was received |
911 | * was protected. Caller should drop it. | 926 | * |
927 | * Returns duplicate status as enum batadv_dup_status | ||
912 | */ | 928 | */ |
913 | static int | 929 | static enum batadv_dup_status |
914 | batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | 930 | batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, |
915 | const struct batadv_ogm_packet *batadv_ogm_packet, | 931 | const struct batadv_ogm_packet *batadv_ogm_packet, |
916 | const struct batadv_hard_iface *if_incoming) | 932 | const struct batadv_hard_iface *if_incoming) |
@@ -918,17 +934,18 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
918 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); | 934 | struct batadv_priv *bat_priv = netdev_priv(if_incoming->soft_iface); |
919 | struct batadv_orig_node *orig_node; | 935 | struct batadv_orig_node *orig_node; |
920 | struct batadv_neigh_node *tmp_neigh_node; | 936 | struct batadv_neigh_node *tmp_neigh_node; |
921 | int is_duplicate = 0; | 937 | int is_dup; |
922 | int32_t seq_diff; | 938 | int32_t seq_diff; |
923 | int need_update = 0; | 939 | int need_update = 0; |
924 | int set_mark, ret = -1; | 940 | int set_mark; |
941 | enum batadv_dup_status ret = BATADV_NO_DUP; | ||
925 | uint32_t seqno = ntohl(batadv_ogm_packet->seqno); | 942 | uint32_t seqno = ntohl(batadv_ogm_packet->seqno); |
926 | uint8_t *neigh_addr; | 943 | uint8_t *neigh_addr; |
927 | uint8_t packet_count; | 944 | uint8_t packet_count; |
928 | 945 | ||
929 | orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); | 946 | orig_node = batadv_get_orig_node(bat_priv, batadv_ogm_packet->orig); |
930 | if (!orig_node) | 947 | if (!orig_node) |
931 | return 0; | 948 | return BATADV_NO_DUP; |
932 | 949 | ||
933 | spin_lock_bh(&orig_node->ogm_cnt_lock); | 950 | spin_lock_bh(&orig_node->ogm_cnt_lock); |
934 | seq_diff = seqno - orig_node->last_real_seqno; | 951 | seq_diff = seqno - orig_node->last_real_seqno; |
@@ -936,22 +953,29 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
936 | /* signalize caller that the packet is to be dropped. */ | 953 | /* signalize caller that the packet is to be dropped. */ |
937 | if (!hlist_empty(&orig_node->neigh_list) && | 954 | if (!hlist_empty(&orig_node->neigh_list) && |
938 | batadv_window_protected(bat_priv, seq_diff, | 955 | batadv_window_protected(bat_priv, seq_diff, |
939 | &orig_node->batman_seqno_reset)) | 956 | &orig_node->batman_seqno_reset)) { |
957 | ret = BATADV_PROTECTED; | ||
940 | goto out; | 958 | goto out; |
959 | } | ||
941 | 960 | ||
942 | rcu_read_lock(); | 961 | rcu_read_lock(); |
943 | hlist_for_each_entry_rcu(tmp_neigh_node, | 962 | hlist_for_each_entry_rcu(tmp_neigh_node, |
944 | &orig_node->neigh_list, list) { | 963 | &orig_node->neigh_list, list) { |
945 | is_duplicate |= batadv_test_bit(tmp_neigh_node->real_bits, | ||
946 | orig_node->last_real_seqno, | ||
947 | seqno); | ||
948 | |||
949 | neigh_addr = tmp_neigh_node->addr; | 964 | neigh_addr = tmp_neigh_node->addr; |
965 | is_dup = batadv_test_bit(tmp_neigh_node->real_bits, | ||
966 | orig_node->last_real_seqno, | ||
967 | seqno); | ||
968 | |||
950 | if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && | 969 | if (batadv_compare_eth(neigh_addr, ethhdr->h_source) && |
951 | tmp_neigh_node->if_incoming == if_incoming) | 970 | tmp_neigh_node->if_incoming == if_incoming) { |
952 | set_mark = 1; | 971 | set_mark = 1; |
953 | else | 972 | if (is_dup) |
973 | ret = BATADV_NEIGH_DUP; | ||
974 | } else { | ||
954 | set_mark = 0; | 975 | set_mark = 0; |
976 | if (is_dup && (ret != BATADV_NEIGH_DUP)) | ||
977 | ret = BATADV_ORIG_DUP; | ||
978 | } | ||
955 | 979 | ||
956 | /* if the window moved, set the update flag. */ | 980 | /* if the window moved, set the update flag. */ |
957 | need_update |= batadv_bit_get_packet(bat_priv, | 981 | need_update |= batadv_bit_get_packet(bat_priv, |
@@ -971,8 +995,6 @@ batadv_iv_ogm_update_seqnos(const struct ethhdr *ethhdr, | |||
971 | orig_node->last_real_seqno = seqno; | 995 | orig_node->last_real_seqno = seqno; |
972 | } | 996 | } |
973 | 997 | ||
974 | ret = is_duplicate; | ||
975 | |||
976 | out: | 998 | out: |
977 | spin_unlock_bh(&orig_node->ogm_cnt_lock); | 999 | spin_unlock_bh(&orig_node->ogm_cnt_lock); |
978 | batadv_orig_node_free_ref(orig_node); | 1000 | batadv_orig_node_free_ref(orig_node); |
@@ -994,7 +1016,8 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
994 | int is_broadcast = 0, is_bidirect; | 1016 | int is_broadcast = 0, is_bidirect; |
995 | bool is_single_hop_neigh = false; | 1017 | bool is_single_hop_neigh = false; |
996 | bool is_from_best_next_hop = false; | 1018 | bool is_from_best_next_hop = false; |
997 | int is_duplicate, sameseq, simlar_ttl; | 1019 | int sameseq, similar_ttl; |
1020 | enum batadv_dup_status dup_status; | ||
998 | uint32_t if_incoming_seqno; | 1021 | uint32_t if_incoming_seqno; |
999 | uint8_t *prev_sender; | 1022 | uint8_t *prev_sender; |
1000 | 1023 | ||
@@ -1138,10 +1161,10 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1138 | if (!orig_node) | 1161 | if (!orig_node) |
1139 | return; | 1162 | return; |
1140 | 1163 | ||
1141 | is_duplicate = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet, | 1164 | dup_status = batadv_iv_ogm_update_seqnos(ethhdr, batadv_ogm_packet, |
1142 | if_incoming); | 1165 | if_incoming); |
1143 | 1166 | ||
1144 | if (is_duplicate == -1) { | 1167 | if (dup_status == BATADV_PROTECTED) { |
1145 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 1168 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
1146 | "Drop packet: packet within seqno protection time (sender: %pM)\n", | 1169 | "Drop packet: packet within seqno protection time (sender: %pM)\n", |
1147 | ethhdr->h_source); | 1170 | ethhdr->h_source); |
@@ -1211,11 +1234,12 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1211 | * seqno and similar ttl as the non-duplicate | 1234 | * seqno and similar ttl as the non-duplicate |
1212 | */ | 1235 | */ |
1213 | sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); | 1236 | sameseq = orig_node->last_real_seqno == ntohl(batadv_ogm_packet->seqno); |
1214 | simlar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; | 1237 | similar_ttl = orig_node->last_ttl - 3 <= batadv_ogm_packet->header.ttl; |
1215 | if (is_bidirect && (!is_duplicate || (sameseq && simlar_ttl))) | 1238 | if (is_bidirect && ((dup_status == BATADV_NO_DUP) || |
1239 | (sameseq && similar_ttl))) | ||
1216 | batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, | 1240 | batadv_iv_ogm_orig_update(bat_priv, orig_node, ethhdr, |
1217 | batadv_ogm_packet, if_incoming, | 1241 | batadv_ogm_packet, if_incoming, |
1218 | tt_buff, is_duplicate); | 1242 | tt_buff, dup_status); |
1219 | 1243 | ||
1220 | /* is single hop (direct) neighbor */ | 1244 | /* is single hop (direct) neighbor */ |
1221 | if (is_single_hop_neigh) { | 1245 | if (is_single_hop_neigh) { |
@@ -1236,7 +1260,7 @@ static void batadv_iv_ogm_process(const struct ethhdr *ethhdr, | |||
1236 | goto out_neigh; | 1260 | goto out_neigh; |
1237 | } | 1261 | } |
1238 | 1262 | ||
1239 | if (is_duplicate) { | 1263 | if (dup_status == BATADV_NEIGH_DUP) { |
1240 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, | 1264 | batadv_dbg(BATADV_DBG_BATMAN, bat_priv, |
1241 | "Drop packet: duplicate packet received\n"); | 1265 | "Drop packet: duplicate packet received\n"); |
1242 | goto out_neigh; | 1266 | goto out_neigh; |
diff --git a/net/batman-adv/bridge_loop_avoidance.c b/net/batman-adv/bridge_loop_avoidance.c index 379061c72549..de27b3175cfd 100644 --- a/net/batman-adv/bridge_loop_avoidance.c +++ b/net/batman-adv/bridge_loop_avoidance.c | |||
@@ -1067,6 +1067,10 @@ void batadv_bla_update_orig_address(struct batadv_priv *bat_priv, | |||
1067 | group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); | 1067 | group = htons(crc16(0, primary_if->net_dev->dev_addr, ETH_ALEN)); |
1068 | bat_priv->bla.claim_dest.group = group; | 1068 | bat_priv->bla.claim_dest.group = group; |
1069 | 1069 | ||
1070 | /* purge everything when bridge loop avoidance is turned off */ | ||
1071 | if (!atomic_read(&bat_priv->bridge_loop_avoidance)) | ||
1072 | oldif = NULL; | ||
1073 | |||
1070 | if (!oldif) { | 1074 | if (!oldif) { |
1071 | batadv_bla_purge_claims(bat_priv, NULL, 1); | 1075 | batadv_bla_purge_claims(bat_priv, NULL, 1); |
1072 | batadv_bla_purge_backbone_gw(bat_priv, 1); | 1076 | batadv_bla_purge_backbone_gw(bat_priv, 1); |
diff --git a/net/batman-adv/sysfs.c b/net/batman-adv/sysfs.c index 15a22efa9a67..929e304dacb2 100644 --- a/net/batman-adv/sysfs.c +++ b/net/batman-adv/sysfs.c | |||
@@ -582,10 +582,7 @@ static ssize_t batadv_store_mesh_iface(struct kobject *kobj, | |||
582 | (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) | 582 | (strncmp(hard_iface->soft_iface->name, buff, IFNAMSIZ) == 0)) |
583 | goto out; | 583 | goto out; |
584 | 584 | ||
585 | if (!rtnl_trylock()) { | 585 | rtnl_lock(); |
586 | ret = -ERESTARTSYS; | ||
587 | goto out; | ||
588 | } | ||
589 | 586 | ||
590 | if (status_tmp == BATADV_IF_NOT_IN_USE) { | 587 | if (status_tmp == BATADV_IF_NOT_IN_USE) { |
591 | batadv_hardif_disable_interface(hard_iface, | 588 | batadv_hardif_disable_interface(hard_iface, |
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 33843c5c4939..d817c932d634 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -1555,11 +1555,15 @@ static const struct rfkill_ops hci_rfkill_ops = { | |||
1555 | static void hci_power_on(struct work_struct *work) | 1555 | static void hci_power_on(struct work_struct *work) |
1556 | { | 1556 | { |
1557 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); | 1557 | struct hci_dev *hdev = container_of(work, struct hci_dev, power_on); |
1558 | int err; | ||
1558 | 1559 | ||
1559 | BT_DBG("%s", hdev->name); | 1560 | BT_DBG("%s", hdev->name); |
1560 | 1561 | ||
1561 | if (hci_dev_open(hdev->id) < 0) | 1562 | err = hci_dev_open(hdev->id); |
1563 | if (err < 0) { | ||
1564 | mgmt_set_powered_failed(hdev, err); | ||
1562 | return; | 1565 | return; |
1566 | } | ||
1563 | 1567 | ||
1564 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) | 1568 | if (test_bit(HCI_AUTO_OFF, &hdev->dev_flags)) |
1565 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, | 1569 | queue_delayed_work(hdev->req_workqueue, &hdev->power_off, |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index a76d1ac0321b..24bee07ee4ce 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -3677,10 +3677,14 @@ static void l2cap_conf_rfc_get(struct l2cap_chan *chan, void *rsp, int len) | |||
3677 | } | 3677 | } |
3678 | 3678 | ||
3679 | static inline int l2cap_command_rej(struct l2cap_conn *conn, | 3679 | static inline int l2cap_command_rej(struct l2cap_conn *conn, |
3680 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3680 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
3681 | u8 *data) | ||
3681 | { | 3682 | { |
3682 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; | 3683 | struct l2cap_cmd_rej_unk *rej = (struct l2cap_cmd_rej_unk *) data; |
3683 | 3684 | ||
3685 | if (cmd_len < sizeof(*rej)) | ||
3686 | return -EPROTO; | ||
3687 | |||
3684 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) | 3688 | if (rej->reason != L2CAP_REJ_NOT_UNDERSTOOD) |
3685 | return 0; | 3689 | return 0; |
3686 | 3690 | ||
@@ -3829,11 +3833,14 @@ sendresp: | |||
3829 | } | 3833 | } |
3830 | 3834 | ||
3831 | static int l2cap_connect_req(struct l2cap_conn *conn, | 3835 | static int l2cap_connect_req(struct l2cap_conn *conn, |
3832 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3836 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, u8 *data) |
3833 | { | 3837 | { |
3834 | struct hci_dev *hdev = conn->hcon->hdev; | 3838 | struct hci_dev *hdev = conn->hcon->hdev; |
3835 | struct hci_conn *hcon = conn->hcon; | 3839 | struct hci_conn *hcon = conn->hcon; |
3836 | 3840 | ||
3841 | if (cmd_len < sizeof(struct l2cap_conn_req)) | ||
3842 | return -EPROTO; | ||
3843 | |||
3837 | hci_dev_lock(hdev); | 3844 | hci_dev_lock(hdev); |
3838 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && | 3845 | if (test_bit(HCI_MGMT, &hdev->dev_flags) && |
3839 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) | 3846 | !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &hcon->flags)) |
@@ -3847,7 +3854,8 @@ static int l2cap_connect_req(struct l2cap_conn *conn, | |||
3847 | } | 3854 | } |
3848 | 3855 | ||
3849 | static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | 3856 | static int l2cap_connect_create_rsp(struct l2cap_conn *conn, |
3850 | struct l2cap_cmd_hdr *cmd, u8 *data) | 3857 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
3858 | u8 *data) | ||
3851 | { | 3859 | { |
3852 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; | 3860 | struct l2cap_conn_rsp *rsp = (struct l2cap_conn_rsp *) data; |
3853 | u16 scid, dcid, result, status; | 3861 | u16 scid, dcid, result, status; |
@@ -3855,6 +3863,9 @@ static int l2cap_connect_create_rsp(struct l2cap_conn *conn, | |||
3855 | u8 req[128]; | 3863 | u8 req[128]; |
3856 | int err; | 3864 | int err; |
3857 | 3865 | ||
3866 | if (cmd_len < sizeof(*rsp)) | ||
3867 | return -EPROTO; | ||
3868 | |||
3858 | scid = __le16_to_cpu(rsp->scid); | 3869 | scid = __le16_to_cpu(rsp->scid); |
3859 | dcid = __le16_to_cpu(rsp->dcid); | 3870 | dcid = __le16_to_cpu(rsp->dcid); |
3860 | result = __le16_to_cpu(rsp->result); | 3871 | result = __le16_to_cpu(rsp->result); |
@@ -3952,6 +3963,9 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
3952 | struct l2cap_chan *chan; | 3963 | struct l2cap_chan *chan; |
3953 | int len, err = 0; | 3964 | int len, err = 0; |
3954 | 3965 | ||
3966 | if (cmd_len < sizeof(*req)) | ||
3967 | return -EPROTO; | ||
3968 | |||
3955 | dcid = __le16_to_cpu(req->dcid); | 3969 | dcid = __le16_to_cpu(req->dcid); |
3956 | flags = __le16_to_cpu(req->flags); | 3970 | flags = __le16_to_cpu(req->flags); |
3957 | 3971 | ||
@@ -3975,7 +3989,7 @@ static inline int l2cap_config_req(struct l2cap_conn *conn, | |||
3975 | 3989 | ||
3976 | /* Reject if config buffer is too small. */ | 3990 | /* Reject if config buffer is too small. */ |
3977 | len = cmd_len - sizeof(*req); | 3991 | len = cmd_len - sizeof(*req); |
3978 | if (len < 0 || chan->conf_len + len > sizeof(chan->conf_req)) { | 3992 | if (chan->conf_len + len > sizeof(chan->conf_req)) { |
3979 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, | 3993 | l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, |
3980 | l2cap_build_conf_rsp(chan, rsp, | 3994 | l2cap_build_conf_rsp(chan, rsp, |
3981 | L2CAP_CONF_REJECT, flags), rsp); | 3995 | L2CAP_CONF_REJECT, flags), rsp); |
@@ -4053,14 +4067,18 @@ unlock: | |||
4053 | } | 4067 | } |
4054 | 4068 | ||
4055 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, | 4069 | static inline int l2cap_config_rsp(struct l2cap_conn *conn, |
4056 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4070 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4071 | u8 *data) | ||
4057 | { | 4072 | { |
4058 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; | 4073 | struct l2cap_conf_rsp *rsp = (struct l2cap_conf_rsp *)data; |
4059 | u16 scid, flags, result; | 4074 | u16 scid, flags, result; |
4060 | struct l2cap_chan *chan; | 4075 | struct l2cap_chan *chan; |
4061 | int len = le16_to_cpu(cmd->len) - sizeof(*rsp); | 4076 | int len = cmd_len - sizeof(*rsp); |
4062 | int err = 0; | 4077 | int err = 0; |
4063 | 4078 | ||
4079 | if (cmd_len < sizeof(*rsp)) | ||
4080 | return -EPROTO; | ||
4081 | |||
4064 | scid = __le16_to_cpu(rsp->scid); | 4082 | scid = __le16_to_cpu(rsp->scid); |
4065 | flags = __le16_to_cpu(rsp->flags); | 4083 | flags = __le16_to_cpu(rsp->flags); |
4066 | result = __le16_to_cpu(rsp->result); | 4084 | result = __le16_to_cpu(rsp->result); |
@@ -4161,7 +4179,8 @@ done: | |||
4161 | } | 4179 | } |
4162 | 4180 | ||
4163 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | 4181 | static inline int l2cap_disconnect_req(struct l2cap_conn *conn, |
4164 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4182 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4183 | u8 *data) | ||
4165 | { | 4184 | { |
4166 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; | 4185 | struct l2cap_disconn_req *req = (struct l2cap_disconn_req *) data; |
4167 | struct l2cap_disconn_rsp rsp; | 4186 | struct l2cap_disconn_rsp rsp; |
@@ -4169,6 +4188,9 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4169 | struct l2cap_chan *chan; | 4188 | struct l2cap_chan *chan; |
4170 | struct sock *sk; | 4189 | struct sock *sk; |
4171 | 4190 | ||
4191 | if (cmd_len != sizeof(*req)) | ||
4192 | return -EPROTO; | ||
4193 | |||
4172 | scid = __le16_to_cpu(req->scid); | 4194 | scid = __le16_to_cpu(req->scid); |
4173 | dcid = __le16_to_cpu(req->dcid); | 4195 | dcid = __le16_to_cpu(req->dcid); |
4174 | 4196 | ||
@@ -4208,12 +4230,16 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn, | |||
4208 | } | 4230 | } |
4209 | 4231 | ||
4210 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | 4232 | static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, |
4211 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4233 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4234 | u8 *data) | ||
4212 | { | 4235 | { |
4213 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; | 4236 | struct l2cap_disconn_rsp *rsp = (struct l2cap_disconn_rsp *) data; |
4214 | u16 dcid, scid; | 4237 | u16 dcid, scid; |
4215 | struct l2cap_chan *chan; | 4238 | struct l2cap_chan *chan; |
4216 | 4239 | ||
4240 | if (cmd_len != sizeof(*rsp)) | ||
4241 | return -EPROTO; | ||
4242 | |||
4217 | scid = __le16_to_cpu(rsp->scid); | 4243 | scid = __le16_to_cpu(rsp->scid); |
4218 | dcid = __le16_to_cpu(rsp->dcid); | 4244 | dcid = __le16_to_cpu(rsp->dcid); |
4219 | 4245 | ||
@@ -4243,11 +4269,15 @@ static inline int l2cap_disconnect_rsp(struct l2cap_conn *conn, | |||
4243 | } | 4269 | } |
4244 | 4270 | ||
4245 | static inline int l2cap_information_req(struct l2cap_conn *conn, | 4271 | static inline int l2cap_information_req(struct l2cap_conn *conn, |
4246 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4272 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4273 | u8 *data) | ||
4247 | { | 4274 | { |
4248 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; | 4275 | struct l2cap_info_req *req = (struct l2cap_info_req *) data; |
4249 | u16 type; | 4276 | u16 type; |
4250 | 4277 | ||
4278 | if (cmd_len != sizeof(*req)) | ||
4279 | return -EPROTO; | ||
4280 | |||
4251 | type = __le16_to_cpu(req->type); | 4281 | type = __le16_to_cpu(req->type); |
4252 | 4282 | ||
4253 | BT_DBG("type 0x%4.4x", type); | 4283 | BT_DBG("type 0x%4.4x", type); |
@@ -4294,11 +4324,15 @@ static inline int l2cap_information_req(struct l2cap_conn *conn, | |||
4294 | } | 4324 | } |
4295 | 4325 | ||
4296 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, | 4326 | static inline int l2cap_information_rsp(struct l2cap_conn *conn, |
4297 | struct l2cap_cmd_hdr *cmd, u8 *data) | 4327 | struct l2cap_cmd_hdr *cmd, u16 cmd_len, |
4328 | u8 *data) | ||
4298 | { | 4329 | { |
4299 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; | 4330 | struct l2cap_info_rsp *rsp = (struct l2cap_info_rsp *) data; |
4300 | u16 type, result; | 4331 | u16 type, result; |
4301 | 4332 | ||
4333 | if (cmd_len != sizeof(*rsp)) | ||
4334 | return -EPROTO; | ||
4335 | |||
4302 | type = __le16_to_cpu(rsp->type); | 4336 | type = __le16_to_cpu(rsp->type); |
4303 | result = __le16_to_cpu(rsp->result); | 4337 | result = __le16_to_cpu(rsp->result); |
4304 | 4338 | ||
@@ -5164,16 +5198,16 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5164 | 5198 | ||
5165 | switch (cmd->code) { | 5199 | switch (cmd->code) { |
5166 | case L2CAP_COMMAND_REJ: | 5200 | case L2CAP_COMMAND_REJ: |
5167 | l2cap_command_rej(conn, cmd, data); | 5201 | l2cap_command_rej(conn, cmd, cmd_len, data); |
5168 | break; | 5202 | break; |
5169 | 5203 | ||
5170 | case L2CAP_CONN_REQ: | 5204 | case L2CAP_CONN_REQ: |
5171 | err = l2cap_connect_req(conn, cmd, data); | 5205 | err = l2cap_connect_req(conn, cmd, cmd_len, data); |
5172 | break; | 5206 | break; |
5173 | 5207 | ||
5174 | case L2CAP_CONN_RSP: | 5208 | case L2CAP_CONN_RSP: |
5175 | case L2CAP_CREATE_CHAN_RSP: | 5209 | case L2CAP_CREATE_CHAN_RSP: |
5176 | err = l2cap_connect_create_rsp(conn, cmd, data); | 5210 | err = l2cap_connect_create_rsp(conn, cmd, cmd_len, data); |
5177 | break; | 5211 | break; |
5178 | 5212 | ||
5179 | case L2CAP_CONF_REQ: | 5213 | case L2CAP_CONF_REQ: |
@@ -5181,15 +5215,15 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5181 | break; | 5215 | break; |
5182 | 5216 | ||
5183 | case L2CAP_CONF_RSP: | 5217 | case L2CAP_CONF_RSP: |
5184 | err = l2cap_config_rsp(conn, cmd, data); | 5218 | err = l2cap_config_rsp(conn, cmd, cmd_len, data); |
5185 | break; | 5219 | break; |
5186 | 5220 | ||
5187 | case L2CAP_DISCONN_REQ: | 5221 | case L2CAP_DISCONN_REQ: |
5188 | err = l2cap_disconnect_req(conn, cmd, data); | 5222 | err = l2cap_disconnect_req(conn, cmd, cmd_len, data); |
5189 | break; | 5223 | break; |
5190 | 5224 | ||
5191 | case L2CAP_DISCONN_RSP: | 5225 | case L2CAP_DISCONN_RSP: |
5192 | err = l2cap_disconnect_rsp(conn, cmd, data); | 5226 | err = l2cap_disconnect_rsp(conn, cmd, cmd_len, data); |
5193 | break; | 5227 | break; |
5194 | 5228 | ||
5195 | case L2CAP_ECHO_REQ: | 5229 | case L2CAP_ECHO_REQ: |
@@ -5200,11 +5234,11 @@ static inline int l2cap_bredr_sig_cmd(struct l2cap_conn *conn, | |||
5200 | break; | 5234 | break; |
5201 | 5235 | ||
5202 | case L2CAP_INFO_REQ: | 5236 | case L2CAP_INFO_REQ: |
5203 | err = l2cap_information_req(conn, cmd, data); | 5237 | err = l2cap_information_req(conn, cmd, cmd_len, data); |
5204 | break; | 5238 | break; |
5205 | 5239 | ||
5206 | case L2CAP_INFO_RSP: | 5240 | case L2CAP_INFO_RSP: |
5207 | err = l2cap_information_rsp(conn, cmd, data); | 5241 | err = l2cap_information_rsp(conn, cmd, cmd_len, data); |
5208 | break; | 5242 | break; |
5209 | 5243 | ||
5210 | case L2CAP_CREATE_CHAN_REQ: | 5244 | case L2CAP_CREATE_CHAN_REQ: |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 35fef22703e9..f8ecbc70293d 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -2700,7 +2700,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2700 | break; | 2700 | break; |
2701 | 2701 | ||
2702 | case DISCOV_TYPE_LE: | 2702 | case DISCOV_TYPE_LE: |
2703 | if (!lmp_host_le_capable(hdev)) { | 2703 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2705 | MGMT_STATUS_NOT_SUPPORTED); | 2705 | MGMT_STATUS_NOT_SUPPORTED); |
2706 | mgmt_pending_remove(cmd); | 2706 | mgmt_pending_remove(cmd); |
@@ -3418,6 +3418,27 @@ new_settings: | |||
3418 | return err; | 3418 | return err; |
3419 | } | 3419 | } |
3420 | 3420 | ||
3421 | int mgmt_set_powered_failed(struct hci_dev *hdev, int err) | ||
3422 | { | ||
3423 | struct pending_cmd *cmd; | ||
3424 | u8 status; | ||
3425 | |||
3426 | cmd = mgmt_pending_find(MGMT_OP_SET_POWERED, hdev); | ||
3427 | if (!cmd) | ||
3428 | return -ENOENT; | ||
3429 | |||
3430 | if (err == -ERFKILL) | ||
3431 | status = MGMT_STATUS_RFKILLED; | ||
3432 | else | ||
3433 | status = MGMT_STATUS_FAILED; | ||
3434 | |||
3435 | err = cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_POWERED, status); | ||
3436 | |||
3437 | mgmt_pending_remove(cmd); | ||
3438 | |||
3439 | return err; | ||
3440 | } | ||
3441 | |||
3421 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) | 3442 | int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable) |
3422 | { | 3443 | { |
3423 | struct cmd_lookup match = { NULL, hdev }; | 3444 | struct cmd_lookup match = { NULL, hdev }; |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index b2296d3857a0..b5562abdd6e0 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -770,7 +770,7 @@ int smp_conn_security(struct hci_conn *hcon, __u8 sec_level) | |||
770 | 770 | ||
771 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); | 771 | BT_DBG("conn %p hcon %p level 0x%2.2x", conn, hcon, sec_level); |
772 | 772 | ||
773 | if (!lmp_host_le_capable(hcon->hdev)) | 773 | if (!test_bit(HCI_LE_ENABLED, &hcon->hdev->dev_flags)) |
774 | return 1; | 774 | return 1; |
775 | 775 | ||
776 | if (sec_level == BT_SECURITY_LOW) | 776 | if (sec_level == BT_SECURITY_LOW) |
@@ -851,7 +851,7 @@ int smp_sig_channel(struct l2cap_conn *conn, struct sk_buff *skb) | |||
851 | __u8 reason; | 851 | __u8 reason; |
852 | int err = 0; | 852 | int err = 0; |
853 | 853 | ||
854 | if (!lmp_host_le_capable(conn->hcon->hdev)) { | 854 | if (!test_bit(HCI_LE_ENABLED, &conn->hcon->hdev->dev_flags)) { |
855 | err = -ENOTSUPP; | 855 | err = -ENOTSUPP; |
856 | reason = SMP_PAIRING_NOTSUPP; | 856 | reason = SMP_PAIRING_NOTSUPP; |
857 | goto done; | 857 | goto done; |
diff --git a/net/ceph/osd_client.c b/net/ceph/osd_client.c index d5953b87918c..3a246a6cab47 100644 --- a/net/ceph/osd_client.c +++ b/net/ceph/osd_client.c | |||
@@ -1675,13 +1675,13 @@ static void kick_requests(struct ceph_osd_client *osdc, int force_resend) | |||
1675 | __register_request(osdc, req); | 1675 | __register_request(osdc, req); |
1676 | __unregister_linger_request(osdc, req); | 1676 | __unregister_linger_request(osdc, req); |
1677 | } | 1677 | } |
1678 | reset_changed_osds(osdc); | ||
1678 | mutex_unlock(&osdc->request_mutex); | 1679 | mutex_unlock(&osdc->request_mutex); |
1679 | 1680 | ||
1680 | if (needmap) { | 1681 | if (needmap) { |
1681 | dout("%d requests for down osds, need new map\n", needmap); | 1682 | dout("%d requests for down osds, need new map\n", needmap); |
1682 | ceph_monc_request_next_osdmap(&osdc->client->monc); | 1683 | ceph_monc_request_next_osdmap(&osdc->client->monc); |
1683 | } | 1684 | } |
1684 | reset_changed_osds(osdc); | ||
1685 | } | 1685 | } |
1686 | 1686 | ||
1687 | 1687 | ||
diff --git a/net/compat.c b/net/compat.c index 79ae88485001..f0a1ba6c8086 100644 --- a/net/compat.c +++ b/net/compat.c | |||
@@ -734,19 +734,25 @@ static unsigned char nas[21] = { | |||
734 | 734 | ||
735 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) | 735 | asmlinkage long compat_sys_sendmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
736 | { | 736 | { |
737 | return sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 737 | if (flags & MSG_CMSG_COMPAT) |
738 | return -EINVAL; | ||
739 | return __sys_sendmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | ||
738 | } | 740 | } |
739 | 741 | ||
740 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, | 742 | asmlinkage long compat_sys_sendmmsg(int fd, struct compat_mmsghdr __user *mmsg, |
741 | unsigned int vlen, unsigned int flags) | 743 | unsigned int vlen, unsigned int flags) |
742 | { | 744 | { |
745 | if (flags & MSG_CMSG_COMPAT) | ||
746 | return -EINVAL; | ||
743 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, | 747 | return __sys_sendmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
744 | flags | MSG_CMSG_COMPAT); | 748 | flags | MSG_CMSG_COMPAT); |
745 | } | 749 | } |
746 | 750 | ||
747 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) | 751 | asmlinkage long compat_sys_recvmsg(int fd, struct compat_msghdr __user *msg, unsigned int flags) |
748 | { | 752 | { |
749 | return sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | 753 | if (flags & MSG_CMSG_COMPAT) |
754 | return -EINVAL; | ||
755 | return __sys_recvmsg(fd, (struct msghdr __user *)msg, flags | MSG_CMSG_COMPAT); | ||
750 | } | 756 | } |
751 | 757 | ||
752 | asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) | 758 | asmlinkage long compat_sys_recv(int fd, void __user *buf, size_t len, unsigned int flags) |
@@ -768,6 +774,9 @@ asmlinkage long compat_sys_recvmmsg(int fd, struct compat_mmsghdr __user *mmsg, | |||
768 | int datagrams; | 774 | int datagrams; |
769 | struct timespec ktspec; | 775 | struct timespec ktspec; |
770 | 776 | ||
777 | if (flags & MSG_CMSG_COMPAT) | ||
778 | return -EINVAL; | ||
779 | |||
771 | if (COMPAT_USE_64BIT_TIME) | 780 | if (COMPAT_USE_64BIT_TIME) |
772 | return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, | 781 | return __sys_recvmmsg(fd, (struct mmsghdr __user *)mmsg, vlen, |
773 | flags | MSG_CMSG_COMPAT, | 782 | flags | MSG_CMSG_COMPAT, |
diff --git a/net/core/dev_addr_lists.c b/net/core/dev_addr_lists.c index c013f38482a1..6cda4e2c2132 100644 --- a/net/core/dev_addr_lists.c +++ b/net/core/dev_addr_lists.c | |||
@@ -39,6 +39,7 @@ static int __hw_addr_create_ex(struct netdev_hw_addr_list *list, | |||
39 | ha->refcount = 1; | 39 | ha->refcount = 1; |
40 | ha->global_use = global; | 40 | ha->global_use = global; |
41 | ha->synced = sync; | 41 | ha->synced = sync; |
42 | ha->sync_cnt = 0; | ||
42 | list_add_tail_rcu(&ha->list, &list->list); | 43 | list_add_tail_rcu(&ha->list, &list->list); |
43 | list->count++; | 44 | list->count++; |
44 | 45 | ||
@@ -66,7 +67,7 @@ static int __hw_addr_add_ex(struct netdev_hw_addr_list *list, | |||
66 | } | 67 | } |
67 | if (sync) { | 68 | if (sync) { |
68 | if (ha->synced) | 69 | if (ha->synced) |
69 | return 0; | 70 | return -EEXIST; |
70 | else | 71 | else |
71 | ha->synced = true; | 72 | ha->synced = true; |
72 | } | 73 | } |
@@ -139,10 +140,13 @@ static int __hw_addr_sync_one(struct netdev_hw_addr_list *to_list, | |||
139 | 140 | ||
140 | err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type, | 141 | err = __hw_addr_add_ex(to_list, ha->addr, addr_len, ha->type, |
141 | false, true); | 142 | false, true); |
142 | if (err) | 143 | if (err && err != -EEXIST) |
143 | return err; | 144 | return err; |
144 | ha->sync_cnt++; | 145 | |
145 | ha->refcount++; | 146 | if (!err) { |
147 | ha->sync_cnt++; | ||
148 | ha->refcount++; | ||
149 | } | ||
146 | 150 | ||
147 | return 0; | 151 | return 0; |
148 | } | 152 | } |
@@ -159,7 +163,8 @@ static void __hw_addr_unsync_one(struct netdev_hw_addr_list *to_list, | |||
159 | if (err) | 163 | if (err) |
160 | return; | 164 | return; |
161 | ha->sync_cnt--; | 165 | ha->sync_cnt--; |
162 | __hw_addr_del_entry(from_list, ha, false, true); | 166 | /* address on from list is not marked synced */ |
167 | __hw_addr_del_entry(from_list, ha, false, false); | ||
163 | } | 168 | } |
164 | 169 | ||
165 | static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list, | 170 | static int __hw_addr_sync_multiple(struct netdev_hw_addr_list *to_list, |
@@ -796,7 +801,7 @@ int dev_mc_sync_multiple(struct net_device *to, struct net_device *from) | |||
796 | return -EINVAL; | 801 | return -EINVAL; |
797 | 802 | ||
798 | netif_addr_lock_nested(to); | 803 | netif_addr_lock_nested(to); |
799 | err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len); | 804 | err = __hw_addr_sync_multiple(&to->mc, &from->mc, to->addr_len); |
800 | if (!err) | 805 | if (!err) |
801 | __dev_set_rx_mode(to); | 806 | __dev_set_rx_mode(to); |
802 | netif_addr_unlock(to); | 807 | netif_addr_unlock(to); |
diff --git a/net/core/filter.c b/net/core/filter.c index dad2a178f9f8..6438f29ff266 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -778,7 +778,7 @@ int sk_detach_filter(struct sock *sk) | |||
778 | } | 778 | } |
779 | EXPORT_SYMBOL_GPL(sk_detach_filter); | 779 | EXPORT_SYMBOL_GPL(sk_detach_filter); |
780 | 780 | ||
781 | static void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) | 781 | void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to) |
782 | { | 782 | { |
783 | static const u16 decodes[] = { | 783 | static const u16 decodes[] = { |
784 | [BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K, | 784 | [BPF_S_ALU_ADD_K] = BPF_ALU|BPF_ADD|BPF_K, |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index af9185d0be6a..cfd777bd6bd0 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -195,7 +195,7 @@ struct sk_buff *__alloc_skb_head(gfp_t gfp_mask, int node) | |||
195 | * the tail pointer in struct sk_buff! | 195 | * the tail pointer in struct sk_buff! |
196 | */ | 196 | */ |
197 | memset(skb, 0, offsetof(struct sk_buff, tail)); | 197 | memset(skb, 0, offsetof(struct sk_buff, tail)); |
198 | skb->data = NULL; | 198 | skb->head = NULL; |
199 | skb->truesize = sizeof(struct sk_buff); | 199 | skb->truesize = sizeof(struct sk_buff); |
200 | atomic_set(&skb->users, 1); | 200 | atomic_set(&skb->users, 1); |
201 | 201 | ||
@@ -611,7 +611,7 @@ static void skb_release_head_state(struct sk_buff *skb) | |||
611 | static void skb_release_all(struct sk_buff *skb) | 611 | static void skb_release_all(struct sk_buff *skb) |
612 | { | 612 | { |
613 | skb_release_head_state(skb); | 613 | skb_release_head_state(skb); |
614 | if (likely(skb->data)) | 614 | if (likely(skb->head)) |
615 | skb_release_data(skb); | 615 | skb_release_data(skb); |
616 | } | 616 | } |
617 | 617 | ||
diff --git a/net/core/sock.c b/net/core/sock.c index 6ba327da79e1..88868a9d21da 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -210,7 +210,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { | |||
210 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , | 210 | "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , |
211 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , | 211 | "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , |
212 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , | 212 | "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , |
213 | "sk_lock-AF_NFC" , "sk_lock-AF_MAX" | 213 | "sk_lock-AF_NFC" , "sk_lock-AF_VSOCK" , "sk_lock-AF_MAX" |
214 | }; | 214 | }; |
215 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { | 215 | static const char *const af_family_slock_key_strings[AF_MAX+1] = { |
216 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , | 216 | "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" , |
@@ -226,7 +226,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { | |||
226 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , | 226 | "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , |
227 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , | 227 | "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , |
228 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , | 228 | "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , |
229 | "slock-AF_NFC" , "slock-AF_MAX" | 229 | "slock-AF_NFC" , "slock-AF_VSOCK" ,"slock-AF_MAX" |
230 | }; | 230 | }; |
231 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { | 231 | static const char *const af_family_clock_key_strings[AF_MAX+1] = { |
232 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , | 232 | "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" , |
@@ -242,7 +242,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { | |||
242 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , | 242 | "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , |
243 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , | 243 | "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , |
244 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , | 244 | "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , |
245 | "clock-AF_NFC" , "clock-AF_MAX" | 245 | "clock-AF_NFC" , "clock-AF_VSOCK" , "clock-AF_MAX" |
246 | }; | 246 | }; |
247 | 247 | ||
248 | /* | 248 | /* |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index d5bef0b0f639..a0e9cf6379de 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -73,8 +73,13 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | |||
73 | goto out; | 73 | goto out; |
74 | } | 74 | } |
75 | 75 | ||
76 | if (filter) | 76 | if (filter) { |
77 | memcpy(nla_data(attr), filter->insns, len); | 77 | struct sock_filter *fb = (struct sock_filter *)nla_data(attr); |
78 | int i; | ||
79 | |||
80 | for (i = 0; i < filter->len; i++, fb++) | ||
81 | sk_decode_filter(&filter->insns[i], fb); | ||
82 | } | ||
78 | 83 | ||
79 | out: | 84 | out: |
80 | rcu_read_unlock(); | 85 | rcu_read_unlock(); |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index e4147ec1665a..7fa8f08fa7ae 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -503,6 +503,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
503 | 503 | ||
504 | inner_iph = (const struct iphdr *)skb_inner_network_header(skb); | 504 | inner_iph = (const struct iphdr *)skb_inner_network_header(skb); |
505 | 505 | ||
506 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | ||
506 | dst = tnl_params->daddr; | 507 | dst = tnl_params->daddr; |
507 | if (dst == 0) { | 508 | if (dst == 0) { |
508 | /* NBMA tunnel */ | 509 | /* NBMA tunnel */ |
@@ -658,7 +659,6 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev, | |||
658 | 659 | ||
659 | skb_dst_drop(skb); | 660 | skb_dst_drop(skb); |
660 | skb_dst_set(skb, &rt->dst); | 661 | skb_dst_set(skb, &rt->dst); |
661 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); | ||
662 | 662 | ||
663 | /* Push down and install the IP header. */ | 663 | /* Push down and install the IP header. */ |
664 | skb_push(skb, sizeof(struct iphdr)); | 664 | skb_push(skb, sizeof(struct iphdr)); |
@@ -853,7 +853,7 @@ void ip_tunnel_dellink(struct net_device *dev, struct list_head *head) | |||
853 | } | 853 | } |
854 | EXPORT_SYMBOL_GPL(ip_tunnel_dellink); | 854 | EXPORT_SYMBOL_GPL(ip_tunnel_dellink); |
855 | 855 | ||
856 | int __net_init ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, | 856 | int ip_tunnel_init_net(struct net *net, int ip_tnl_net_id, |
857 | struct rtnl_link_ops *ops, char *devname) | 857 | struct rtnl_link_ops *ops, char *devname) |
858 | { | 858 | { |
859 | struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id); | 859 | struct ip_tunnel_net *itn = net_generic(net, ip_tnl_net_id); |
@@ -899,7 +899,7 @@ static void ip_tunnel_destroy(struct ip_tunnel_net *itn, struct list_head *head) | |||
899 | unregister_netdevice_queue(itn->fb_tunnel_dev, head); | 899 | unregister_netdevice_queue(itn->fb_tunnel_dev, head); |
900 | } | 900 | } |
901 | 901 | ||
902 | void __net_exit ip_tunnel_delete_net(struct ip_tunnel_net *itn) | 902 | void ip_tunnel_delete_net(struct ip_tunnel_net *itn) |
903 | { | 903 | { |
904 | LIST_HEAD(list); | 904 | LIST_HEAD(list); |
905 | 905 | ||
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 9d2bdb2c1d3f..c118f6b576bb 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
@@ -361,8 +361,7 @@ static netdev_tx_t vti_tunnel_xmit(struct sk_buff *skb, struct net_device *dev) | |||
361 | tunnel->err_count = 0; | 361 | tunnel->err_count = 0; |
362 | } | 362 | } |
363 | 363 | ||
364 | IPCB(skb)->flags &= ~(IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED | | 364 | memset(IPCB(skb), 0, sizeof(*IPCB(skb))); |
365 | IPSKB_REROUTED); | ||
366 | skb_dst_drop(skb); | 365 | skb_dst_drop(skb); |
367 | skb_dst_set(skb, &rt->dst); | 366 | skb_dst_set(skb, &rt->dst); |
368 | nf_reset(skb); | 367 | nf_reset(skb); |
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c index cf08218ddbcf..ff4b781b1056 100644 --- a/net/ipv4/netfilter/ipt_ULOG.c +++ b/net/ipv4/netfilter/ipt_ULOG.c | |||
@@ -231,8 +231,10 @@ static void ipt_ulog_packet(struct net *net, | |||
231 | put_unaligned(tv.tv_usec, &pm->timestamp_usec); | 231 | put_unaligned(tv.tv_usec, &pm->timestamp_usec); |
232 | put_unaligned(skb->mark, &pm->mark); | 232 | put_unaligned(skb->mark, &pm->mark); |
233 | pm->hook = hooknum; | 233 | pm->hook = hooknum; |
234 | if (prefix != NULL) | 234 | if (prefix != NULL) { |
235 | strncpy(pm->prefix, prefix, sizeof(pm->prefix)); | 235 | strncpy(pm->prefix, prefix, sizeof(pm->prefix) - 1); |
236 | pm->prefix[sizeof(pm->prefix) - 1] = '\0'; | ||
237 | } | ||
236 | else if (loginfo->prefix[0] != '\0') | 238 | else if (loginfo->prefix[0] != '\0') |
237 | strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); | 239 | strncpy(pm->prefix, loginfo->prefix, sizeof(pm->prefix)); |
238 | else | 240 | else |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 550781a17b34..d35bbf0cf404 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -737,10 +737,15 @@ static void ip_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_buf | |||
737 | { | 737 | { |
738 | struct rtable *rt; | 738 | struct rtable *rt; |
739 | struct flowi4 fl4; | 739 | struct flowi4 fl4; |
740 | const struct iphdr *iph = (const struct iphdr *) skb->data; | ||
741 | int oif = skb->dev->ifindex; | ||
742 | u8 tos = RT_TOS(iph->tos); | ||
743 | u8 prot = iph->protocol; | ||
744 | u32 mark = skb->mark; | ||
740 | 745 | ||
741 | rt = (struct rtable *) dst; | 746 | rt = (struct rtable *) dst; |
742 | 747 | ||
743 | ip_rt_build_flow_key(&fl4, sk, skb); | 748 | __build_flow_key(&fl4, sk, iph, oif, tos, prot, mark, 0); |
744 | __ip_do_redirect(rt, skb, &fl4, true); | 749 | __ip_do_redirect(rt, skb, &fl4, true); |
745 | } | 750 | } |
746 | 751 | ||
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index d1ab6ab29a55..1bbf744c2cc3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -1487,7 +1487,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev) | |||
1487 | } | 1487 | } |
1488 | 1488 | ||
1489 | int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, | 1489 | int ipv6_chk_addr(struct net *net, const struct in6_addr *addr, |
1490 | struct net_device *dev, int strict) | 1490 | const struct net_device *dev, int strict) |
1491 | { | 1491 | { |
1492 | struct inet6_ifaddr *ifp; | 1492 | struct inet6_ifaddr *ifp; |
1493 | unsigned int hash = inet6_addr_hash(addr); | 1493 | unsigned int hash = inet6_addr_hash(addr); |
@@ -2658,8 +2658,10 @@ static void init_loopback(struct net_device *dev) | |||
2658 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); | 2658 | sp_rt = addrconf_dst_alloc(idev, &sp_ifa->addr, 0); |
2659 | 2659 | ||
2660 | /* Failure cases are ignored */ | 2660 | /* Failure cases are ignored */ |
2661 | if (!IS_ERR(sp_rt)) | 2661 | if (!IS_ERR(sp_rt)) { |
2662 | sp_ifa->rt = sp_rt; | ||
2662 | ip6_ins_rt(sp_rt); | 2663 | ip6_ins_rt(sp_rt); |
2664 | } | ||
2663 | } | 2665 | } |
2664 | read_unlock_bh(&idev->lock); | 2666 | read_unlock_bh(&idev->lock); |
2665 | } | 2667 | } |
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c index 72836f40b730..95f3f1da0d7f 100644 --- a/net/ipv6/netfilter.c +++ b/net/ipv6/netfilter.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/netfilter.h> | 10 | #include <linux/netfilter.h> |
11 | #include <linux/netfilter_ipv6.h> | 11 | #include <linux/netfilter_ipv6.h> |
12 | #include <linux/export.h> | 12 | #include <linux/export.h> |
13 | #include <net/addrconf.h> | ||
13 | #include <net/dst.h> | 14 | #include <net/dst.h> |
14 | #include <net/ipv6.h> | 15 | #include <net/ipv6.h> |
15 | #include <net/ip6_route.h> | 16 | #include <net/ip6_route.h> |
@@ -186,6 +187,10 @@ static __sum16 nf_ip6_checksum_partial(struct sk_buff *skb, unsigned int hook, | |||
186 | return csum; | 187 | return csum; |
187 | }; | 188 | }; |
188 | 189 | ||
190 | static const struct nf_ipv6_ops ipv6ops = { | ||
191 | .chk_addr = ipv6_chk_addr, | ||
192 | }; | ||
193 | |||
189 | static const struct nf_afinfo nf_ip6_afinfo = { | 194 | static const struct nf_afinfo nf_ip6_afinfo = { |
190 | .family = AF_INET6, | 195 | .family = AF_INET6, |
191 | .checksum = nf_ip6_checksum, | 196 | .checksum = nf_ip6_checksum, |
@@ -198,6 +203,7 @@ static const struct nf_afinfo nf_ip6_afinfo = { | |||
198 | 203 | ||
199 | int __init ipv6_netfilter_init(void) | 204 | int __init ipv6_netfilter_init(void) |
200 | { | 205 | { |
206 | RCU_INIT_POINTER(nf_ipv6_ops, &ipv6ops); | ||
201 | return nf_register_afinfo(&nf_ip6_afinfo); | 207 | return nf_register_afinfo(&nf_ip6_afinfo); |
202 | } | 208 | } |
203 | 209 | ||
@@ -206,5 +212,6 @@ int __init ipv6_netfilter_init(void) | |||
206 | */ | 212 | */ |
207 | void ipv6_netfilter_fini(void) | 213 | void ipv6_netfilter_fini(void) |
208 | { | 214 | { |
215 | RCU_INIT_POINTER(nf_ipv6_ops, NULL); | ||
209 | nf_unregister_afinfo(&nf_ip6_afinfo); | 216 | nf_unregister_afinfo(&nf_ip6_afinfo); |
210 | } | 217 | } |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index f3c1ff4357ff..51c3285b5d9b 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -90,7 +90,7 @@ static const struct snmp_mib snmp6_ipstats_list[] = { | |||
90 | SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), | 90 | SNMP_MIB_ITEM("Ip6OutMcastOctets", IPSTATS_MIB_OUTMCASTOCTETS), |
91 | SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), | 91 | SNMP_MIB_ITEM("Ip6InBcastOctets", IPSTATS_MIB_INBCASTOCTETS), |
92 | SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), | 92 | SNMP_MIB_ITEM("Ip6OutBcastOctets", IPSTATS_MIB_OUTBCASTOCTETS), |
93 | SNMP_MIB_ITEM("InCsumErrors", IPSTATS_MIB_CSUMERRORS), | 93 | /* IPSTATS_MIB_CSUMERRORS is not relevant in IPv6 (no checksum) */ |
94 | SNMP_MIB_SENTINEL | 94 | SNMP_MIB_SENTINEL |
95 | }; | 95 | }; |
96 | 96 | ||
diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c index 3bb3a891a424..d3cfaf9c7a08 100644 --- a/net/ipv6/udp_offload.c +++ b/net/ipv6/udp_offload.c | |||
@@ -46,11 +46,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
46 | unsigned int mss; | 46 | unsigned int mss; |
47 | unsigned int unfrag_ip6hlen, unfrag_len; | 47 | unsigned int unfrag_ip6hlen, unfrag_len; |
48 | struct frag_hdr *fptr; | 48 | struct frag_hdr *fptr; |
49 | u8 *mac_start, *prevhdr; | 49 | u8 *packet_start, *prevhdr; |
50 | u8 nexthdr; | 50 | u8 nexthdr; |
51 | u8 frag_hdr_sz = sizeof(struct frag_hdr); | 51 | u8 frag_hdr_sz = sizeof(struct frag_hdr); |
52 | int offset; | 52 | int offset; |
53 | __wsum csum; | 53 | __wsum csum; |
54 | int tnl_hlen; | ||
54 | 55 | ||
55 | mss = skb_shinfo(skb)->gso_size; | 56 | mss = skb_shinfo(skb)->gso_size; |
56 | if (unlikely(skb->len <= mss)) | 57 | if (unlikely(skb->len <= mss)) |
@@ -83,9 +84,11 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
83 | skb->ip_summed = CHECKSUM_NONE; | 84 | skb->ip_summed = CHECKSUM_NONE; |
84 | 85 | ||
85 | /* Check if there is enough headroom to insert fragment header. */ | 86 | /* Check if there is enough headroom to insert fragment header. */ |
86 | if ((skb_mac_header(skb) < skb->head + frag_hdr_sz) && | 87 | tnl_hlen = skb_tnl_header_len(skb); |
87 | pskb_expand_head(skb, frag_hdr_sz, 0, GFP_ATOMIC)) | 88 | if (skb_headroom(skb) < (tnl_hlen + frag_hdr_sz)) { |
88 | goto out; | 89 | if (gso_pskb_expand_head(skb, tnl_hlen + frag_hdr_sz)) |
90 | goto out; | ||
91 | } | ||
89 | 92 | ||
90 | /* Find the unfragmentable header and shift it left by frag_hdr_sz | 93 | /* Find the unfragmentable header and shift it left by frag_hdr_sz |
91 | * bytes to insert fragment header. | 94 | * bytes to insert fragment header. |
@@ -93,11 +96,12 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb, | |||
93 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); | 96 | unfrag_ip6hlen = ip6_find_1stfragopt(skb, &prevhdr); |
94 | nexthdr = *prevhdr; | 97 | nexthdr = *prevhdr; |
95 | *prevhdr = NEXTHDR_FRAGMENT; | 98 | *prevhdr = NEXTHDR_FRAGMENT; |
96 | unfrag_len = skb_network_header(skb) - skb_mac_header(skb) + | 99 | unfrag_len = (skb_network_header(skb) - skb_mac_header(skb)) + |
97 | unfrag_ip6hlen; | 100 | unfrag_ip6hlen + tnl_hlen; |
98 | mac_start = skb_mac_header(skb); | 101 | packet_start = (u8 *) skb->head + SKB_GSO_CB(skb)->mac_offset; |
99 | memmove(mac_start-frag_hdr_sz, mac_start, unfrag_len); | 102 | memmove(packet_start-frag_hdr_sz, packet_start, unfrag_len); |
100 | 103 | ||
104 | SKB_GSO_CB(skb)->mac_offset -= frag_hdr_sz; | ||
101 | skb->mac_header -= frag_hdr_sz; | 105 | skb->mac_header -= frag_hdr_sz; |
102 | skb->network_header -= frag_hdr_sz; | 106 | skb->network_header -= frag_hdr_sz; |
103 | 107 | ||
diff --git a/net/key/af_key.c b/net/key/af_key.c index 5b1e5af25713..c5fbd7589681 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
@@ -2366,6 +2366,8 @@ static int pfkey_spddelete(struct sock *sk, struct sk_buff *skb, const struct sa | |||
2366 | 2366 | ||
2367 | out: | 2367 | out: |
2368 | xfrm_pol_put(xp); | 2368 | xfrm_pol_put(xp); |
2369 | if (err == 0) | ||
2370 | xfrm_garbage_collect(net); | ||
2369 | return err; | 2371 | return err; |
2370 | } | 2372 | } |
2371 | 2373 | ||
@@ -2615,6 +2617,8 @@ static int pfkey_spdget(struct sock *sk, struct sk_buff *skb, const struct sadb_ | |||
2615 | 2617 | ||
2616 | out: | 2618 | out: |
2617 | xfrm_pol_put(xp); | 2619 | xfrm_pol_put(xp); |
2620 | if (delete && err == 0) | ||
2621 | xfrm_garbage_collect(net); | ||
2618 | return err; | 2622 | return err; |
2619 | } | 2623 | } |
2620 | 2624 | ||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c index 637a341c1e2d..8dec6876dc50 100644 --- a/net/l2tp/l2tp_ppp.c +++ b/net/l2tp/l2tp_ppp.c | |||
@@ -346,19 +346,19 @@ static int pppol2tp_sendmsg(struct kiocb *iocb, struct socket *sock, struct msgh | |||
346 | skb_put(skb, 2); | 346 | skb_put(skb, 2); |
347 | 347 | ||
348 | /* Copy user data into skb */ | 348 | /* Copy user data into skb */ |
349 | error = memcpy_fromiovec(skb->data, m->msg_iov, total_len); | 349 | error = memcpy_fromiovec(skb_put(skb, total_len), m->msg_iov, |
350 | total_len); | ||
350 | if (error < 0) { | 351 | if (error < 0) { |
351 | kfree_skb(skb); | 352 | kfree_skb(skb); |
352 | goto error_put_sess_tun; | 353 | goto error_put_sess_tun; |
353 | } | 354 | } |
354 | skb_put(skb, total_len); | ||
355 | 355 | ||
356 | l2tp_xmit_skb(session, skb, session->hdr_len); | 356 | l2tp_xmit_skb(session, skb, session->hdr_len); |
357 | 357 | ||
358 | sock_put(ps->tunnel_sock); | 358 | sock_put(ps->tunnel_sock); |
359 | sock_put(sk); | 359 | sock_put(sk); |
360 | 360 | ||
361 | return error; | 361 | return total_len; |
362 | 362 | ||
363 | error_put_sess_tun: | 363 | error_put_sess_tun: |
364 | sock_put(ps->tunnel_sock); | 364 | sock_put(ps->tunnel_sock); |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 60f1ce5e5e52..98d20c0f6fed 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -159,9 +159,10 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu) | |||
159 | return 0; | 159 | return 0; |
160 | } | 160 | } |
161 | 161 | ||
162 | static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) | 162 | static int ieee80211_verify_mac(struct ieee80211_sub_if_data *sdata, u8 *addr) |
163 | { | 163 | { |
164 | struct ieee80211_sub_if_data *sdata; | 164 | struct ieee80211_local *local = sdata->local; |
165 | struct ieee80211_sub_if_data *iter; | ||
165 | u64 new, mask, tmp; | 166 | u64 new, mask, tmp; |
166 | u8 *m; | 167 | u8 *m; |
167 | int ret = 0; | 168 | int ret = 0; |
@@ -181,11 +182,14 @@ static int ieee80211_verify_mac(struct ieee80211_local *local, u8 *addr) | |||
181 | 182 | ||
182 | 183 | ||
183 | mutex_lock(&local->iflist_mtx); | 184 | mutex_lock(&local->iflist_mtx); |
184 | list_for_each_entry(sdata, &local->interfaces, list) { | 185 | list_for_each_entry(iter, &local->interfaces, list) { |
185 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | 186 | if (iter == sdata) |
187 | continue; | ||
188 | |||
189 | if (iter->vif.type == NL80211_IFTYPE_MONITOR) | ||
186 | continue; | 190 | continue; |
187 | 191 | ||
188 | m = sdata->vif.addr; | 192 | m = iter->vif.addr; |
189 | tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | | 193 | tmp = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | |
190 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | | 194 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | |
191 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); | 195 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); |
@@ -209,7 +213,7 @@ static int ieee80211_change_mac(struct net_device *dev, void *addr) | |||
209 | if (ieee80211_sdata_running(sdata)) | 213 | if (ieee80211_sdata_running(sdata)) |
210 | return -EBUSY; | 214 | return -EBUSY; |
211 | 215 | ||
212 | ret = ieee80211_verify_mac(sdata->local, sa->sa_data); | 216 | ret = ieee80211_verify_mac(sdata, sa->sa_data); |
213 | if (ret) | 217 | if (ret) |
214 | return ret; | 218 | return ret; |
215 | 219 | ||
@@ -474,6 +478,9 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
474 | master->control_port_protocol; | 478 | master->control_port_protocol; |
475 | sdata->control_port_no_encrypt = | 479 | sdata->control_port_no_encrypt = |
476 | master->control_port_no_encrypt; | 480 | master->control_port_no_encrypt; |
481 | sdata->vif.cab_queue = master->vif.cab_queue; | ||
482 | memcpy(sdata->vif.hw_queue, master->vif.hw_queue, | ||
483 | sizeof(sdata->vif.hw_queue)); | ||
477 | break; | 484 | break; |
478 | } | 485 | } |
479 | case NL80211_IFTYPE_AP: | 486 | case NL80211_IFTYPE_AP: |
@@ -653,7 +660,11 @@ int ieee80211_do_open(struct wireless_dev *wdev, bool coming_up) | |||
653 | 660 | ||
654 | ieee80211_recalc_ps(local, -1); | 661 | ieee80211_recalc_ps(local, -1); |
655 | 662 | ||
656 | if (dev) { | 663 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR || |
664 | sdata->vif.type == NL80211_IFTYPE_AP_VLAN) { | ||
665 | /* XXX: for AP_VLAN, actually track AP queues */ | ||
666 | netif_tx_start_all_queues(dev); | ||
667 | } else if (dev) { | ||
657 | unsigned long flags; | 668 | unsigned long flags; |
658 | int n_acs = IEEE80211_NUM_ACS; | 669 | int n_acs = IEEE80211_NUM_ACS; |
659 | int ac; | 670 | int ac; |
@@ -1479,7 +1490,17 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local, | |||
1479 | break; | 1490 | break; |
1480 | } | 1491 | } |
1481 | 1492 | ||
1493 | /* | ||
1494 | * Pick address of existing interface in case user changed | ||
1495 | * MAC address manually, default to perm_addr. | ||
1496 | */ | ||
1482 | m = local->hw.wiphy->perm_addr; | 1497 | m = local->hw.wiphy->perm_addr; |
1498 | list_for_each_entry(sdata, &local->interfaces, list) { | ||
1499 | if (sdata->vif.type == NL80211_IFTYPE_MONITOR) | ||
1500 | continue; | ||
1501 | m = sdata->vif.addr; | ||
1502 | break; | ||
1503 | } | ||
1483 | start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | | 1504 | start = ((u64)m[0] << 5*8) | ((u64)m[1] << 4*8) | |
1484 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | | 1505 | ((u64)m[2] << 3*8) | ((u64)m[3] << 2*8) | |
1485 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); | 1506 | ((u64)m[4] << 1*8) | ((u64)m[5] << 0*8); |
@@ -1696,6 +1717,15 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local) | |||
1696 | 1717 | ||
1697 | ASSERT_RTNL(); | 1718 | ASSERT_RTNL(); |
1698 | 1719 | ||
1720 | /* | ||
1721 | * Close all AP_VLAN interfaces first, as otherwise they | ||
1722 | * might be closed while the AP interface they belong to | ||
1723 | * is closed, causing unregister_netdevice_many() to crash. | ||
1724 | */ | ||
1725 | list_for_each_entry(sdata, &local->interfaces, list) | ||
1726 | if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) | ||
1727 | dev_close(sdata->dev); | ||
1728 | |||
1699 | mutex_lock(&local->iflist_mtx); | 1729 | mutex_lock(&local->iflist_mtx); |
1700 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { | 1730 | list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) { |
1701 | list_del(&sdata->list); | 1731 | list_del(&sdata->list); |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index a46e490f20dd..a8c2130c8ba4 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3321,10 +3321,6 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3321 | if (WARN_ON_ONCE(!auth_data)) | 3321 | if (WARN_ON_ONCE(!auth_data)) |
3322 | return -EINVAL; | 3322 | return -EINVAL; |
3323 | 3323 | ||
3324 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
3325 | tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
3326 | IEEE80211_TX_INTFL_MLME_CONN_TX; | ||
3327 | |||
3328 | auth_data->tries++; | 3324 | auth_data->tries++; |
3329 | 3325 | ||
3330 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { | 3326 | if (auth_data->tries > IEEE80211_AUTH_MAX_TRIES) { |
@@ -3358,6 +3354,10 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3358 | auth_data->expected_transaction = trans; | 3354 | auth_data->expected_transaction = trans; |
3359 | } | 3355 | } |
3360 | 3356 | ||
3357 | if (local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS) | ||
3358 | tx_flags = IEEE80211_TX_CTL_REQ_TX_STATUS | | ||
3359 | IEEE80211_TX_INTFL_MLME_CONN_TX; | ||
3360 | |||
3361 | ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, | 3361 | ieee80211_send_auth(sdata, trans, auth_data->algorithm, status, |
3362 | auth_data->data, auth_data->data_len, | 3362 | auth_data->data, auth_data->data_len, |
3363 | auth_data->bss->bssid, | 3363 | auth_data->bss->bssid, |
@@ -3381,12 +3381,12 @@ static int ieee80211_probe_auth(struct ieee80211_sub_if_data *sdata) | |||
3381 | * will not answer to direct packet in unassociated state. | 3381 | * will not answer to direct packet in unassociated state. |
3382 | */ | 3382 | */ |
3383 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], | 3383 | ieee80211_send_probe_req(sdata, NULL, ssidie + 2, ssidie[1], |
3384 | NULL, 0, (u32) -1, true, tx_flags, | 3384 | NULL, 0, (u32) -1, true, 0, |
3385 | auth_data->bss->channel, false); | 3385 | auth_data->bss->channel, false); |
3386 | rcu_read_unlock(); | 3386 | rcu_read_unlock(); |
3387 | } | 3387 | } |
3388 | 3388 | ||
3389 | if (!(local->hw.flags & IEEE80211_HW_REPORTS_TX_ACK_STATUS)) { | 3389 | if (tx_flags == 0) { |
3390 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; | 3390 | auth_data->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; |
3391 | ifmgd->auth_data->timeout_started = true; | 3391 | ifmgd->auth_data->timeout_started = true; |
3392 | run_again(ifmgd, auth_data->timeout); | 3392 | run_again(ifmgd, auth_data->timeout); |
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 07c865a31a3d..857ca9f35177 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
@@ -30,6 +30,8 @@ static DEFINE_MUTEX(afinfo_mutex); | |||
30 | 30 | ||
31 | const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; | 31 | const struct nf_afinfo __rcu *nf_afinfo[NFPROTO_NUMPROTO] __read_mostly; |
32 | EXPORT_SYMBOL(nf_afinfo); | 32 | EXPORT_SYMBOL(nf_afinfo); |
33 | const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly; | ||
34 | EXPORT_SYMBOL_GPL(nf_ipv6_ops); | ||
33 | 35 | ||
34 | int nf_register_afinfo(const struct nf_afinfo *afinfo) | 36 | int nf_register_afinfo(const struct nf_afinfo *afinfo) |
35 | { | 37 | { |
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index 085b5880ab0d..05565d2b3a61 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c | |||
@@ -1001,6 +1001,32 @@ static inline int is_tcp_reset(const struct sk_buff *skb, int nh_len) | |||
1001 | return th->rst; | 1001 | return th->rst; |
1002 | } | 1002 | } |
1003 | 1003 | ||
1004 | static inline bool is_new_conn(const struct sk_buff *skb, | ||
1005 | struct ip_vs_iphdr *iph) | ||
1006 | { | ||
1007 | switch (iph->protocol) { | ||
1008 | case IPPROTO_TCP: { | ||
1009 | struct tcphdr _tcph, *th; | ||
1010 | |||
1011 | th = skb_header_pointer(skb, iph->len, sizeof(_tcph), &_tcph); | ||
1012 | if (th == NULL) | ||
1013 | return false; | ||
1014 | return th->syn; | ||
1015 | } | ||
1016 | case IPPROTO_SCTP: { | ||
1017 | sctp_chunkhdr_t *sch, schunk; | ||
1018 | |||
1019 | sch = skb_header_pointer(skb, iph->len + sizeof(sctp_sctphdr_t), | ||
1020 | sizeof(schunk), &schunk); | ||
1021 | if (sch == NULL) | ||
1022 | return false; | ||
1023 | return sch->type == SCTP_CID_INIT; | ||
1024 | } | ||
1025 | default: | ||
1026 | return false; | ||
1027 | } | ||
1028 | } | ||
1029 | |||
1004 | /* Handle response packets: rewrite addresses and send away... | 1030 | /* Handle response packets: rewrite addresses and send away... |
1005 | */ | 1031 | */ |
1006 | static unsigned int | 1032 | static unsigned int |
@@ -1612,6 +1638,15 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) | |||
1612 | * Check if the packet belongs to an existing connection entry | 1638 | * Check if the packet belongs to an existing connection entry |
1613 | */ | 1639 | */ |
1614 | cp = pp->conn_in_get(af, skb, &iph, 0); | 1640 | cp = pp->conn_in_get(af, skb, &iph, 0); |
1641 | |||
1642 | if (unlikely(sysctl_expire_nodest_conn(ipvs)) && cp && cp->dest && | ||
1643 | unlikely(!atomic_read(&cp->dest->weight)) && !iph.fragoffs && | ||
1644 | is_new_conn(skb, &iph)) { | ||
1645 | ip_vs_conn_expire_now(cp); | ||
1646 | __ip_vs_conn_put(cp); | ||
1647 | cp = NULL; | ||
1648 | } | ||
1649 | |||
1615 | if (unlikely(!cp) && !iph.fragoffs) { | 1650 | if (unlikely(!cp) && !iph.fragoffs) { |
1616 | /* No (second) fragments need to enter here, as nf_defrag_ipv6 | 1651 | /* No (second) fragments need to enter here, as nf_defrag_ipv6 |
1617 | * replayed fragment zero will already have created the cp | 1652 | * replayed fragment zero will already have created the cp |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 5b142fb16480..9e6c2a075a4c 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -2542,6 +2542,7 @@ __ip_vs_get_dest_entries(struct net *net, const struct ip_vs_get_dests *get, | |||
2542 | struct ip_vs_dest *dest; | 2542 | struct ip_vs_dest *dest; |
2543 | struct ip_vs_dest_entry entry; | 2543 | struct ip_vs_dest_entry entry; |
2544 | 2544 | ||
2545 | memset(&entry, 0, sizeof(entry)); | ||
2545 | list_for_each_entry(dest, &svc->destinations, n_list) { | 2546 | list_for_each_entry(dest, &svc->destinations, n_list) { |
2546 | if (count >= get->num_dests) | 2547 | if (count >= get->num_dests) |
2547 | break; | 2548 | break; |
diff --git a/net/netfilter/ipvs/ip_vs_sh.c b/net/netfilter/ipvs/ip_vs_sh.c index 0df269d7c99f..a65edfe4b16c 100644 --- a/net/netfilter/ipvs/ip_vs_sh.c +++ b/net/netfilter/ipvs/ip_vs_sh.c | |||
@@ -67,8 +67,8 @@ struct ip_vs_sh_bucket { | |||
67 | #define IP_VS_SH_TAB_MASK (IP_VS_SH_TAB_SIZE - 1) | 67 | #define IP_VS_SH_TAB_MASK (IP_VS_SH_TAB_SIZE - 1) |
68 | 68 | ||
69 | struct ip_vs_sh_state { | 69 | struct ip_vs_sh_state { |
70 | struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE]; | ||
71 | struct rcu_head rcu_head; | 70 | struct rcu_head rcu_head; |
71 | struct ip_vs_sh_bucket buckets[IP_VS_SH_TAB_SIZE]; | ||
72 | }; | 72 | }; |
73 | 73 | ||
74 | /* | 74 | /* |
diff --git a/net/netfilter/nfnetlink_acct.c b/net/netfilter/nfnetlink_acct.c index dc3fd5d44464..c7b6d466a662 100644 --- a/net/netfilter/nfnetlink_acct.c +++ b/net/netfilter/nfnetlink_acct.c | |||
@@ -149,9 +149,12 @@ nfnl_acct_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
149 | 149 | ||
150 | rcu_read_lock(); | 150 | rcu_read_lock(); |
151 | list_for_each_entry_rcu(cur, &nfnl_acct_list, head) { | 151 | list_for_each_entry_rcu(cur, &nfnl_acct_list, head) { |
152 | if (last && cur != last) | 152 | if (last) { |
153 | continue; | 153 | if (cur != last) |
154 | continue; | ||
154 | 155 | ||
156 | last = NULL; | ||
157 | } | ||
155 | if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid, | 158 | if (nfnl_acct_fill_info(skb, NETLINK_CB(cb->skb).portid, |
156 | cb->nlh->nlmsg_seq, | 159 | cb->nlh->nlmsg_seq, |
157 | NFNL_MSG_TYPE(cb->nlh->nlmsg_type), | 160 | NFNL_MSG_TYPE(cb->nlh->nlmsg_type), |
diff --git a/net/netfilter/nfnetlink_cttimeout.c b/net/netfilter/nfnetlink_cttimeout.c index 701c88a20fea..65074dfb9383 100644 --- a/net/netfilter/nfnetlink_cttimeout.c +++ b/net/netfilter/nfnetlink_cttimeout.c | |||
@@ -220,9 +220,12 @@ ctnl_timeout_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
220 | 220 | ||
221 | rcu_read_lock(); | 221 | rcu_read_lock(); |
222 | list_for_each_entry_rcu(cur, &cttimeout_list, head) { | 222 | list_for_each_entry_rcu(cur, &cttimeout_list, head) { |
223 | if (last && cur != last) | 223 | if (last) { |
224 | continue; | 224 | if (cur != last) |
225 | continue; | ||
225 | 226 | ||
227 | last = NULL; | ||
228 | } | ||
226 | if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid, | 229 | if (ctnl_timeout_fill_info(skb, NETLINK_CB(cb->skb).portid, |
227 | cb->nlh->nlmsg_seq, | 230 | cb->nlh->nlmsg_seq, |
228 | NFNL_MSG_TYPE(cb->nlh->nlmsg_type), | 231 | NFNL_MSG_TYPE(cb->nlh->nlmsg_type), |
diff --git a/net/netfilter/nfnetlink_queue_core.c b/net/netfilter/nfnetlink_queue_core.c index 4e27fa035814..5352b2d2d5bf 100644 --- a/net/netfilter/nfnetlink_queue_core.c +++ b/net/netfilter/nfnetlink_queue_core.c | |||
@@ -637,9 +637,6 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) | |||
637 | if (queue->copy_mode == NFQNL_COPY_NONE) | 637 | if (queue->copy_mode == NFQNL_COPY_NONE) |
638 | return -EINVAL; | 638 | return -EINVAL; |
639 | 639 | ||
640 | if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(entry->skb)) | ||
641 | return __nfqnl_enqueue_packet(net, queue, entry); | ||
642 | |||
643 | skb = entry->skb; | 640 | skb = entry->skb; |
644 | 641 | ||
645 | switch (entry->pf) { | 642 | switch (entry->pf) { |
@@ -651,6 +648,9 @@ nfqnl_enqueue_packet(struct nf_queue_entry *entry, unsigned int queuenum) | |||
651 | break; | 648 | break; |
652 | } | 649 | } |
653 | 650 | ||
651 | if ((queue->flags & NFQA_CFG_F_GSO) || !skb_is_gso(skb)) | ||
652 | return __nfqnl_enqueue_packet(net, queue, entry); | ||
653 | |||
654 | nf_bridge_adjust_skb_data(skb); | 654 | nf_bridge_adjust_skb_data(skb); |
655 | segs = skb_gso_segment(skb, 0); | 655 | segs = skb_gso_segment(skb, 0); |
656 | /* Does not use PTR_ERR to limit the number of error codes that can be | 656 | /* Does not use PTR_ERR to limit the number of error codes that can be |
diff --git a/net/netfilter/xt_LOG.c b/net/netfilter/xt_LOG.c index 491c7d821a0b..5ab24843370a 100644 --- a/net/netfilter/xt_LOG.c +++ b/net/netfilter/xt_LOG.c | |||
@@ -737,7 +737,7 @@ static void dump_ipv6_packet(struct sbuff *m, | |||
737 | dump_sk_uid_gid(m, skb->sk); | 737 | dump_sk_uid_gid(m, skb->sk); |
738 | 738 | ||
739 | /* Max length: 16 "MARK=0xFFFFFFFF " */ | 739 | /* Max length: 16 "MARK=0xFFFFFFFF " */ |
740 | if (!recurse && skb->mark) | 740 | if (recurse && skb->mark) |
741 | sb_add(m, "MARK=0x%x ", skb->mark); | 741 | sb_add(m, "MARK=0x%x ", skb->mark); |
742 | } | 742 | } |
743 | 743 | ||
diff --git a/net/netfilter/xt_TCPMSS.c b/net/netfilter/xt_TCPMSS.c index a75240f0d42b..afaebc766933 100644 --- a/net/netfilter/xt_TCPMSS.c +++ b/net/netfilter/xt_TCPMSS.c | |||
@@ -125,6 +125,12 @@ tcpmss_mangle_packet(struct sk_buff *skb, | |||
125 | 125 | ||
126 | skb_put(skb, TCPOLEN_MSS); | 126 | skb_put(skb, TCPOLEN_MSS); |
127 | 127 | ||
128 | /* RFC 879 states that the default MSS is 536 without specific | ||
129 | * knowledge that the destination host is prepared to accept larger. | ||
130 | * Since no MSS was provided, we MUST NOT set a value > 536. | ||
131 | */ | ||
132 | newmss = min(newmss, (u16)536); | ||
133 | |||
128 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); | 134 | opt = (u_int8_t *)tcph + sizeof(struct tcphdr); |
129 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); | 135 | memmove(opt + TCPOLEN_MSS, opt, tcplen - sizeof(struct tcphdr)); |
130 | 136 | ||
diff --git a/net/netfilter/xt_addrtype.c b/net/netfilter/xt_addrtype.c index 49c5ff7f6dd6..68ff29f60867 100644 --- a/net/netfilter/xt_addrtype.c +++ b/net/netfilter/xt_addrtype.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <net/ip6_fib.h> | 22 | #include <net/ip6_fib.h> |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | #include <linux/netfilter_ipv6.h> | ||
25 | #include <linux/netfilter/xt_addrtype.h> | 26 | #include <linux/netfilter/xt_addrtype.h> |
26 | #include <linux/netfilter/x_tables.h> | 27 | #include <linux/netfilter/x_tables.h> |
27 | 28 | ||
@@ -33,12 +34,12 @@ MODULE_ALIAS("ip6t_addrtype"); | |||
33 | 34 | ||
34 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | 35 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) |
35 | static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, | 36 | static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, |
36 | const struct in6_addr *addr) | 37 | const struct in6_addr *addr, u16 mask) |
37 | { | 38 | { |
38 | const struct nf_afinfo *afinfo; | 39 | const struct nf_afinfo *afinfo; |
39 | struct flowi6 flow; | 40 | struct flowi6 flow; |
40 | struct rt6_info *rt; | 41 | struct rt6_info *rt; |
41 | u32 ret; | 42 | u32 ret = 0; |
42 | int route_err; | 43 | int route_err; |
43 | 44 | ||
44 | memset(&flow, 0, sizeof(flow)); | 45 | memset(&flow, 0, sizeof(flow)); |
@@ -49,12 +50,19 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, | |||
49 | rcu_read_lock(); | 50 | rcu_read_lock(); |
50 | 51 | ||
51 | afinfo = nf_get_afinfo(NFPROTO_IPV6); | 52 | afinfo = nf_get_afinfo(NFPROTO_IPV6); |
52 | if (afinfo != NULL) | 53 | if (afinfo != NULL) { |
54 | const struct nf_ipv6_ops *v6ops; | ||
55 | |||
56 | if (dev && (mask & XT_ADDRTYPE_LOCAL)) { | ||
57 | v6ops = nf_get_ipv6_ops(); | ||
58 | if (v6ops && v6ops->chk_addr(net, addr, dev, true)) | ||
59 | ret = XT_ADDRTYPE_LOCAL; | ||
60 | } | ||
53 | route_err = afinfo->route(net, (struct dst_entry **)&rt, | 61 | route_err = afinfo->route(net, (struct dst_entry **)&rt, |
54 | flowi6_to_flowi(&flow), !!dev); | 62 | flowi6_to_flowi(&flow), false); |
55 | else | 63 | } else { |
56 | route_err = 1; | 64 | route_err = 1; |
57 | 65 | } | |
58 | rcu_read_unlock(); | 66 | rcu_read_unlock(); |
59 | 67 | ||
60 | if (route_err) | 68 | if (route_err) |
@@ -62,15 +70,12 @@ static u32 match_lookup_rt6(struct net *net, const struct net_device *dev, | |||
62 | 70 | ||
63 | if (rt->rt6i_flags & RTF_REJECT) | 71 | if (rt->rt6i_flags & RTF_REJECT) |
64 | ret = XT_ADDRTYPE_UNREACHABLE; | 72 | ret = XT_ADDRTYPE_UNREACHABLE; |
65 | else | ||
66 | ret = 0; | ||
67 | 73 | ||
68 | if (rt->rt6i_flags & RTF_LOCAL) | 74 | if (dev == NULL && rt->rt6i_flags & RTF_LOCAL) |
69 | ret |= XT_ADDRTYPE_LOCAL; | 75 | ret |= XT_ADDRTYPE_LOCAL; |
70 | if (rt->rt6i_flags & RTF_ANYCAST) | 76 | if (rt->rt6i_flags & RTF_ANYCAST) |
71 | ret |= XT_ADDRTYPE_ANYCAST; | 77 | ret |= XT_ADDRTYPE_ANYCAST; |
72 | 78 | ||
73 | |||
74 | dst_release(&rt->dst); | 79 | dst_release(&rt->dst); |
75 | return ret; | 80 | return ret; |
76 | } | 81 | } |
@@ -90,7 +95,7 @@ static bool match_type6(struct net *net, const struct net_device *dev, | |||
90 | 95 | ||
91 | if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | | 96 | if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST | |
92 | XT_ADDRTYPE_UNREACHABLE) & mask) | 97 | XT_ADDRTYPE_UNREACHABLE) & mask) |
93 | return !!(mask & match_lookup_rt6(net, dev, addr)); | 98 | return !!(mask & match_lookup_rt6(net, dev, addr, mask)); |
94 | return true; | 99 | return true; |
95 | } | 100 | } |
96 | 101 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 12ac6b47a35c..57ee84d21470 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -371,7 +371,7 @@ static int netlink_mmap(struct file *file, struct socket *sock, | |||
371 | err = 0; | 371 | err = 0; |
372 | out: | 372 | out: |
373 | mutex_unlock(&nlk->pg_vec_lock); | 373 | mutex_unlock(&nlk->pg_vec_lock); |
374 | return 0; | 374 | return err; |
375 | } | 375 | } |
376 | 376 | ||
377 | static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr) | 377 | static void netlink_frame_flush_dcache(const struct nl_mmap_hdr *hdr) |
@@ -747,7 +747,7 @@ static void netlink_skb_destructor(struct sk_buff *skb) | |||
747 | atomic_dec(&ring->pending); | 747 | atomic_dec(&ring->pending); |
748 | sock_put(sk); | 748 | sock_put(sk); |
749 | 749 | ||
750 | skb->data = NULL; | 750 | skb->head = NULL; |
751 | } | 751 | } |
752 | #endif | 752 | #endif |
753 | if (skb->sk != NULL) | 753 | if (skb->sk != NULL) |
diff --git a/net/nfc/Makefile b/net/nfc/Makefile index fb799deaed4f..a76f4533cb6c 100644 --- a/net/nfc/Makefile +++ b/net/nfc/Makefile | |||
@@ -5,7 +5,6 @@ | |||
5 | obj-$(CONFIG_NFC) += nfc.o | 5 | obj-$(CONFIG_NFC) += nfc.o |
6 | obj-$(CONFIG_NFC_NCI) += nci/ | 6 | obj-$(CONFIG_NFC_NCI) += nci/ |
7 | obj-$(CONFIG_NFC_HCI) += hci/ | 7 | obj-$(CONFIG_NFC_HCI) += hci/ |
8 | #obj-$(CONFIG_NFC_LLCP) += llcp/ | ||
9 | 8 | ||
10 | nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ | 9 | nfc-objs := core.o netlink.o af_nfc.o rawsock.o llcp_core.o llcp_commands.o \ |
11 | llcp_sock.o | 10 | llcp_sock.o |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 8ec1bca7f859..20a1bd0e6549 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -2851,12 +2851,11 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr, | |||
2851 | return -EOPNOTSUPP; | 2851 | return -EOPNOTSUPP; |
2852 | 2852 | ||
2853 | uaddr->sa_family = AF_PACKET; | 2853 | uaddr->sa_family = AF_PACKET; |
2854 | memset(uaddr->sa_data, 0, sizeof(uaddr->sa_data)); | ||
2854 | rcu_read_lock(); | 2855 | rcu_read_lock(); |
2855 | dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); | 2856 | dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex); |
2856 | if (dev) | 2857 | if (dev) |
2857 | strncpy(uaddr->sa_data, dev->name, 14); | 2858 | strlcpy(uaddr->sa_data, dev->name, sizeof(uaddr->sa_data)); |
2858 | else | ||
2859 | memset(uaddr->sa_data, 0, 14); | ||
2860 | rcu_read_unlock(); | 2859 | rcu_read_unlock(); |
2861 | *uaddr_len = sizeof(*uaddr); | 2860 | *uaddr_len = sizeof(*uaddr); |
2862 | 2861 | ||
diff --git a/net/sched/act_police.c b/net/sched/act_police.c index 823463adbd21..189e3c5b3d09 100644 --- a/net/sched/act_police.c +++ b/net/sched/act_police.c | |||
@@ -231,14 +231,14 @@ override: | |||
231 | } | 231 | } |
232 | if (R_tab) { | 232 | if (R_tab) { |
233 | police->rate_present = true; | 233 | police->rate_present = true; |
234 | psched_ratecfg_precompute(&police->rate, R_tab->rate.rate); | 234 | psched_ratecfg_precompute(&police->rate, &R_tab->rate); |
235 | qdisc_put_rtab(R_tab); | 235 | qdisc_put_rtab(R_tab); |
236 | } else { | 236 | } else { |
237 | police->rate_present = false; | 237 | police->rate_present = false; |
238 | } | 238 | } |
239 | if (P_tab) { | 239 | if (P_tab) { |
240 | police->peak_present = true; | 240 | police->peak_present = true; |
241 | psched_ratecfg_precompute(&police->peak, P_tab->rate.rate); | 241 | psched_ratecfg_precompute(&police->peak, &P_tab->rate); |
242 | qdisc_put_rtab(P_tab); | 242 | qdisc_put_rtab(P_tab); |
243 | } else { | 243 | } else { |
244 | police->peak_present = false; | 244 | police->peak_present = false; |
@@ -376,9 +376,9 @@ tcf_act_police_dump(struct sk_buff *skb, struct tc_action *a, int bind, int ref) | |||
376 | }; | 376 | }; |
377 | 377 | ||
378 | if (police->rate_present) | 378 | if (police->rate_present) |
379 | opt.rate.rate = psched_ratecfg_getrate(&police->rate); | 379 | psched_ratecfg_getrate(&opt.rate, &police->rate); |
380 | if (police->peak_present) | 380 | if (police->peak_present) |
381 | opt.peakrate.rate = psched_ratecfg_getrate(&police->peak); | 381 | psched_ratecfg_getrate(&opt.peakrate, &police->peak); |
382 | if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) | 382 | if (nla_put(skb, TCA_POLICE_TBF, sizeof(opt), &opt)) |
383 | goto nla_put_failure; | 383 | goto nla_put_failure; |
384 | if (police->tcfp_result && | 384 | if (police->tcfp_result && |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 2b935e7cfe7b..281c1bded1f6 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -291,17 +291,18 @@ struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r, struct nlattr *ta | |||
291 | { | 291 | { |
292 | struct qdisc_rate_table *rtab; | 292 | struct qdisc_rate_table *rtab; |
293 | 293 | ||
294 | if (tab == NULL || r->rate == 0 || r->cell_log == 0 || | ||
295 | nla_len(tab) != TC_RTAB_SIZE) | ||
296 | return NULL; | ||
297 | |||
294 | for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { | 298 | for (rtab = qdisc_rtab_list; rtab; rtab = rtab->next) { |
295 | if (memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) == 0) { | 299 | if (!memcmp(&rtab->rate, r, sizeof(struct tc_ratespec)) && |
300 | !memcmp(&rtab->data, nla_data(tab), 1024)) { | ||
296 | rtab->refcnt++; | 301 | rtab->refcnt++; |
297 | return rtab; | 302 | return rtab; |
298 | } | 303 | } |
299 | } | 304 | } |
300 | 305 | ||
301 | if (tab == NULL || r->rate == 0 || r->cell_log == 0 || | ||
302 | nla_len(tab) != TC_RTAB_SIZE) | ||
303 | return NULL; | ||
304 | |||
305 | rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); | 306 | rtab = kmalloc(sizeof(*rtab), GFP_KERNEL); |
306 | if (rtab) { | 307 | if (rtab) { |
307 | rtab->rate = *r; | 308 | rtab->rate = *r; |
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c index eac7e0ee23c1..20224086cc28 100644 --- a/net/sched/sch_generic.c +++ b/net/sched/sch_generic.c | |||
@@ -898,14 +898,16 @@ void dev_shutdown(struct net_device *dev) | |||
898 | WARN_ON(timer_pending(&dev->watchdog_timer)); | 898 | WARN_ON(timer_pending(&dev->watchdog_timer)); |
899 | } | 899 | } |
900 | 900 | ||
901 | void psched_ratecfg_precompute(struct psched_ratecfg *r, u32 rate) | 901 | void psched_ratecfg_precompute(struct psched_ratecfg *r, |
902 | const struct tc_ratespec *conf) | ||
902 | { | 903 | { |
903 | u64 factor; | 904 | u64 factor; |
904 | u64 mult; | 905 | u64 mult; |
905 | int shift; | 906 | int shift; |
906 | 907 | ||
907 | r->rate_bps = (u64)rate << 3; | 908 | memset(r, 0, sizeof(*r)); |
908 | r->shift = 0; | 909 | r->overhead = conf->overhead; |
910 | r->rate_bps = (u64)conf->rate << 3; | ||
909 | r->mult = 1; | 911 | r->mult = 1; |
910 | /* | 912 | /* |
911 | * Calibrate mult, shift so that token counting is accurate | 913 | * Calibrate mult, shift so that token counting is accurate |
diff --git a/net/sched/sch_htb.c b/net/sched/sch_htb.c index 79b1876b6cd2..adaedd79389c 100644 --- a/net/sched/sch_htb.c +++ b/net/sched/sch_htb.c | |||
@@ -109,7 +109,7 @@ struct htb_class { | |||
109 | } un; | 109 | } un; |
110 | struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */ | 110 | struct rb_node node[TC_HTB_NUMPRIO]; /* node for self or feed tree */ |
111 | struct rb_node pq_node; /* node for event queue */ | 111 | struct rb_node pq_node; /* node for event queue */ |
112 | psched_time_t pq_key; | 112 | s64 pq_key; |
113 | 113 | ||
114 | int prio_activity; /* for which prios are we active */ | 114 | int prio_activity; /* for which prios are we active */ |
115 | enum htb_cmode cmode; /* current mode of the class */ | 115 | enum htb_cmode cmode; /* current mode of the class */ |
@@ -121,10 +121,10 @@ struct htb_class { | |||
121 | /* token bucket parameters */ | 121 | /* token bucket parameters */ |
122 | struct psched_ratecfg rate; | 122 | struct psched_ratecfg rate; |
123 | struct psched_ratecfg ceil; | 123 | struct psched_ratecfg ceil; |
124 | s64 buffer, cbuffer; /* token bucket depth/rate */ | 124 | s64 buffer, cbuffer; /* token bucket depth/rate */ |
125 | psched_tdiff_t mbuffer; /* max wait time */ | 125 | s64 mbuffer; /* max wait time */ |
126 | s64 tokens, ctokens; /* current number of tokens */ | 126 | s64 tokens, ctokens; /* current number of tokens */ |
127 | psched_time_t t_c; /* checkpoint time */ | 127 | s64 t_c; /* checkpoint time */ |
128 | }; | 128 | }; |
129 | 129 | ||
130 | struct htb_sched { | 130 | struct htb_sched { |
@@ -141,15 +141,15 @@ struct htb_sched { | |||
141 | struct rb_root wait_pq[TC_HTB_MAXDEPTH]; | 141 | struct rb_root wait_pq[TC_HTB_MAXDEPTH]; |
142 | 142 | ||
143 | /* time of nearest event per level (row) */ | 143 | /* time of nearest event per level (row) */ |
144 | psched_time_t near_ev_cache[TC_HTB_MAXDEPTH]; | 144 | s64 near_ev_cache[TC_HTB_MAXDEPTH]; |
145 | 145 | ||
146 | int defcls; /* class where unclassified flows go to */ | 146 | int defcls; /* class where unclassified flows go to */ |
147 | 147 | ||
148 | /* filters for qdisc itself */ | 148 | /* filters for qdisc itself */ |
149 | struct tcf_proto *filter_list; | 149 | struct tcf_proto *filter_list; |
150 | 150 | ||
151 | int rate2quantum; /* quant = rate / rate2quantum */ | 151 | int rate2quantum; /* quant = rate / rate2quantum */ |
152 | psched_time_t now; /* cached dequeue time */ | 152 | s64 now; /* cached dequeue time */ |
153 | struct qdisc_watchdog watchdog; | 153 | struct qdisc_watchdog watchdog; |
154 | 154 | ||
155 | /* non shaped skbs; let them go directly thru */ | 155 | /* non shaped skbs; let them go directly thru */ |
@@ -664,8 +664,8 @@ static void htb_charge_class(struct htb_sched *q, struct htb_class *cl, | |||
664 | * next pending event (0 for no event in pq, q->now for too many events). | 664 | * next pending event (0 for no event in pq, q->now for too many events). |
665 | * Note: Applied are events whose have cl->pq_key <= q->now. | 665 | * Note: Applied are events whose have cl->pq_key <= q->now. |
666 | */ | 666 | */ |
667 | static psched_time_t htb_do_events(struct htb_sched *q, int level, | 667 | static s64 htb_do_events(struct htb_sched *q, int level, |
668 | unsigned long start) | 668 | unsigned long start) |
669 | { | 669 | { |
670 | /* don't run for longer than 2 jiffies; 2 is used instead of | 670 | /* don't run for longer than 2 jiffies; 2 is used instead of |
671 | * 1 to simplify things when jiffy is going to be incremented | 671 | * 1 to simplify things when jiffy is going to be incremented |
@@ -857,7 +857,7 @@ static struct sk_buff *htb_dequeue(struct Qdisc *sch) | |||
857 | struct sk_buff *skb; | 857 | struct sk_buff *skb; |
858 | struct htb_sched *q = qdisc_priv(sch); | 858 | struct htb_sched *q = qdisc_priv(sch); |
859 | int level; | 859 | int level; |
860 | psched_time_t next_event; | 860 | s64 next_event; |
861 | unsigned long start_at; | 861 | unsigned long start_at; |
862 | 862 | ||
863 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ | 863 | /* try to dequeue direct packets as high prio (!) to minimize cpu work */ |
@@ -880,7 +880,7 @@ ok: | |||
880 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { | 880 | for (level = 0; level < TC_HTB_MAXDEPTH; level++) { |
881 | /* common case optimization - skip event handler quickly */ | 881 | /* common case optimization - skip event handler quickly */ |
882 | int m; | 882 | int m; |
883 | psched_time_t event; | 883 | s64 event; |
884 | 884 | ||
885 | if (q->now >= q->near_ev_cache[level]) { | 885 | if (q->now >= q->near_ev_cache[level]) { |
886 | event = htb_do_events(q, level, start_at); | 886 | event = htb_do_events(q, level, start_at); |
@@ -1090,9 +1090,9 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg, | |||
1090 | 1090 | ||
1091 | memset(&opt, 0, sizeof(opt)); | 1091 | memset(&opt, 0, sizeof(opt)); |
1092 | 1092 | ||
1093 | opt.rate.rate = psched_ratecfg_getrate(&cl->rate); | 1093 | psched_ratecfg_getrate(&opt.rate, &cl->rate); |
1094 | opt.buffer = PSCHED_NS2TICKS(cl->buffer); | 1094 | opt.buffer = PSCHED_NS2TICKS(cl->buffer); |
1095 | opt.ceil.rate = psched_ratecfg_getrate(&cl->ceil); | 1095 | psched_ratecfg_getrate(&opt.ceil, &cl->ceil); |
1096 | opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer); | 1096 | opt.cbuffer = PSCHED_NS2TICKS(cl->cbuffer); |
1097 | opt.quantum = cl->quantum; | 1097 | opt.quantum = cl->quantum; |
1098 | opt.prio = cl->prio; | 1098 | opt.prio = cl->prio; |
@@ -1117,8 +1117,8 @@ htb_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d) | |||
1117 | 1117 | ||
1118 | if (!cl->level && cl->un.leaf.q) | 1118 | if (!cl->level && cl->un.leaf.q) |
1119 | cl->qstats.qlen = cl->un.leaf.q->q.qlen; | 1119 | cl->qstats.qlen = cl->un.leaf.q->q.qlen; |
1120 | cl->xstats.tokens = cl->tokens; | 1120 | cl->xstats.tokens = PSCHED_NS2TICKS(cl->tokens); |
1121 | cl->xstats.ctokens = cl->ctokens; | 1121 | cl->xstats.ctokens = PSCHED_NS2TICKS(cl->ctokens); |
1122 | 1122 | ||
1123 | if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || | 1123 | if (gnet_stats_copy_basic(d, &cl->bstats) < 0 || |
1124 | gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 || | 1124 | gnet_stats_copy_rate_est(d, NULL, &cl->rate_est) < 0 || |
@@ -1200,7 +1200,7 @@ static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl, | |||
1200 | parent->un.leaf.q = new_q ? new_q : &noop_qdisc; | 1200 | parent->un.leaf.q = new_q ? new_q : &noop_qdisc; |
1201 | parent->tokens = parent->buffer; | 1201 | parent->tokens = parent->buffer; |
1202 | parent->ctokens = parent->cbuffer; | 1202 | parent->ctokens = parent->cbuffer; |
1203 | parent->t_c = psched_get_time(); | 1203 | parent->t_c = ktime_to_ns(ktime_get()); |
1204 | parent->cmode = HTB_CAN_SEND; | 1204 | parent->cmode = HTB_CAN_SEND; |
1205 | } | 1205 | } |
1206 | 1206 | ||
@@ -1417,8 +1417,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1417 | /* set class to be in HTB_CAN_SEND state */ | 1417 | /* set class to be in HTB_CAN_SEND state */ |
1418 | cl->tokens = PSCHED_TICKS2NS(hopt->buffer); | 1418 | cl->tokens = PSCHED_TICKS2NS(hopt->buffer); |
1419 | cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer); | 1419 | cl->ctokens = PSCHED_TICKS2NS(hopt->cbuffer); |
1420 | cl->mbuffer = 60 * PSCHED_TICKS_PER_SEC; /* 1min */ | 1420 | cl->mbuffer = 60ULL * NSEC_PER_SEC; /* 1min */ |
1421 | cl->t_c = psched_get_time(); | 1421 | cl->t_c = ktime_to_ns(ktime_get()); |
1422 | cl->cmode = HTB_CAN_SEND; | 1422 | cl->cmode = HTB_CAN_SEND; |
1423 | 1423 | ||
1424 | /* attach to the hash list and parent's family */ | 1424 | /* attach to the hash list and parent's family */ |
@@ -1459,8 +1459,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid, | |||
1459 | cl->prio = TC_HTB_NUMPRIO - 1; | 1459 | cl->prio = TC_HTB_NUMPRIO - 1; |
1460 | } | 1460 | } |
1461 | 1461 | ||
1462 | psched_ratecfg_precompute(&cl->rate, hopt->rate.rate); | 1462 | psched_ratecfg_precompute(&cl->rate, &hopt->rate); |
1463 | psched_ratecfg_precompute(&cl->ceil, hopt->ceil.rate); | 1463 | psched_ratecfg_precompute(&cl->ceil, &hopt->ceil); |
1464 | 1464 | ||
1465 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); | 1465 | cl->buffer = PSCHED_TICKS2NS(hopt->buffer); |
1466 | cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); | 1466 | cl->cbuffer = PSCHED_TICKS2NS(hopt->buffer); |
diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index c8388f3c3426..e478d316602b 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c | |||
@@ -298,9 +298,9 @@ static int tbf_change(struct Qdisc *sch, struct nlattr *opt) | |||
298 | q->tokens = q->buffer; | 298 | q->tokens = q->buffer; |
299 | q->ptokens = q->mtu; | 299 | q->ptokens = q->mtu; |
300 | 300 | ||
301 | psched_ratecfg_precompute(&q->rate, rtab->rate.rate); | 301 | psched_ratecfg_precompute(&q->rate, &rtab->rate); |
302 | if (ptab) { | 302 | if (ptab) { |
303 | psched_ratecfg_precompute(&q->peak, ptab->rate.rate); | 303 | psched_ratecfg_precompute(&q->peak, &ptab->rate); |
304 | q->peak_present = true; | 304 | q->peak_present = true; |
305 | } else { | 305 | } else { |
306 | q->peak_present = false; | 306 | q->peak_present = false; |
@@ -350,9 +350,9 @@ static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) | |||
350 | goto nla_put_failure; | 350 | goto nla_put_failure; |
351 | 351 | ||
352 | opt.limit = q->limit; | 352 | opt.limit = q->limit; |
353 | opt.rate.rate = psched_ratecfg_getrate(&q->rate); | 353 | psched_ratecfg_getrate(&opt.rate, &q->rate); |
354 | if (q->peak_present) | 354 | if (q->peak_present) |
355 | opt.peakrate.rate = psched_ratecfg_getrate(&q->peak); | 355 | psched_ratecfg_getrate(&opt.peakrate, &q->peak); |
356 | else | 356 | else |
357 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); | 357 | memset(&opt.peakrate, 0, sizeof(opt.peakrate)); |
358 | opt.mtu = PSCHED_NS2TICKS(q->mtu); | 358 | opt.mtu = PSCHED_NS2TICKS(q->mtu); |
diff --git a/net/sctp/outqueue.c b/net/sctp/outqueue.c index 32a4625fef77..be35e2dbcc9a 100644 --- a/net/sctp/outqueue.c +++ b/net/sctp/outqueue.c | |||
@@ -206,6 +206,8 @@ static inline int sctp_cacc_skip(struct sctp_transport *primary, | |||
206 | */ | 206 | */ |
207 | void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | 207 | void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) |
208 | { | 208 | { |
209 | memset(q, 0, sizeof(struct sctp_outq)); | ||
210 | |||
209 | q->asoc = asoc; | 211 | q->asoc = asoc; |
210 | INIT_LIST_HEAD(&q->out_chunk_list); | 212 | INIT_LIST_HEAD(&q->out_chunk_list); |
211 | INIT_LIST_HEAD(&q->control_chunk_list); | 213 | INIT_LIST_HEAD(&q->control_chunk_list); |
@@ -213,11 +215,7 @@ void sctp_outq_init(struct sctp_association *asoc, struct sctp_outq *q) | |||
213 | INIT_LIST_HEAD(&q->sacked); | 215 | INIT_LIST_HEAD(&q->sacked); |
214 | INIT_LIST_HEAD(&q->abandoned); | 216 | INIT_LIST_HEAD(&q->abandoned); |
215 | 217 | ||
216 | q->fast_rtx = 0; | ||
217 | q->outstanding_bytes = 0; | ||
218 | q->empty = 1; | 218 | q->empty = 1; |
219 | q->cork = 0; | ||
220 | q->out_qlen = 0; | ||
221 | } | 219 | } |
222 | 220 | ||
223 | /* Free the outqueue structure and any related pending chunks. | 221 | /* Free the outqueue structure and any related pending chunks. |
diff --git a/net/sctp/socket.c b/net/sctp/socket.c index f631c5ff4dbf..6abb1caf9836 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c | |||
@@ -4003,6 +4003,12 @@ SCTP_STATIC void sctp_destroy_sock(struct sock *sk) | |||
4003 | 4003 | ||
4004 | /* Release our hold on the endpoint. */ | 4004 | /* Release our hold on the endpoint. */ |
4005 | sp = sctp_sk(sk); | 4005 | sp = sctp_sk(sk); |
4006 | /* This could happen during socket init, thus we bail out | ||
4007 | * early, since the rest of the below is not setup either. | ||
4008 | */ | ||
4009 | if (sp->ep == NULL) | ||
4010 | return; | ||
4011 | |||
4006 | if (sp->do_auto_asconf) { | 4012 | if (sp->do_auto_asconf) { |
4007 | sp->do_auto_asconf = 0; | 4013 | sp->do_auto_asconf = 0; |
4008 | list_del(&sp->auto_asconf_list); | 4014 | list_del(&sp->auto_asconf_list); |
diff --git a/net/socket.c b/net/socket.c index 6b94633ca61d..4ca1526db756 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -1956,7 +1956,7 @@ struct used_address { | |||
1956 | unsigned int name_len; | 1956 | unsigned int name_len; |
1957 | }; | 1957 | }; |
1958 | 1958 | ||
1959 | static int __sys_sendmsg(struct socket *sock, struct msghdr __user *msg, | 1959 | static int ___sys_sendmsg(struct socket *sock, struct msghdr __user *msg, |
1960 | struct msghdr *msg_sys, unsigned int flags, | 1960 | struct msghdr *msg_sys, unsigned int flags, |
1961 | struct used_address *used_address) | 1961 | struct used_address *used_address) |
1962 | { | 1962 | { |
@@ -2071,22 +2071,30 @@ out: | |||
2071 | * BSD sendmsg interface | 2071 | * BSD sendmsg interface |
2072 | */ | 2072 | */ |
2073 | 2073 | ||
2074 | SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) | 2074 | long __sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags) |
2075 | { | 2075 | { |
2076 | int fput_needed, err; | 2076 | int fput_needed, err; |
2077 | struct msghdr msg_sys; | 2077 | struct msghdr msg_sys; |
2078 | struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); | 2078 | struct socket *sock; |
2079 | 2079 | ||
2080 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | ||
2080 | if (!sock) | 2081 | if (!sock) |
2081 | goto out; | 2082 | goto out; |
2082 | 2083 | ||
2083 | err = __sys_sendmsg(sock, msg, &msg_sys, flags, NULL); | 2084 | err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL); |
2084 | 2085 | ||
2085 | fput_light(sock->file, fput_needed); | 2086 | fput_light(sock->file, fput_needed); |
2086 | out: | 2087 | out: |
2087 | return err; | 2088 | return err; |
2088 | } | 2089 | } |
2089 | 2090 | ||
2091 | SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned int, flags) | ||
2092 | { | ||
2093 | if (flags & MSG_CMSG_COMPAT) | ||
2094 | return -EINVAL; | ||
2095 | return __sys_sendmsg(fd, msg, flags); | ||
2096 | } | ||
2097 | |||
2090 | /* | 2098 | /* |
2091 | * Linux sendmmsg interface | 2099 | * Linux sendmmsg interface |
2092 | */ | 2100 | */ |
@@ -2117,15 +2125,16 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2117 | 2125 | ||
2118 | while (datagrams < vlen) { | 2126 | while (datagrams < vlen) { |
2119 | if (MSG_CMSG_COMPAT & flags) { | 2127 | if (MSG_CMSG_COMPAT & flags) { |
2120 | err = __sys_sendmsg(sock, (struct msghdr __user *)compat_entry, | 2128 | err = ___sys_sendmsg(sock, (struct msghdr __user *)compat_entry, |
2121 | &msg_sys, flags, &used_address); | 2129 | &msg_sys, flags, &used_address); |
2122 | if (err < 0) | 2130 | if (err < 0) |
2123 | break; | 2131 | break; |
2124 | err = __put_user(err, &compat_entry->msg_len); | 2132 | err = __put_user(err, &compat_entry->msg_len); |
2125 | ++compat_entry; | 2133 | ++compat_entry; |
2126 | } else { | 2134 | } else { |
2127 | err = __sys_sendmsg(sock, (struct msghdr __user *)entry, | 2135 | err = ___sys_sendmsg(sock, |
2128 | &msg_sys, flags, &used_address); | 2136 | (struct msghdr __user *)entry, |
2137 | &msg_sys, flags, &used_address); | ||
2129 | if (err < 0) | 2138 | if (err < 0) |
2130 | break; | 2139 | break; |
2131 | err = put_user(err, &entry->msg_len); | 2140 | err = put_user(err, &entry->msg_len); |
@@ -2149,10 +2158,12 @@ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2149 | SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, | 2158 | SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, |
2150 | unsigned int, vlen, unsigned int, flags) | 2159 | unsigned int, vlen, unsigned int, flags) |
2151 | { | 2160 | { |
2161 | if (flags & MSG_CMSG_COMPAT) | ||
2162 | return -EINVAL; | ||
2152 | return __sys_sendmmsg(fd, mmsg, vlen, flags); | 2163 | return __sys_sendmmsg(fd, mmsg, vlen, flags); |
2153 | } | 2164 | } |
2154 | 2165 | ||
2155 | static int __sys_recvmsg(struct socket *sock, struct msghdr __user *msg, | 2166 | static int ___sys_recvmsg(struct socket *sock, struct msghdr __user *msg, |
2156 | struct msghdr *msg_sys, unsigned int flags, int nosec) | 2167 | struct msghdr *msg_sys, unsigned int flags, int nosec) |
2157 | { | 2168 | { |
2158 | struct compat_msghdr __user *msg_compat = | 2169 | struct compat_msghdr __user *msg_compat = |
@@ -2244,23 +2255,31 @@ out: | |||
2244 | * BSD recvmsg interface | 2255 | * BSD recvmsg interface |
2245 | */ | 2256 | */ |
2246 | 2257 | ||
2247 | SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, | 2258 | long __sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags) |
2248 | unsigned int, flags) | ||
2249 | { | 2259 | { |
2250 | int fput_needed, err; | 2260 | int fput_needed, err; |
2251 | struct msghdr msg_sys; | 2261 | struct msghdr msg_sys; |
2252 | struct socket *sock = sockfd_lookup_light(fd, &err, &fput_needed); | 2262 | struct socket *sock; |
2253 | 2263 | ||
2264 | sock = sockfd_lookup_light(fd, &err, &fput_needed); | ||
2254 | if (!sock) | 2265 | if (!sock) |
2255 | goto out; | 2266 | goto out; |
2256 | 2267 | ||
2257 | err = __sys_recvmsg(sock, msg, &msg_sys, flags, 0); | 2268 | err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
2258 | 2269 | ||
2259 | fput_light(sock->file, fput_needed); | 2270 | fput_light(sock->file, fput_needed); |
2260 | out: | 2271 | out: |
2261 | return err; | 2272 | return err; |
2262 | } | 2273 | } |
2263 | 2274 | ||
2275 | SYSCALL_DEFINE3(recvmsg, int, fd, struct msghdr __user *, msg, | ||
2276 | unsigned int, flags) | ||
2277 | { | ||
2278 | if (flags & MSG_CMSG_COMPAT) | ||
2279 | return -EINVAL; | ||
2280 | return __sys_recvmsg(fd, msg, flags); | ||
2281 | } | ||
2282 | |||
2264 | /* | 2283 | /* |
2265 | * Linux recvmmsg interface | 2284 | * Linux recvmmsg interface |
2266 | */ | 2285 | */ |
@@ -2298,17 +2317,18 @@ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, | |||
2298 | * No need to ask LSM for more than the first datagram. | 2317 | * No need to ask LSM for more than the first datagram. |
2299 | */ | 2318 | */ |
2300 | if (MSG_CMSG_COMPAT & flags) { | 2319 | if (MSG_CMSG_COMPAT & flags) { |
2301 | err = __sys_recvmsg(sock, (struct msghdr __user *)compat_entry, | 2320 | err = ___sys_recvmsg(sock, (struct msghdr __user *)compat_entry, |
2302 | &msg_sys, flags & ~MSG_WAITFORONE, | 2321 | &msg_sys, flags & ~MSG_WAITFORONE, |
2303 | datagrams); | 2322 | datagrams); |
2304 | if (err < 0) | 2323 | if (err < 0) |
2305 | break; | 2324 | break; |
2306 | err = __put_user(err, &compat_entry->msg_len); | 2325 | err = __put_user(err, &compat_entry->msg_len); |
2307 | ++compat_entry; | 2326 | ++compat_entry; |
2308 | } else { | 2327 | } else { |
2309 | err = __sys_recvmsg(sock, (struct msghdr __user *)entry, | 2328 | err = ___sys_recvmsg(sock, |
2310 | &msg_sys, flags & ~MSG_WAITFORONE, | 2329 | (struct msghdr __user *)entry, |
2311 | datagrams); | 2330 | &msg_sys, flags & ~MSG_WAITFORONE, |
2331 | datagrams); | ||
2312 | if (err < 0) | 2332 | if (err < 0) |
2313 | break; | 2333 | break; |
2314 | err = put_user(err, &entry->msg_len); | 2334 | err = put_user(err, &entry->msg_len); |
@@ -2375,6 +2395,9 @@ SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, | |||
2375 | int datagrams; | 2395 | int datagrams; |
2376 | struct timespec timeout_sys; | 2396 | struct timespec timeout_sys; |
2377 | 2397 | ||
2398 | if (flags & MSG_CMSG_COMPAT) | ||
2399 | return -EINVAL; | ||
2400 | |||
2378 | if (!timeout) | 2401 | if (!timeout) |
2379 | return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); | 2402 | return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); |
2380 | 2403 | ||
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index dfdb5e643211..d5aed3bb3945 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -3411,7 +3411,7 @@ static int nl80211_send_station(struct sk_buff *msg, u32 portid, u32 seq, | |||
3411 | (u32)sinfo->rx_bytes)) | 3411 | (u32)sinfo->rx_bytes)) |
3412 | goto nla_put_failure; | 3412 | goto nla_put_failure; |
3413 | if ((sinfo->filled & (STATION_INFO_TX_BYTES | | 3413 | if ((sinfo->filled & (STATION_INFO_TX_BYTES | |
3414 | NL80211_STA_INFO_TX_BYTES64)) && | 3414 | STATION_INFO_TX_BYTES64)) && |
3415 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, | 3415 | nla_put_u32(msg, NL80211_STA_INFO_TX_BYTES, |
3416 | (u32)sinfo->tx_bytes)) | 3416 | (u32)sinfo->tx_bytes)) |
3417 | goto nla_put_failure; | 3417 | goto nla_put_failure; |
diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 8b5eddfba1e5..3ed35c345cae 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c | |||
@@ -231,6 +231,9 @@ void cfg80211_conn_work(struct work_struct *work) | |||
231 | mutex_lock(&rdev->sched_scan_mtx); | 231 | mutex_lock(&rdev->sched_scan_mtx); |
232 | 232 | ||
233 | list_for_each_entry(wdev, &rdev->wdev_list, list) { | 233 | list_for_each_entry(wdev, &rdev->wdev_list, list) { |
234 | if (!wdev->netdev) | ||
235 | continue; | ||
236 | |||
234 | wdev_lock(wdev); | 237 | wdev_lock(wdev); |
235 | if (!netif_running(wdev->netdev)) { | 238 | if (!netif_running(wdev->netdev)) { |
236 | wdev_unlock(wdev); | 239 | wdev_unlock(wdev); |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 23cea0f74336..ea970b8002a2 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -2557,11 +2557,12 @@ static void __xfrm_garbage_collect(struct net *net) | |||
2557 | } | 2557 | } |
2558 | } | 2558 | } |
2559 | 2559 | ||
2560 | static void xfrm_garbage_collect(struct net *net) | 2560 | void xfrm_garbage_collect(struct net *net) |
2561 | { | 2561 | { |
2562 | flow_cache_flush(); | 2562 | flow_cache_flush(); |
2563 | __xfrm_garbage_collect(net); | 2563 | __xfrm_garbage_collect(net); |
2564 | } | 2564 | } |
2565 | EXPORT_SYMBOL(xfrm_garbage_collect); | ||
2565 | 2566 | ||
2566 | static void xfrm_garbage_collect_deferred(struct net *net) | 2567 | static void xfrm_garbage_collect_deferred(struct net *net) |
2567 | { | 2568 | { |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index aa778748c565..3f565e495ac6 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -1681,6 +1681,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
1681 | 1681 | ||
1682 | out: | 1682 | out: |
1683 | xfrm_pol_put(xp); | 1683 | xfrm_pol_put(xp); |
1684 | if (delete && err == 0) | ||
1685 | xfrm_garbage_collect(net); | ||
1684 | return err; | 1686 | return err; |
1685 | } | 1687 | } |
1686 | 1688 | ||