diff options
Diffstat (limited to 'net')
43 files changed, 391 insertions, 223 deletions
diff --git a/net/802/mrp.c b/net/802/mrp.c index a4cc3229952a..e085bcc754f6 100644 --- a/net/802/mrp.c +++ b/net/802/mrp.c | |||
@@ -870,8 +870,12 @@ void mrp_uninit_applicant(struct net_device *dev, struct mrp_application *appl) | |||
870 | * all pending messages before the applicant is gone. | 870 | * all pending messages before the applicant is gone. |
871 | */ | 871 | */ |
872 | del_timer_sync(&app->join_timer); | 872 | del_timer_sync(&app->join_timer); |
873 | |||
874 | spin_lock(&app->lock); | ||
873 | mrp_mad_event(app, MRP_EVENT_TX); | 875 | mrp_mad_event(app, MRP_EVENT_TX); |
874 | mrp_pdu_queue(app); | 876 | mrp_pdu_queue(app); |
877 | spin_unlock(&app->lock); | ||
878 | |||
875 | mrp_queue_xmit(app); | 879 | mrp_queue_xmit(app); |
876 | 880 | ||
877 | dev_mc_del(dev, appl->group_address); | 881 | dev_mc_del(dev, appl->group_address); |
diff --git a/net/batman-adv/main.c b/net/batman-adv/main.c index 6277735cd89e..3e30a0f1b908 100644 --- a/net/batman-adv/main.c +++ b/net/batman-adv/main.c | |||
@@ -177,7 +177,13 @@ void batadv_mesh_free(struct net_device *soft_iface) | |||
177 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); | 177 | atomic_set(&bat_priv->mesh_state, BATADV_MESH_INACTIVE); |
178 | } | 178 | } |
179 | 179 | ||
180 | int batadv_is_my_mac(const uint8_t *addr) | 180 | /** |
181 | * batadv_is_my_mac - check if the given mac address belongs to any of the real | ||
182 | * interfaces in the current mesh | ||
183 | * @bat_priv: the bat priv with all the soft interface information | ||
184 | * @addr: the address to check | ||
185 | */ | ||
186 | int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr) | ||
181 | { | 187 | { |
182 | const struct batadv_hard_iface *hard_iface; | 188 | const struct batadv_hard_iface *hard_iface; |
183 | 189 | ||
@@ -186,6 +192,9 @@ int batadv_is_my_mac(const uint8_t *addr) | |||
186 | if (hard_iface->if_status != BATADV_IF_ACTIVE) | 192 | if (hard_iface->if_status != BATADV_IF_ACTIVE) |
187 | continue; | 193 | continue; |
188 | 194 | ||
195 | if (hard_iface->soft_iface != bat_priv->soft_iface) | ||
196 | continue; | ||
197 | |||
189 | if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) { | 198 | if (batadv_compare_eth(hard_iface->net_dev->dev_addr, addr)) { |
190 | rcu_read_unlock(); | 199 | rcu_read_unlock(); |
191 | return 1; | 200 | return 1; |
diff --git a/net/batman-adv/main.h b/net/batman-adv/main.h index f90f5bc8e426..59a0d6af15c8 100644 --- a/net/batman-adv/main.h +++ b/net/batman-adv/main.h | |||
@@ -165,7 +165,7 @@ extern struct workqueue_struct *batadv_event_workqueue; | |||
165 | 165 | ||
166 | int batadv_mesh_init(struct net_device *soft_iface); | 166 | int batadv_mesh_init(struct net_device *soft_iface); |
167 | void batadv_mesh_free(struct net_device *soft_iface); | 167 | void batadv_mesh_free(struct net_device *soft_iface); |
168 | int batadv_is_my_mac(const uint8_t *addr); | 168 | int batadv_is_my_mac(struct batadv_priv *bat_priv, const uint8_t *addr); |
169 | struct batadv_hard_iface * | 169 | struct batadv_hard_iface * |
170 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); | 170 | batadv_seq_print_text_primary_if_get(struct seq_file *seq); |
171 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, | 171 | int batadv_batman_skb_recv(struct sk_buff *skb, struct net_device *dev, |
diff --git a/net/batman-adv/network-coding.c b/net/batman-adv/network-coding.c index 6b9a54485314..f7c54305a918 100644 --- a/net/batman-adv/network-coding.c +++ b/net/batman-adv/network-coding.c | |||
@@ -1484,7 +1484,7 @@ void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv, | |||
1484 | { | 1484 | { |
1485 | struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); | 1485 | struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); |
1486 | 1486 | ||
1487 | if (batadv_is_my_mac(ethhdr->h_dest)) | 1487 | if (batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
1488 | return; | 1488 | return; |
1489 | 1489 | ||
1490 | /* Set data pointer to MAC header to mimic packets from our tx path */ | 1490 | /* Set data pointer to MAC header to mimic packets from our tx path */ |
@@ -1496,6 +1496,7 @@ void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv, | |||
1496 | /** | 1496 | /** |
1497 | * batadv_nc_skb_decode_packet - decode given skb using the decode data stored | 1497 | * batadv_nc_skb_decode_packet - decode given skb using the decode data stored |
1498 | * in nc_packet | 1498 | * in nc_packet |
1499 | * @bat_priv: the bat priv with all the soft interface information | ||
1499 | * @skb: unicast skb to decode | 1500 | * @skb: unicast skb to decode |
1500 | * @nc_packet: decode data needed to decode the skb | 1501 | * @nc_packet: decode data needed to decode the skb |
1501 | * | 1502 | * |
@@ -1503,7 +1504,7 @@ void batadv_nc_skb_store_sniffed_unicast(struct batadv_priv *bat_priv, | |||
1503 | * in case of an error. | 1504 | * in case of an error. |
1504 | */ | 1505 | */ |
1505 | static struct batadv_unicast_packet * | 1506 | static struct batadv_unicast_packet * |
1506 | batadv_nc_skb_decode_packet(struct sk_buff *skb, | 1507 | batadv_nc_skb_decode_packet(struct batadv_priv *bat_priv, struct sk_buff *skb, |
1507 | struct batadv_nc_packet *nc_packet) | 1508 | struct batadv_nc_packet *nc_packet) |
1508 | { | 1509 | { |
1509 | const int h_size = sizeof(struct batadv_unicast_packet); | 1510 | const int h_size = sizeof(struct batadv_unicast_packet); |
@@ -1537,7 +1538,7 @@ batadv_nc_skb_decode_packet(struct sk_buff *skb, | |||
1537 | /* Select the correct unicast header information based on the location | 1538 | /* Select the correct unicast header information based on the location |
1538 | * of our mac address in the coded_packet header | 1539 | * of our mac address in the coded_packet header |
1539 | */ | 1540 | */ |
1540 | if (batadv_is_my_mac(coded_packet_tmp.second_dest)) { | 1541 | if (batadv_is_my_mac(bat_priv, coded_packet_tmp.second_dest)) { |
1541 | /* If we are the second destination the packet was overheard, | 1542 | /* If we are the second destination the packet was overheard, |
1542 | * so the Ethernet address must be copied to h_dest and | 1543 | * so the Ethernet address must be copied to h_dest and |
1543 | * pkt_type changed from PACKET_OTHERHOST to PACKET_HOST | 1544 | * pkt_type changed from PACKET_OTHERHOST to PACKET_HOST |
@@ -1608,7 +1609,7 @@ batadv_nc_find_decoding_packet(struct batadv_priv *bat_priv, | |||
1608 | 1609 | ||
1609 | /* Select the correct packet id based on the location of our mac-addr */ | 1610 | /* Select the correct packet id based on the location of our mac-addr */ |
1610 | dest = ethhdr->h_source; | 1611 | dest = ethhdr->h_source; |
1611 | if (!batadv_is_my_mac(coded->second_dest)) { | 1612 | if (!batadv_is_my_mac(bat_priv, coded->second_dest)) { |
1612 | source = coded->second_source; | 1613 | source = coded->second_source; |
1613 | packet_id = coded->second_crc; | 1614 | packet_id = coded->second_crc; |
1614 | } else { | 1615 | } else { |
@@ -1675,12 +1676,12 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb, | |||
1675 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | 1676 | ethhdr = (struct ethhdr *)skb_mac_header(skb); |
1676 | 1677 | ||
1677 | /* Verify frame is destined for us */ | 1678 | /* Verify frame is destined for us */ |
1678 | if (!batadv_is_my_mac(ethhdr->h_dest) && | 1679 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest) && |
1679 | !batadv_is_my_mac(coded_packet->second_dest)) | 1680 | !batadv_is_my_mac(bat_priv, coded_packet->second_dest)) |
1680 | return NET_RX_DROP; | 1681 | return NET_RX_DROP; |
1681 | 1682 | ||
1682 | /* Update stat counter */ | 1683 | /* Update stat counter */ |
1683 | if (batadv_is_my_mac(coded_packet->second_dest)) | 1684 | if (batadv_is_my_mac(bat_priv, coded_packet->second_dest)) |
1684 | batadv_inc_counter(bat_priv, BATADV_CNT_NC_SNIFFED); | 1685 | batadv_inc_counter(bat_priv, BATADV_CNT_NC_SNIFFED); |
1685 | 1686 | ||
1686 | nc_packet = batadv_nc_find_decoding_packet(bat_priv, ethhdr, | 1687 | nc_packet = batadv_nc_find_decoding_packet(bat_priv, ethhdr, |
@@ -1698,7 +1699,7 @@ static int batadv_nc_recv_coded_packet(struct sk_buff *skb, | |||
1698 | goto free_nc_packet; | 1699 | goto free_nc_packet; |
1699 | 1700 | ||
1700 | /* Decode the packet */ | 1701 | /* Decode the packet */ |
1701 | unicast_packet = batadv_nc_skb_decode_packet(skb, nc_packet); | 1702 | unicast_packet = batadv_nc_skb_decode_packet(bat_priv, skb, nc_packet); |
1702 | if (!unicast_packet) { | 1703 | if (!unicast_packet) { |
1703 | batadv_inc_counter(bat_priv, BATADV_CNT_NC_DECODE_FAILED); | 1704 | batadv_inc_counter(bat_priv, BATADV_CNT_NC_DECODE_FAILED); |
1704 | goto free_nc_packet; | 1705 | goto free_nc_packet; |
diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c index 8f88967ff14b..2f1f88923df8 100644 --- a/net/batman-adv/routing.c +++ b/net/batman-adv/routing.c | |||
@@ -403,7 +403,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, | |||
403 | goto out; | 403 | goto out; |
404 | 404 | ||
405 | /* not for me */ | 405 | /* not for me */ |
406 | if (!batadv_is_my_mac(ethhdr->h_dest)) | 406 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
407 | goto out; | 407 | goto out; |
408 | 408 | ||
409 | icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; | 409 | icmp_packet = (struct batadv_icmp_packet_rr *)skb->data; |
@@ -417,7 +417,7 @@ int batadv_recv_icmp_packet(struct sk_buff *skb, | |||
417 | } | 417 | } |
418 | 418 | ||
419 | /* packet for me */ | 419 | /* packet for me */ |
420 | if (batadv_is_my_mac(icmp_packet->dst)) | 420 | if (batadv_is_my_mac(bat_priv, icmp_packet->dst)) |
421 | return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); | 421 | return batadv_recv_my_icmp_packet(bat_priv, skb, hdr_size); |
422 | 422 | ||
423 | /* TTL exceeded */ | 423 | /* TTL exceeded */ |
@@ -551,6 +551,7 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, | |||
551 | 551 | ||
552 | /** | 552 | /** |
553 | * batadv_check_unicast_packet - Check for malformed unicast packets | 553 | * batadv_check_unicast_packet - Check for malformed unicast packets |
554 | * @bat_priv: the bat priv with all the soft interface information | ||
554 | * @skb: packet to check | 555 | * @skb: packet to check |
555 | * @hdr_size: size of header to pull | 556 | * @hdr_size: size of header to pull |
556 | * | 557 | * |
@@ -559,7 +560,8 @@ batadv_find_ifalter_router(struct batadv_orig_node *primary_orig, | |||
559 | * reason: -ENODATA for bad header, -EBADR for broadcast destination or source, | 560 | * reason: -ENODATA for bad header, -EBADR for broadcast destination or source, |
560 | * and -EREMOTE for non-local (other host) destination. | 561 | * and -EREMOTE for non-local (other host) destination. |
561 | */ | 562 | */ |
562 | static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) | 563 | static int batadv_check_unicast_packet(struct batadv_priv *bat_priv, |
564 | struct sk_buff *skb, int hdr_size) | ||
563 | { | 565 | { |
564 | struct ethhdr *ethhdr; | 566 | struct ethhdr *ethhdr; |
565 | 567 | ||
@@ -578,7 +580,7 @@ static int batadv_check_unicast_packet(struct sk_buff *skb, int hdr_size) | |||
578 | return -EBADR; | 580 | return -EBADR; |
579 | 581 | ||
580 | /* not for me */ | 582 | /* not for me */ |
581 | if (!batadv_is_my_mac(ethhdr->h_dest)) | 583 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
582 | return -EREMOTE; | 584 | return -EREMOTE; |
583 | 585 | ||
584 | return 0; | 586 | return 0; |
@@ -593,7 +595,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) | |||
593 | char tt_flag; | 595 | char tt_flag; |
594 | size_t packet_size; | 596 | size_t packet_size; |
595 | 597 | ||
596 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) | 598 | if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) |
597 | return NET_RX_DROP; | 599 | return NET_RX_DROP; |
598 | 600 | ||
599 | /* I could need to modify it */ | 601 | /* I could need to modify it */ |
@@ -625,7 +627,7 @@ int batadv_recv_tt_query(struct sk_buff *skb, struct batadv_hard_iface *recv_if) | |||
625 | case BATADV_TT_RESPONSE: | 627 | case BATADV_TT_RESPONSE: |
626 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX); | 628 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_RESPONSE_RX); |
627 | 629 | ||
628 | if (batadv_is_my_mac(tt_query->dst)) { | 630 | if (batadv_is_my_mac(bat_priv, tt_query->dst)) { |
629 | /* packet needs to be linearized to access the TT | 631 | /* packet needs to be linearized to access the TT |
630 | * changes | 632 | * changes |
631 | */ | 633 | */ |
@@ -668,14 +670,15 @@ int batadv_recv_roam_adv(struct sk_buff *skb, struct batadv_hard_iface *recv_if) | |||
668 | struct batadv_roam_adv_packet *roam_adv_packet; | 670 | struct batadv_roam_adv_packet *roam_adv_packet; |
669 | struct batadv_orig_node *orig_node; | 671 | struct batadv_orig_node *orig_node; |
670 | 672 | ||
671 | if (batadv_check_unicast_packet(skb, sizeof(*roam_adv_packet)) < 0) | 673 | if (batadv_check_unicast_packet(bat_priv, skb, |
674 | sizeof(*roam_adv_packet)) < 0) | ||
672 | goto out; | 675 | goto out; |
673 | 676 | ||
674 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); | 677 | batadv_inc_counter(bat_priv, BATADV_CNT_TT_ROAM_ADV_RX); |
675 | 678 | ||
676 | roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data; | 679 | roam_adv_packet = (struct batadv_roam_adv_packet *)skb->data; |
677 | 680 | ||
678 | if (!batadv_is_my_mac(roam_adv_packet->dst)) | 681 | if (!batadv_is_my_mac(bat_priv, roam_adv_packet->dst)) |
679 | return batadv_route_unicast_packet(skb, recv_if); | 682 | return batadv_route_unicast_packet(skb, recv_if); |
680 | 683 | ||
681 | /* check if it is a backbone gateway. we don't accept | 684 | /* check if it is a backbone gateway. we don't accept |
@@ -981,7 +984,7 @@ static int batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, | |||
981 | * last time) the packet had an updated information or not | 984 | * last time) the packet had an updated information or not |
982 | */ | 985 | */ |
983 | curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); | 986 | curr_ttvn = (uint8_t)atomic_read(&bat_priv->tt.vn); |
984 | if (!batadv_is_my_mac(unicast_packet->dest)) { | 987 | if (!batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
985 | orig_node = batadv_orig_hash_find(bat_priv, | 988 | orig_node = batadv_orig_hash_find(bat_priv, |
986 | unicast_packet->dest); | 989 | unicast_packet->dest); |
987 | /* if it is not possible to find the orig_node representing the | 990 | /* if it is not possible to find the orig_node representing the |
@@ -1059,7 +1062,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
1059 | hdr_size = sizeof(*unicast_4addr_packet); | 1062 | hdr_size = sizeof(*unicast_4addr_packet); |
1060 | 1063 | ||
1061 | /* function returns -EREMOTE for promiscuous packets */ | 1064 | /* function returns -EREMOTE for promiscuous packets */ |
1062 | check = batadv_check_unicast_packet(skb, hdr_size); | 1065 | check = batadv_check_unicast_packet(bat_priv, skb, hdr_size); |
1063 | 1066 | ||
1064 | /* Even though the packet is not for us, we might save it to use for | 1067 | /* Even though the packet is not for us, we might save it to use for |
1065 | * decoding a later received coded packet | 1068 | * decoding a later received coded packet |
@@ -1074,7 +1077,7 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, | |||
1074 | return NET_RX_DROP; | 1077 | return NET_RX_DROP; |
1075 | 1078 | ||
1076 | /* packet for me */ | 1079 | /* packet for me */ |
1077 | if (batadv_is_my_mac(unicast_packet->dest)) { | 1080 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
1078 | if (is4addr) { | 1081 | if (is4addr) { |
1079 | batadv_dat_inc_counter(bat_priv, | 1082 | batadv_dat_inc_counter(bat_priv, |
1080 | unicast_4addr_packet->subtype); | 1083 | unicast_4addr_packet->subtype); |
@@ -1111,7 +1114,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, | |||
1111 | struct sk_buff *new_skb = NULL; | 1114 | struct sk_buff *new_skb = NULL; |
1112 | int ret; | 1115 | int ret; |
1113 | 1116 | ||
1114 | if (batadv_check_unicast_packet(skb, hdr_size) < 0) | 1117 | if (batadv_check_unicast_packet(bat_priv, skb, hdr_size) < 0) |
1115 | return NET_RX_DROP; | 1118 | return NET_RX_DROP; |
1116 | 1119 | ||
1117 | if (!batadv_check_unicast_ttvn(bat_priv, skb)) | 1120 | if (!batadv_check_unicast_ttvn(bat_priv, skb)) |
@@ -1120,7 +1123,7 @@ int batadv_recv_ucast_frag_packet(struct sk_buff *skb, | |||
1120 | unicast_packet = (struct batadv_unicast_frag_packet *)skb->data; | 1123 | unicast_packet = (struct batadv_unicast_frag_packet *)skb->data; |
1121 | 1124 | ||
1122 | /* packet for me */ | 1125 | /* packet for me */ |
1123 | if (batadv_is_my_mac(unicast_packet->dest)) { | 1126 | if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { |
1124 | ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); | 1127 | ret = batadv_frag_reassemble_skb(skb, bat_priv, &new_skb); |
1125 | 1128 | ||
1126 | if (ret == NET_RX_DROP) | 1129 | if (ret == NET_RX_DROP) |
@@ -1174,13 +1177,13 @@ int batadv_recv_bcast_packet(struct sk_buff *skb, | |||
1174 | goto out; | 1177 | goto out; |
1175 | 1178 | ||
1176 | /* ignore broadcasts sent by myself */ | 1179 | /* ignore broadcasts sent by myself */ |
1177 | if (batadv_is_my_mac(ethhdr->h_source)) | 1180 | if (batadv_is_my_mac(bat_priv, ethhdr->h_source)) |
1178 | goto out; | 1181 | goto out; |
1179 | 1182 | ||
1180 | bcast_packet = (struct batadv_bcast_packet *)skb->data; | 1183 | bcast_packet = (struct batadv_bcast_packet *)skb->data; |
1181 | 1184 | ||
1182 | /* ignore broadcasts originated by myself */ | 1185 | /* ignore broadcasts originated by myself */ |
1183 | if (batadv_is_my_mac(bcast_packet->orig)) | 1186 | if (batadv_is_my_mac(bat_priv, bcast_packet->orig)) |
1184 | goto out; | 1187 | goto out; |
1185 | 1188 | ||
1186 | if (bcast_packet->header.ttl < 2) | 1189 | if (bcast_packet->header.ttl < 2) |
@@ -1266,14 +1269,14 @@ int batadv_recv_vis_packet(struct sk_buff *skb, | |||
1266 | ethhdr = (struct ethhdr *)skb_mac_header(skb); | 1269 | ethhdr = (struct ethhdr *)skb_mac_header(skb); |
1267 | 1270 | ||
1268 | /* not for me */ | 1271 | /* not for me */ |
1269 | if (!batadv_is_my_mac(ethhdr->h_dest)) | 1272 | if (!batadv_is_my_mac(bat_priv, ethhdr->h_dest)) |
1270 | return NET_RX_DROP; | 1273 | return NET_RX_DROP; |
1271 | 1274 | ||
1272 | /* ignore own packets */ | 1275 | /* ignore own packets */ |
1273 | if (batadv_is_my_mac(vis_packet->vis_orig)) | 1276 | if (batadv_is_my_mac(bat_priv, vis_packet->vis_orig)) |
1274 | return NET_RX_DROP; | 1277 | return NET_RX_DROP; |
1275 | 1278 | ||
1276 | if (batadv_is_my_mac(vis_packet->sender_orig)) | 1279 | if (batadv_is_my_mac(bat_priv, vis_packet->sender_orig)) |
1277 | return NET_RX_DROP; | 1280 | return NET_RX_DROP; |
1278 | 1281 | ||
1279 | switch (vis_packet->vis_type) { | 1282 | switch (vis_packet->vis_type) { |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index 932232087449..5e89deeb9542 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -1940,7 +1940,7 @@ out: | |||
1940 | bool batadv_send_tt_response(struct batadv_priv *bat_priv, | 1940 | bool batadv_send_tt_response(struct batadv_priv *bat_priv, |
1941 | struct batadv_tt_query_packet *tt_request) | 1941 | struct batadv_tt_query_packet *tt_request) |
1942 | { | 1942 | { |
1943 | if (batadv_is_my_mac(tt_request->dst)) { | 1943 | if (batadv_is_my_mac(bat_priv, tt_request->dst)) { |
1944 | /* don't answer backbone gws! */ | 1944 | /* don't answer backbone gws! */ |
1945 | if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) | 1945 | if (batadv_bla_is_backbone_gw_orig(bat_priv, tt_request->src)) |
1946 | return true; | 1946 | return true; |
diff --git a/net/batman-adv/vis.c b/net/batman-adv/vis.c index 962ccf3b8382..1625e5793a89 100644 --- a/net/batman-adv/vis.c +++ b/net/batman-adv/vis.c | |||
@@ -477,7 +477,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, | |||
477 | 477 | ||
478 | /* Are we the target for this VIS packet? */ | 478 | /* Are we the target for this VIS packet? */ |
479 | if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && | 479 | if (vis_server == BATADV_VIS_TYPE_SERVER_SYNC && |
480 | batadv_is_my_mac(vis_packet->target_orig)) | 480 | batadv_is_my_mac(bat_priv, vis_packet->target_orig)) |
481 | are_target = 1; | 481 | are_target = 1; |
482 | 482 | ||
483 | spin_lock_bh(&bat_priv->vis.hash_lock); | 483 | spin_lock_bh(&bat_priv->vis.hash_lock); |
@@ -496,7 +496,7 @@ void batadv_receive_client_update_packet(struct batadv_priv *bat_priv, | |||
496 | batadv_send_list_add(bat_priv, info); | 496 | batadv_send_list_add(bat_priv, info); |
497 | 497 | ||
498 | /* ... we're not the recipient (and thus need to forward). */ | 498 | /* ... we're not the recipient (and thus need to forward). */ |
499 | } else if (!batadv_is_my_mac(packet->target_orig)) { | 499 | } else if (!batadv_is_my_mac(bat_priv, packet->target_orig)) { |
500 | batadv_send_list_add(bat_priv, info); | 500 | batadv_send_list_add(bat_priv, info); |
501 | } | 501 | } |
502 | 502 | ||
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index f17fcb3097c2..4cdba60926ff 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -67,7 +67,8 @@ void br_port_carrier_check(struct net_bridge_port *p) | |||
67 | struct net_device *dev = p->dev; | 67 | struct net_device *dev = p->dev; |
68 | struct net_bridge *br = p->br; | 68 | struct net_bridge *br = p->br; |
69 | 69 | ||
70 | if (netif_running(dev) && netif_oper_up(dev)) | 70 | if (!(p->flags & BR_ADMIN_COST) && |
71 | netif_running(dev) && netif_oper_up(dev)) | ||
71 | p->path_cost = port_cost(dev); | 72 | p->path_cost = port_cost(dev); |
72 | 73 | ||
73 | if (!netif_running(br->dev)) | 74 | if (!netif_running(br->dev)) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 3cbf5beb3d4b..d2c043a857b6 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -156,6 +156,7 @@ struct net_bridge_port | |||
156 | #define BR_BPDU_GUARD 0x00000002 | 156 | #define BR_BPDU_GUARD 0x00000002 |
157 | #define BR_ROOT_BLOCK 0x00000004 | 157 | #define BR_ROOT_BLOCK 0x00000004 |
158 | #define BR_MULTICAST_FAST_LEAVE 0x00000008 | 158 | #define BR_MULTICAST_FAST_LEAVE 0x00000008 |
159 | #define BR_ADMIN_COST 0x00000010 | ||
159 | 160 | ||
160 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING | 161 | #ifdef CONFIG_BRIDGE_IGMP_SNOOPING |
161 | u32 multicast_startup_queries_sent; | 162 | u32 multicast_startup_queries_sent; |
diff --git a/net/bridge/br_stp_if.c b/net/bridge/br_stp_if.c index 0bdb4ebd362b..d45e760141bb 100644 --- a/net/bridge/br_stp_if.c +++ b/net/bridge/br_stp_if.c | |||
@@ -288,6 +288,7 @@ int br_stp_set_path_cost(struct net_bridge_port *p, unsigned long path_cost) | |||
288 | path_cost > BR_MAX_PATH_COST) | 288 | path_cost > BR_MAX_PATH_COST) |
289 | return -ERANGE; | 289 | return -ERANGE; |
290 | 290 | ||
291 | p->flags |= BR_ADMIN_COST; | ||
291 | p->path_cost = path_cost; | 292 | p->path_cost = path_cost; |
292 | br_configuration_update(p->br); | 293 | br_configuration_update(p->br); |
293 | br_port_state_selection(p->br); | 294 | br_port_state_selection(p->br); |
diff --git a/net/can/gw.c b/net/can/gw.c index 2dc619db805a..3ee690e8c7d3 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -466,7 +466,7 @@ static int cgw_notifier(struct notifier_block *nb, | |||
466 | if (gwj->src.dev == dev || gwj->dst.dev == dev) { | 466 | if (gwj->src.dev == dev || gwj->dst.dev == dev) { |
467 | hlist_del(&gwj->list); | 467 | hlist_del(&gwj->list); |
468 | cgw_unregister_filter(gwj); | 468 | cgw_unregister_filter(gwj); |
469 | kfree(gwj); | 469 | kmem_cache_free(cgw_cache, gwj); |
470 | } | 470 | } |
471 | } | 471 | } |
472 | } | 472 | } |
@@ -863,7 +863,7 @@ static void cgw_remove_all_jobs(void) | |||
863 | hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) { | 863 | hlist_for_each_entry_safe(gwj, nx, &cgw_list, list) { |
864 | hlist_del(&gwj->list); | 864 | hlist_del(&gwj->list); |
865 | cgw_unregister_filter(gwj); | 865 | cgw_unregister_filter(gwj); |
866 | kfree(gwj); | 866 | kmem_cache_free(cgw_cache, gwj); |
867 | } | 867 | } |
868 | } | 868 | } |
869 | 869 | ||
@@ -919,7 +919,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
919 | 919 | ||
920 | hlist_del(&gwj->list); | 920 | hlist_del(&gwj->list); |
921 | cgw_unregister_filter(gwj); | 921 | cgw_unregister_filter(gwj); |
922 | kfree(gwj); | 922 | kmem_cache_free(cgw_cache, gwj); |
923 | err = 0; | 923 | err = 0; |
924 | break; | 924 | break; |
925 | } | 925 | } |
diff --git a/net/core/dev.c b/net/core/dev.c index 8a3cb2c50fbf..9e26b8d9eafe 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2146,6 +2146,9 @@ static void skb_warn_bad_offload(const struct sk_buff *skb) | |||
2146 | struct net_device *dev = skb->dev; | 2146 | struct net_device *dev = skb->dev; |
2147 | const char *driver = ""; | 2147 | const char *driver = ""; |
2148 | 2148 | ||
2149 | if (!net_ratelimit()) | ||
2150 | return; | ||
2151 | |||
2149 | if (dev && dev->dev.parent) | 2152 | if (dev && dev->dev.parent) |
2150 | driver = dev_driver_string(dev->dev.parent); | 2153 | driver = dev_driver_string(dev->dev.parent); |
2151 | 2154 | ||
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 589d0abb34a0..18af08a73f0a 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -1046,7 +1046,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1046 | rcu_read_lock(); | 1046 | rcu_read_lock(); |
1047 | cb->seq = net->dev_base_seq; | 1047 | cb->seq = net->dev_base_seq; |
1048 | 1048 | ||
1049 | if (nlmsg_parse(cb->nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, | 1049 | if (nlmsg_parse(cb->nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, |
1050 | ifla_policy) >= 0) { | 1050 | ifla_policy) >= 0) { |
1051 | 1051 | ||
1052 | if (tb[IFLA_EXT_MASK]) | 1052 | if (tb[IFLA_EXT_MASK]) |
@@ -1896,7 +1896,7 @@ static u16 rtnl_calcit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1896 | u32 ext_filter_mask = 0; | 1896 | u32 ext_filter_mask = 0; |
1897 | u16 min_ifinfo_dump_size = 0; | 1897 | u16 min_ifinfo_dump_size = 0; |
1898 | 1898 | ||
1899 | if (nlmsg_parse(nlh, sizeof(struct rtgenmsg), tb, IFLA_MAX, | 1899 | if (nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, IFLA_MAX, |
1900 | ifla_policy) >= 0) { | 1900 | ifla_policy) >= 0) { |
1901 | if (tb[IFLA_EXT_MASK]) | 1901 | if (tb[IFLA_EXT_MASK]) |
1902 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); | 1902 | ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); |
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 2759dfd576ae..dfc39d4d48b7 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c | |||
@@ -587,13 +587,16 @@ static void check_lifetime(struct work_struct *work) | |||
587 | { | 587 | { |
588 | unsigned long now, next, next_sec, next_sched; | 588 | unsigned long now, next, next_sec, next_sched; |
589 | struct in_ifaddr *ifa; | 589 | struct in_ifaddr *ifa; |
590 | struct hlist_node *n; | ||
590 | int i; | 591 | int i; |
591 | 592 | ||
592 | now = jiffies; | 593 | now = jiffies; |
593 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); | 594 | next = round_jiffies_up(now + ADDR_CHECK_FREQUENCY); |
594 | 595 | ||
595 | rcu_read_lock(); | ||
596 | for (i = 0; i < IN4_ADDR_HSIZE; i++) { | 596 | for (i = 0; i < IN4_ADDR_HSIZE; i++) { |
597 | bool change_needed = false; | ||
598 | |||
599 | rcu_read_lock(); | ||
597 | hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) { | 600 | hlist_for_each_entry_rcu(ifa, &inet_addr_lst[i], hash) { |
598 | unsigned long age; | 601 | unsigned long age; |
599 | 602 | ||
@@ -606,16 +609,7 @@ static void check_lifetime(struct work_struct *work) | |||
606 | 609 | ||
607 | if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && | 610 | if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && |
608 | age >= ifa->ifa_valid_lft) { | 611 | age >= ifa->ifa_valid_lft) { |
609 | struct in_ifaddr **ifap ; | 612 | change_needed = true; |
610 | |||
611 | rtnl_lock(); | ||
612 | for (ifap = &ifa->ifa_dev->ifa_list; | ||
613 | *ifap != NULL; ifap = &ifa->ifa_next) { | ||
614 | if (*ifap == ifa) | ||
615 | inet_del_ifa(ifa->ifa_dev, | ||
616 | ifap, 1); | ||
617 | } | ||
618 | rtnl_unlock(); | ||
619 | } else if (ifa->ifa_preferred_lft == | 613 | } else if (ifa->ifa_preferred_lft == |
620 | INFINITY_LIFE_TIME) { | 614 | INFINITY_LIFE_TIME) { |
621 | continue; | 615 | continue; |
@@ -625,10 +619,8 @@ static void check_lifetime(struct work_struct *work) | |||
625 | next = ifa->ifa_tstamp + | 619 | next = ifa->ifa_tstamp + |
626 | ifa->ifa_valid_lft * HZ; | 620 | ifa->ifa_valid_lft * HZ; |
627 | 621 | ||
628 | if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) { | 622 | if (!(ifa->ifa_flags & IFA_F_DEPRECATED)) |
629 | ifa->ifa_flags |= IFA_F_DEPRECATED; | 623 | change_needed = true; |
630 | rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); | ||
631 | } | ||
632 | } else if (time_before(ifa->ifa_tstamp + | 624 | } else if (time_before(ifa->ifa_tstamp + |
633 | ifa->ifa_preferred_lft * HZ, | 625 | ifa->ifa_preferred_lft * HZ, |
634 | next)) { | 626 | next)) { |
@@ -636,8 +628,42 @@ static void check_lifetime(struct work_struct *work) | |||
636 | ifa->ifa_preferred_lft * HZ; | 628 | ifa->ifa_preferred_lft * HZ; |
637 | } | 629 | } |
638 | } | 630 | } |
631 | rcu_read_unlock(); | ||
632 | if (!change_needed) | ||
633 | continue; | ||
634 | rtnl_lock(); | ||
635 | hlist_for_each_entry_safe(ifa, n, &inet_addr_lst[i], hash) { | ||
636 | unsigned long age; | ||
637 | |||
638 | if (ifa->ifa_flags & IFA_F_PERMANENT) | ||
639 | continue; | ||
640 | |||
641 | /* We try to batch several events at once. */ | ||
642 | age = (now - ifa->ifa_tstamp + | ||
643 | ADDRCONF_TIMER_FUZZ_MINUS) / HZ; | ||
644 | |||
645 | if (ifa->ifa_valid_lft != INFINITY_LIFE_TIME && | ||
646 | age >= ifa->ifa_valid_lft) { | ||
647 | struct in_ifaddr **ifap; | ||
648 | |||
649 | for (ifap = &ifa->ifa_dev->ifa_list; | ||
650 | *ifap != NULL; ifap = &(*ifap)->ifa_next) { | ||
651 | if (*ifap == ifa) { | ||
652 | inet_del_ifa(ifa->ifa_dev, | ||
653 | ifap, 1); | ||
654 | break; | ||
655 | } | ||
656 | } | ||
657 | } else if (ifa->ifa_preferred_lft != | ||
658 | INFINITY_LIFE_TIME && | ||
659 | age >= ifa->ifa_preferred_lft && | ||
660 | !(ifa->ifa_flags & IFA_F_DEPRECATED)) { | ||
661 | ifa->ifa_flags |= IFA_F_DEPRECATED; | ||
662 | rtmsg_ifa(RTM_NEWADDR, ifa, NULL, 0); | ||
663 | } | ||
664 | } | ||
665 | rtnl_unlock(); | ||
639 | } | 666 | } |
640 | rcu_read_unlock(); | ||
641 | 667 | ||
642 | next_sec = round_jiffies_up(next); | 668 | next_sec = round_jiffies_up(next); |
643 | next_sched = next; | 669 | next_sched = next; |
@@ -804,6 +830,8 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
804 | return -EEXIST; | 830 | return -EEXIST; |
805 | ifa = ifa_existing; | 831 | ifa = ifa_existing; |
806 | set_ifa_lifetime(ifa, valid_lft, prefered_lft); | 832 | set_ifa_lifetime(ifa, valid_lft, prefered_lft); |
833 | cancel_delayed_work(&check_lifetime_work); | ||
834 | schedule_delayed_work(&check_lifetime_work, 0); | ||
807 | rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); | 835 | rtmsg_ifa(RTM_NEWADDR, ifa, nlh, NETLINK_CB(skb).portid); |
808 | blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); | 836 | blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa); |
809 | } | 837 | } |
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 3b4f0cd2e63e..4cfe34d4cc96 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
@@ -139,8 +139,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
139 | 139 | ||
140 | /* skb is pure payload to encrypt */ | 140 | /* skb is pure payload to encrypt */ |
141 | 141 | ||
142 | err = -ENOMEM; | ||
143 | |||
144 | esp = x->data; | 142 | esp = x->data; |
145 | aead = esp->aead; | 143 | aead = esp->aead; |
146 | alen = crypto_aead_authsize(aead); | 144 | alen = crypto_aead_authsize(aead); |
@@ -176,8 +174,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) | |||
176 | } | 174 | } |
177 | 175 | ||
178 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); | 176 | tmp = esp_alloc_tmp(aead, nfrags + sglists, seqhilen); |
179 | if (!tmp) | 177 | if (!tmp) { |
178 | err = -ENOMEM; | ||
180 | goto error; | 179 | goto error; |
180 | } | ||
181 | 181 | ||
182 | seqhi = esp_tmp_seqhi(tmp); | 182 | seqhi = esp_tmp_seqhi(tmp); |
183 | iv = esp_tmp_iv(aead, tmp, seqhilen); | 183 | iv = esp_tmp_iv(aead, tmp, seqhilen); |
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c index 938520668b2f..b66910aaef4d 100644 --- a/net/ipv4/ip_fragment.c +++ b/net/ipv4/ip_fragment.c | |||
@@ -219,8 +219,7 @@ static void ip_expire(unsigned long arg) | |||
219 | if (!head->dev) | 219 | if (!head->dev) |
220 | goto out_rcu_unlock; | 220 | goto out_rcu_unlock; |
221 | 221 | ||
222 | /* skb dst is stale, drop it, and perform route lookup again */ | 222 | /* skb has no dst, perform route lookup again */ |
223 | skb_dst_drop(head); | ||
224 | iph = ip_hdr(head); | 223 | iph = ip_hdr(head); |
225 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, | 224 | err = ip_route_input_noref(head, iph->daddr, iph->saddr, |
226 | iph->tos, head->dev); | 225 | iph->tos, head->dev); |
@@ -494,9 +493,16 @@ found: | |||
494 | qp->q.max_size = skb->len + ihl; | 493 | qp->q.max_size = skb->len + ihl; |
495 | 494 | ||
496 | if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && | 495 | if (qp->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && |
497 | qp->q.meat == qp->q.len) | 496 | qp->q.meat == qp->q.len) { |
498 | return ip_frag_reasm(qp, prev, dev); | 497 | unsigned long orefdst = skb->_skb_refdst; |
499 | 498 | ||
499 | skb->_skb_refdst = 0UL; | ||
500 | err = ip_frag_reasm(qp, prev, dev); | ||
501 | skb->_skb_refdst = orefdst; | ||
502 | return err; | ||
503 | } | ||
504 | |||
505 | skb_dst_drop(skb); | ||
500 | inet_frag_lru_move(&qp->q); | 506 | inet_frag_lru_move(&qp->q); |
501 | return -EINPROGRESS; | 507 | return -EINPROGRESS; |
502 | 508 | ||
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c index c30130062cd6..c49dcd0284a0 100644 --- a/net/ipv4/netfilter/ipt_rpfilter.c +++ b/net/ipv4/netfilter/ipt_rpfilter.c | |||
@@ -66,6 +66,12 @@ static bool rpfilter_lookup_reverse(struct flowi4 *fl4, | |||
66 | return dev_match; | 66 | return dev_match; |
67 | } | 67 | } |
68 | 68 | ||
69 | static bool rpfilter_is_local(const struct sk_buff *skb) | ||
70 | { | ||
71 | const struct rtable *rt = skb_rtable(skb); | ||
72 | return rt && (rt->rt_flags & RTCF_LOCAL); | ||
73 | } | ||
74 | |||
69 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | 75 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) |
70 | { | 76 | { |
71 | const struct xt_rpfilter_info *info; | 77 | const struct xt_rpfilter_info *info; |
@@ -76,7 +82,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
76 | info = par->matchinfo; | 82 | info = par->matchinfo; |
77 | invert = info->flags & XT_RPFILTER_INVERT; | 83 | invert = info->flags & XT_RPFILTER_INVERT; |
78 | 84 | ||
79 | if (par->in->flags & IFF_LOOPBACK) | 85 | if (rpfilter_is_local(skb)) |
80 | return true ^ invert; | 86 | return true ^ invert; |
81 | 87 | ||
82 | iph = ip_hdr(skb); | 88 | iph = ip_hdr(skb); |
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 7f4a5cb8f8d0..b05c96e7af8b 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -348,8 +348,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb, | |||
348 | * hasn't changed since we received the original syn, but I see | 348 | * hasn't changed since we received the original syn, but I see |
349 | * no easy way to do this. | 349 | * no easy way to do this. |
350 | */ | 350 | */ |
351 | flowi4_init_output(&fl4, 0, sk->sk_mark, RT_CONN_FLAGS(sk), | 351 | flowi4_init_output(&fl4, sk->sk_bound_dev_if, sk->sk_mark, |
352 | RT_SCOPE_UNIVERSE, IPPROTO_TCP, | 352 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, IPPROTO_TCP, |
353 | inet_sk_flowi_flags(sk), | 353 | inet_sk_flowi_flags(sk), |
354 | (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, | 354 | (opt && opt->srr) ? opt->faddr : ireq->rmt_addr, |
355 | ireq->loc_addr, th->source, th->dest); | 355 | ireq->loc_addr, th->source, th->dest); |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 6d9ca35f0c35..aafd052865ba 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -111,6 +111,7 @@ int sysctl_tcp_early_retrans __read_mostly = 3; | |||
111 | #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ | 111 | #define FLAG_SND_UNA_ADVANCED 0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */ |
112 | #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ | 112 | #define FLAG_DSACKING_ACK 0x800 /* SACK blocks contained D-SACK info */ |
113 | #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ | 113 | #define FLAG_SACK_RENEGING 0x2000 /* snd_una advanced to a sacked seq */ |
114 | #define FLAG_UPDATE_TS_RECENT 0x4000 /* tcp_replace_ts_recent() */ | ||
114 | 115 | ||
115 | #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) | 116 | #define FLAG_ACKED (FLAG_DATA_ACKED|FLAG_SYN_ACKED) |
116 | #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) | 117 | #define FLAG_NOT_DUP (FLAG_DATA|FLAG_WIN_UPDATE|FLAG_ACKED) |
@@ -3265,6 +3266,27 @@ static void tcp_send_challenge_ack(struct sock *sk) | |||
3265 | } | 3266 | } |
3266 | } | 3267 | } |
3267 | 3268 | ||
3269 | static void tcp_store_ts_recent(struct tcp_sock *tp) | ||
3270 | { | ||
3271 | tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; | ||
3272 | tp->rx_opt.ts_recent_stamp = get_seconds(); | ||
3273 | } | ||
3274 | |||
3275 | static void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) | ||
3276 | { | ||
3277 | if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { | ||
3278 | /* PAWS bug workaround wrt. ACK frames, the PAWS discard | ||
3279 | * extra check below makes sure this can only happen | ||
3280 | * for pure ACK frames. -DaveM | ||
3281 | * | ||
3282 | * Not only, also it occurs for expired timestamps. | ||
3283 | */ | ||
3284 | |||
3285 | if (tcp_paws_check(&tp->rx_opt, 0)) | ||
3286 | tcp_store_ts_recent(tp); | ||
3287 | } | ||
3288 | } | ||
3289 | |||
3268 | /* This routine deals with acks during a TLP episode. | 3290 | /* This routine deals with acks during a TLP episode. |
3269 | * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe. | 3291 | * Ref: loss detection algorithm in draft-dukkipati-tcpm-tcp-loss-probe. |
3270 | */ | 3292 | */ |
@@ -3340,6 +3362,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag) | |||
3340 | prior_fackets = tp->fackets_out; | 3362 | prior_fackets = tp->fackets_out; |
3341 | prior_in_flight = tcp_packets_in_flight(tp); | 3363 | prior_in_flight = tcp_packets_in_flight(tp); |
3342 | 3364 | ||
3365 | /* ts_recent update must be made after we are sure that the packet | ||
3366 | * is in window. | ||
3367 | */ | ||
3368 | if (flag & FLAG_UPDATE_TS_RECENT) | ||
3369 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
3370 | |||
3343 | if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { | 3371 | if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) { |
3344 | /* Window is constant, pure forward advance. | 3372 | /* Window is constant, pure forward advance. |
3345 | * No more checks are required. | 3373 | * No more checks are required. |
@@ -3636,27 +3664,6 @@ const u8 *tcp_parse_md5sig_option(const struct tcphdr *th) | |||
3636 | EXPORT_SYMBOL(tcp_parse_md5sig_option); | 3664 | EXPORT_SYMBOL(tcp_parse_md5sig_option); |
3637 | #endif | 3665 | #endif |
3638 | 3666 | ||
3639 | static inline void tcp_store_ts_recent(struct tcp_sock *tp) | ||
3640 | { | ||
3641 | tp->rx_opt.ts_recent = tp->rx_opt.rcv_tsval; | ||
3642 | tp->rx_opt.ts_recent_stamp = get_seconds(); | ||
3643 | } | ||
3644 | |||
3645 | static inline void tcp_replace_ts_recent(struct tcp_sock *tp, u32 seq) | ||
3646 | { | ||
3647 | if (tp->rx_opt.saw_tstamp && !after(seq, tp->rcv_wup)) { | ||
3648 | /* PAWS bug workaround wrt. ACK frames, the PAWS discard | ||
3649 | * extra check below makes sure this can only happen | ||
3650 | * for pure ACK frames. -DaveM | ||
3651 | * | ||
3652 | * Not only, also it occurs for expired timestamps. | ||
3653 | */ | ||
3654 | |||
3655 | if (tcp_paws_check(&tp->rx_opt, 0)) | ||
3656 | tcp_store_ts_recent(tp); | ||
3657 | } | ||
3658 | } | ||
3659 | |||
3660 | /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM | 3667 | /* Sorry, PAWS as specified is broken wrt. pure-ACKs -DaveM |
3661 | * | 3668 | * |
3662 | * It is not fatal. If this ACK does _not_ change critical state (seqs, window) | 3669 | * It is not fatal. If this ACK does _not_ change critical state (seqs, window) |
@@ -5250,14 +5257,9 @@ slow_path: | |||
5250 | return 0; | 5257 | return 0; |
5251 | 5258 | ||
5252 | step5: | 5259 | step5: |
5253 | if (tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) | 5260 | if (tcp_ack(sk, skb, FLAG_SLOWPATH | FLAG_UPDATE_TS_RECENT) < 0) |
5254 | goto discard; | 5261 | goto discard; |
5255 | 5262 | ||
5256 | /* ts_recent update must be made after we are sure that the packet | ||
5257 | * is in window. | ||
5258 | */ | ||
5259 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
5260 | |||
5261 | tcp_rcv_rtt_measure_ts(sk, skb); | 5263 | tcp_rcv_rtt_measure_ts(sk, skb); |
5262 | 5264 | ||
5263 | /* Process urgent data. */ | 5265 | /* Process urgent data. */ |
@@ -5666,7 +5668,8 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5666 | 5668 | ||
5667 | /* step 5: check the ACK field */ | 5669 | /* step 5: check the ACK field */ |
5668 | if (true) { | 5670 | if (true) { |
5669 | int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH) > 0; | 5671 | int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH | |
5672 | FLAG_UPDATE_TS_RECENT) > 0; | ||
5670 | 5673 | ||
5671 | switch (sk->sk_state) { | 5674 | switch (sk->sk_state) { |
5672 | case TCP_SYN_RECV: | 5675 | case TCP_SYN_RECV: |
@@ -5817,11 +5820,6 @@ int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb, | |||
5817 | } | 5820 | } |
5818 | } | 5821 | } |
5819 | 5822 | ||
5820 | /* ts_recent update must be made after we are sure that the packet | ||
5821 | * is in window. | ||
5822 | */ | ||
5823 | tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); | ||
5824 | |||
5825 | /* step 6: check the URG bit */ | 5823 | /* step 6: check the URG bit */ |
5826 | tcp_urg(sk, skb, th); | 5824 | tcp_urg(sk, skb, th); |
5827 | 5825 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 5f28131eb37e..b735c23a961d 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2353,8 +2353,12 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2353 | */ | 2353 | */ |
2354 | TCP_SKB_CB(skb)->when = tcp_time_stamp; | 2354 | TCP_SKB_CB(skb)->when = tcp_time_stamp; |
2355 | 2355 | ||
2356 | /* make sure skb->data is aligned on arches that require it */ | 2356 | /* make sure skb->data is aligned on arches that require it |
2357 | if (unlikely(NET_IP_ALIGN && ((unsigned long)skb->data & 3))) { | 2357 | * and check if ack-trimming & collapsing extended the headroom |
2358 | * beyond what csum_start can cover. | ||
2359 | */ | ||
2360 | if (unlikely((NET_IP_ALIGN && ((unsigned long)skb->data & 3)) || | ||
2361 | skb_headroom(skb) >= 0xFFFF)) { | ||
2358 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, | 2362 | struct sk_buff *nskb = __pskb_copy(skb, MAX_TCP_HEADER, |
2359 | GFP_ATOMIC); | 2363 | GFP_ATOMIC); |
2360 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : | 2364 | return nskb ? tcp_transmit_skb(sk, nskb, 0, GFP_ATOMIC) : |
@@ -2666,6 +2670,7 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2666 | skb_reserve(skb, MAX_TCP_HEADER); | 2670 | skb_reserve(skb, MAX_TCP_HEADER); |
2667 | 2671 | ||
2668 | skb_dst_set(skb, dst); | 2672 | skb_dst_set(skb, dst); |
2673 | security_skb_owned_by(skb, sk); | ||
2669 | 2674 | ||
2670 | mss = dst_metric_advmss(dst); | 2675 | mss = dst_metric_advmss(dst); |
2671 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) | 2676 | if (tp->rx_opt.user_mss && tp->rx_opt.user_mss < mss) |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 28b61e89bbb8..d1ab6ab29a55 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -169,8 +169,6 @@ static void inet6_prefix_notify(int event, struct inet6_dev *idev, | |||
169 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, | 169 | static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr, |
170 | struct net_device *dev); | 170 | struct net_device *dev); |
171 | 171 | ||
172 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | ||
173 | |||
174 | static struct ipv6_devconf ipv6_devconf __read_mostly = { | 172 | static struct ipv6_devconf ipv6_devconf __read_mostly = { |
175 | .forwarding = 0, | 173 | .forwarding = 0, |
176 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, | 174 | .hop_limit = IPV6_DEFAULT_HOPLIMIT, |
@@ -910,7 +908,7 @@ out2: | |||
910 | rcu_read_unlock_bh(); | 908 | rcu_read_unlock_bh(); |
911 | 909 | ||
912 | if (likely(err == 0)) | 910 | if (likely(err == 0)) |
913 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); | 911 | inet6addr_notifier_call_chain(NETDEV_UP, ifa); |
914 | else { | 912 | else { |
915 | kfree(ifa); | 913 | kfree(ifa); |
916 | ifa = ERR_PTR(err); | 914 | ifa = ERR_PTR(err); |
@@ -1000,7 +998,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp) | |||
1000 | 998 | ||
1001 | ipv6_ifa_notify(RTM_DELADDR, ifp); | 999 | ipv6_ifa_notify(RTM_DELADDR, ifp); |
1002 | 1000 | ||
1003 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifp); | 1001 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifp); |
1004 | 1002 | ||
1005 | /* | 1003 | /* |
1006 | * Purge or update corresponding prefix | 1004 | * Purge or update corresponding prefix |
@@ -3087,7 +3085,7 @@ static int addrconf_ifdown(struct net_device *dev, int how) | |||
3087 | 3085 | ||
3088 | if (state != INET6_IFADDR_STATE_DEAD) { | 3086 | if (state != INET6_IFADDR_STATE_DEAD) { |
3089 | __ipv6_ifa_notify(RTM_DELADDR, ifa); | 3087 | __ipv6_ifa_notify(RTM_DELADDR, ifa); |
3090 | atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa); | 3088 | inet6addr_notifier_call_chain(NETDEV_DOWN, ifa); |
3091 | } | 3089 | } |
3092 | in6_ifa_put(ifa); | 3090 | in6_ifa_put(ifa); |
3093 | 3091 | ||
@@ -5054,22 +5052,6 @@ static struct pernet_operations addrconf_ops = { | |||
5054 | .exit = addrconf_exit_net, | 5052 | .exit = addrconf_exit_net, |
5055 | }; | 5053 | }; |
5056 | 5054 | ||
5057 | /* | ||
5058 | * Device notifier | ||
5059 | */ | ||
5060 | |||
5061 | int register_inet6addr_notifier(struct notifier_block *nb) | ||
5062 | { | ||
5063 | return atomic_notifier_chain_register(&inet6addr_chain, nb); | ||
5064 | } | ||
5065 | EXPORT_SYMBOL(register_inet6addr_notifier); | ||
5066 | |||
5067 | int unregister_inet6addr_notifier(struct notifier_block *nb) | ||
5068 | { | ||
5069 | return atomic_notifier_chain_unregister(&inet6addr_chain, nb); | ||
5070 | } | ||
5071 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | ||
5072 | |||
5073 | static struct rtnl_af_ops inet6_ops = { | 5055 | static struct rtnl_af_ops inet6_ops = { |
5074 | .family = AF_INET6, | 5056 | .family = AF_INET6, |
5075 | .fill_link_af = inet6_fill_link_af, | 5057 | .fill_link_af = inet6_fill_link_af, |
diff --git a/net/ipv6/addrconf_core.c b/net/ipv6/addrconf_core.c index d051e5f4bf34..72104562c864 100644 --- a/net/ipv6/addrconf_core.c +++ b/net/ipv6/addrconf_core.c | |||
@@ -78,3 +78,22 @@ int __ipv6_addr_type(const struct in6_addr *addr) | |||
78 | } | 78 | } |
79 | EXPORT_SYMBOL(__ipv6_addr_type); | 79 | EXPORT_SYMBOL(__ipv6_addr_type); |
80 | 80 | ||
81 | static ATOMIC_NOTIFIER_HEAD(inet6addr_chain); | ||
82 | |||
83 | int register_inet6addr_notifier(struct notifier_block *nb) | ||
84 | { | ||
85 | return atomic_notifier_chain_register(&inet6addr_chain, nb); | ||
86 | } | ||
87 | EXPORT_SYMBOL(register_inet6addr_notifier); | ||
88 | |||
89 | int unregister_inet6addr_notifier(struct notifier_block *nb) | ||
90 | { | ||
91 | return atomic_notifier_chain_unregister(&inet6addr_chain, nb); | ||
92 | } | ||
93 | EXPORT_SYMBOL(unregister_inet6addr_notifier); | ||
94 | |||
95 | int inet6addr_notifier_call_chain(unsigned long val, void *v) | ||
96 | { | ||
97 | return atomic_notifier_call_chain(&inet6addr_chain, val, v); | ||
98 | } | ||
99 | EXPORT_SYMBOL(inet6addr_notifier_call_chain); | ||
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index 5060d54199ab..e0983f3648a6 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -71,6 +71,12 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
71 | return ret; | 71 | return ret; |
72 | } | 72 | } |
73 | 73 | ||
74 | static bool rpfilter_is_local(const struct sk_buff *skb) | ||
75 | { | ||
76 | const struct rt6_info *rt = (const void *) skb_dst(skb); | ||
77 | return rt && (rt->rt6i_flags & RTF_LOCAL); | ||
78 | } | ||
79 | |||
74 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | 80 | static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) |
75 | { | 81 | { |
76 | const struct xt_rpfilter_info *info = par->matchinfo; | 82 | const struct xt_rpfilter_info *info = par->matchinfo; |
@@ -78,7 +84,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
78 | struct ipv6hdr *iph; | 84 | struct ipv6hdr *iph; |
79 | bool invert = info->flags & XT_RPFILTER_INVERT; | 85 | bool invert = info->flags & XT_RPFILTER_INVERT; |
80 | 86 | ||
81 | if (par->in->flags & IFF_LOOPBACK) | 87 | if (rpfilter_is_local(skb)) |
82 | return true ^ invert; | 88 | return true ^ invert; |
83 | 89 | ||
84 | iph = ipv6_hdr(skb); | 90 | iph = ipv6_hdr(skb); |
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c index e6e44cef8db2..790d9f4b8b0b 100644 --- a/net/ipv6/reassembly.c +++ b/net/ipv6/reassembly.c | |||
@@ -342,9 +342,17 @@ found: | |||
342 | } | 342 | } |
343 | 343 | ||
344 | if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && | 344 | if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) && |
345 | fq->q.meat == fq->q.len) | 345 | fq->q.meat == fq->q.len) { |
346 | return ip6_frag_reasm(fq, prev, dev); | 346 | int res; |
347 | unsigned long orefdst = skb->_skb_refdst; | ||
348 | |||
349 | skb->_skb_refdst = 0UL; | ||
350 | res = ip6_frag_reasm(fq, prev, dev); | ||
351 | skb->_skb_refdst = orefdst; | ||
352 | return res; | ||
353 | } | ||
347 | 354 | ||
355 | skb_dst_drop(skb); | ||
348 | inet_frag_lru_move(&fq->q); | 356 | inet_frag_lru_move(&fq->q); |
349 | return -1; | 357 | return -1; |
350 | 358 | ||
diff --git a/net/irda/iriap.c b/net/irda/iriap.c index 29340a9a6fb9..e1b37f5a2691 100644 --- a/net/irda/iriap.c +++ b/net/irda/iriap.c | |||
@@ -303,7 +303,8 @@ static void iriap_disconnect_indication(void *instance, void *sap, | |||
303 | { | 303 | { |
304 | struct iriap_cb *self; | 304 | struct iriap_cb *self; |
305 | 305 | ||
306 | IRDA_DEBUG(4, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]); | 306 | IRDA_DEBUG(4, "%s(), reason=%s [%d]\n", __func__, |
307 | irlmp_reason_str(reason), reason); | ||
307 | 308 | ||
308 | self = instance; | 309 | self = instance; |
309 | 310 | ||
diff --git a/net/irda/irlmp.c b/net/irda/irlmp.c index 6115a44c0a24..1064621da6f6 100644 --- a/net/irda/irlmp.c +++ b/net/irda/irlmp.c | |||
@@ -66,8 +66,15 @@ const char *irlmp_reasons[] = { | |||
66 | "LM_LAP_RESET", | 66 | "LM_LAP_RESET", |
67 | "LM_INIT_DISCONNECT", | 67 | "LM_INIT_DISCONNECT", |
68 | "ERROR, NOT USED", | 68 | "ERROR, NOT USED", |
69 | "UNKNOWN", | ||
69 | }; | 70 | }; |
70 | 71 | ||
72 | const char *irlmp_reason_str(LM_REASON reason) | ||
73 | { | ||
74 | reason = min_t(size_t, reason, ARRAY_SIZE(irlmp_reasons) - 1); | ||
75 | return irlmp_reasons[reason]; | ||
76 | } | ||
77 | |||
71 | /* | 78 | /* |
72 | * Function irlmp_init (void) | 79 | * Function irlmp_init (void) |
73 | * | 80 | * |
@@ -747,7 +754,8 @@ void irlmp_disconnect_indication(struct lsap_cb *self, LM_REASON reason, | |||
747 | { | 754 | { |
748 | struct lsap_cb *lsap; | 755 | struct lsap_cb *lsap; |
749 | 756 | ||
750 | IRDA_DEBUG(1, "%s(), reason=%s\n", __func__, irlmp_reasons[reason]); | 757 | IRDA_DEBUG(1, "%s(), reason=%s [%d]\n", __func__, |
758 | irlmp_reason_str(reason), reason); | ||
751 | IRDA_ASSERT(self != NULL, return;); | 759 | IRDA_ASSERT(self != NULL, return;); |
752 | IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); | 760 | IRDA_ASSERT(self->magic == LMP_LSAP_MAGIC, return;); |
753 | 761 | ||
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c index e165e8dc962e..ae691651b721 100644 --- a/net/iucv/af_iucv.c +++ b/net/iucv/af_iucv.c | |||
@@ -49,12 +49,6 @@ static const u8 iprm_shutdown[8] = | |||
49 | 49 | ||
50 | #define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class)) | 50 | #define TRGCLS_SIZE (sizeof(((struct iucv_message *)0)->class)) |
51 | 51 | ||
52 | /* macros to set/get socket control buffer at correct offset */ | ||
53 | #define CB_TAG(skb) ((skb)->cb) /* iucv message tag */ | ||
54 | #define CB_TAG_LEN (sizeof(((struct iucv_message *) 0)->tag)) | ||
55 | #define CB_TRGCLS(skb) ((skb)->cb + CB_TAG_LEN) /* iucv msg target class */ | ||
56 | #define CB_TRGCLS_LEN (TRGCLS_SIZE) | ||
57 | |||
58 | #define __iucv_sock_wait(sk, condition, timeo, ret) \ | 52 | #define __iucv_sock_wait(sk, condition, timeo, ret) \ |
59 | do { \ | 53 | do { \ |
60 | DEFINE_WAIT(__wait); \ | 54 | DEFINE_WAIT(__wait); \ |
@@ -1141,7 +1135,7 @@ static int iucv_sock_sendmsg(struct kiocb *iocb, struct socket *sock, | |||
1141 | 1135 | ||
1142 | /* increment and save iucv message tag for msg_completion cbk */ | 1136 | /* increment and save iucv message tag for msg_completion cbk */ |
1143 | txmsg.tag = iucv->send_tag++; | 1137 | txmsg.tag = iucv->send_tag++; |
1144 | memcpy(CB_TAG(skb), &txmsg.tag, CB_TAG_LEN); | 1138 | IUCV_SKB_CB(skb)->tag = txmsg.tag; |
1145 | 1139 | ||
1146 | if (iucv->transport == AF_IUCV_TRANS_HIPER) { | 1140 | if (iucv->transport == AF_IUCV_TRANS_HIPER) { |
1147 | atomic_inc(&iucv->msg_sent); | 1141 | atomic_inc(&iucv->msg_sent); |
@@ -1224,7 +1218,7 @@ static int iucv_fragment_skb(struct sock *sk, struct sk_buff *skb, int len) | |||
1224 | return -ENOMEM; | 1218 | return -ENOMEM; |
1225 | 1219 | ||
1226 | /* copy target class to control buffer of new skb */ | 1220 | /* copy target class to control buffer of new skb */ |
1227 | memcpy(CB_TRGCLS(nskb), CB_TRGCLS(skb), CB_TRGCLS_LEN); | 1221 | IUCV_SKB_CB(nskb)->class = IUCV_SKB_CB(skb)->class; |
1228 | 1222 | ||
1229 | /* copy data fragment */ | 1223 | /* copy data fragment */ |
1230 | memcpy(nskb->data, skb->data + copied, size); | 1224 | memcpy(nskb->data, skb->data + copied, size); |
@@ -1256,7 +1250,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, | |||
1256 | 1250 | ||
1257 | /* store msg target class in the second 4 bytes of skb ctrl buffer */ | 1251 | /* store msg target class in the second 4 bytes of skb ctrl buffer */ |
1258 | /* Note: the first 4 bytes are reserved for msg tag */ | 1252 | /* Note: the first 4 bytes are reserved for msg tag */ |
1259 | memcpy(CB_TRGCLS(skb), &msg->class, CB_TRGCLS_LEN); | 1253 | IUCV_SKB_CB(skb)->class = msg->class; |
1260 | 1254 | ||
1261 | /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ | 1255 | /* check for special IPRM messages (e.g. iucv_sock_shutdown) */ |
1262 | if ((msg->flags & IUCV_IPRMDATA) && len > 7) { | 1256 | if ((msg->flags & IUCV_IPRMDATA) && len > 7) { |
@@ -1292,6 +1286,7 @@ static void iucv_process_message(struct sock *sk, struct sk_buff *skb, | |||
1292 | } | 1286 | } |
1293 | } | 1287 | } |
1294 | 1288 | ||
1289 | IUCV_SKB_CB(skb)->offset = 0; | ||
1295 | if (sock_queue_rcv_skb(sk, skb)) | 1290 | if (sock_queue_rcv_skb(sk, skb)) |
1296 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); | 1291 | skb_queue_head(&iucv_sk(sk)->backlog_skb_q, skb); |
1297 | } | 1292 | } |
@@ -1327,6 +1322,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1327 | unsigned int copied, rlen; | 1322 | unsigned int copied, rlen; |
1328 | struct sk_buff *skb, *rskb, *cskb; | 1323 | struct sk_buff *skb, *rskb, *cskb; |
1329 | int err = 0; | 1324 | int err = 0; |
1325 | u32 offset; | ||
1330 | 1326 | ||
1331 | msg->msg_namelen = 0; | 1327 | msg->msg_namelen = 0; |
1332 | 1328 | ||
@@ -1348,13 +1344,14 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1348 | return err; | 1344 | return err; |
1349 | } | 1345 | } |
1350 | 1346 | ||
1351 | rlen = skb->len; /* real length of skb */ | 1347 | offset = IUCV_SKB_CB(skb)->offset; |
1348 | rlen = skb->len - offset; /* real length of skb */ | ||
1352 | copied = min_t(unsigned int, rlen, len); | 1349 | copied = min_t(unsigned int, rlen, len); |
1353 | if (!rlen) | 1350 | if (!rlen) |
1354 | sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN; | 1351 | sk->sk_shutdown = sk->sk_shutdown | RCV_SHUTDOWN; |
1355 | 1352 | ||
1356 | cskb = skb; | 1353 | cskb = skb; |
1357 | if (skb_copy_datagram_iovec(cskb, 0, msg->msg_iov, copied)) { | 1354 | if (skb_copy_datagram_iovec(cskb, offset, msg->msg_iov, copied)) { |
1358 | if (!(flags & MSG_PEEK)) | 1355 | if (!(flags & MSG_PEEK)) |
1359 | skb_queue_head(&sk->sk_receive_queue, skb); | 1356 | skb_queue_head(&sk->sk_receive_queue, skb); |
1360 | return -EFAULT; | 1357 | return -EFAULT; |
@@ -1372,7 +1369,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1372 | * get the trgcls from the control buffer of the skb due to | 1369 | * get the trgcls from the control buffer of the skb due to |
1373 | * fragmentation of original iucv message. */ | 1370 | * fragmentation of original iucv message. */ |
1374 | err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS, | 1371 | err = put_cmsg(msg, SOL_IUCV, SCM_IUCV_TRGCLS, |
1375 | CB_TRGCLS_LEN, CB_TRGCLS(skb)); | 1372 | sizeof(IUCV_SKB_CB(skb)->class), |
1373 | (void *)&IUCV_SKB_CB(skb)->class); | ||
1376 | if (err) { | 1374 | if (err) { |
1377 | if (!(flags & MSG_PEEK)) | 1375 | if (!(flags & MSG_PEEK)) |
1378 | skb_queue_head(&sk->sk_receive_queue, skb); | 1376 | skb_queue_head(&sk->sk_receive_queue, skb); |
@@ -1384,9 +1382,8 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1384 | 1382 | ||
1385 | /* SOCK_STREAM: re-queue skb if it contains unreceived data */ | 1383 | /* SOCK_STREAM: re-queue skb if it contains unreceived data */ |
1386 | if (sk->sk_type == SOCK_STREAM) { | 1384 | if (sk->sk_type == SOCK_STREAM) { |
1387 | skb_pull(skb, copied); | 1385 | if (copied < rlen) { |
1388 | if (skb->len) { | 1386 | IUCV_SKB_CB(skb)->offset = offset + copied; |
1389 | skb_queue_head(&sk->sk_receive_queue, skb); | ||
1390 | goto done; | 1387 | goto done; |
1391 | } | 1388 | } |
1392 | } | 1389 | } |
@@ -1405,6 +1402,7 @@ static int iucv_sock_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1405 | spin_lock_bh(&iucv->message_q.lock); | 1402 | spin_lock_bh(&iucv->message_q.lock); |
1406 | rskb = skb_dequeue(&iucv->backlog_skb_q); | 1403 | rskb = skb_dequeue(&iucv->backlog_skb_q); |
1407 | while (rskb) { | 1404 | while (rskb) { |
1405 | IUCV_SKB_CB(rskb)->offset = 0; | ||
1408 | if (sock_queue_rcv_skb(sk, rskb)) { | 1406 | if (sock_queue_rcv_skb(sk, rskb)) { |
1409 | skb_queue_head(&iucv->backlog_skb_q, | 1407 | skb_queue_head(&iucv->backlog_skb_q, |
1410 | rskb); | 1408 | rskb); |
@@ -1833,7 +1831,7 @@ static void iucv_callback_txdone(struct iucv_path *path, | |||
1833 | spin_lock_irqsave(&list->lock, flags); | 1831 | spin_lock_irqsave(&list->lock, flags); |
1834 | 1832 | ||
1835 | while (list_skb != (struct sk_buff *)list) { | 1833 | while (list_skb != (struct sk_buff *)list) { |
1836 | if (!memcmp(&msg->tag, CB_TAG(list_skb), CB_TAG_LEN)) { | 1834 | if (msg->tag != IUCV_SKB_CB(list_skb)->tag) { |
1837 | this = list_skb; | 1835 | this = list_skb; |
1838 | break; | 1836 | break; |
1839 | } | 1837 | } |
@@ -2094,6 +2092,7 @@ static int afiucv_hs_callback_rx(struct sock *sk, struct sk_buff *skb) | |||
2094 | skb_pull(skb, sizeof(struct af_iucv_trans_hdr)); | 2092 | skb_pull(skb, sizeof(struct af_iucv_trans_hdr)); |
2095 | skb_reset_transport_header(skb); | 2093 | skb_reset_transport_header(skb); |
2096 | skb_reset_network_header(skb); | 2094 | skb_reset_network_header(skb); |
2095 | IUCV_SKB_CB(skb)->offset = 0; | ||
2097 | spin_lock(&iucv->message_q.lock); | 2096 | spin_lock(&iucv->message_q.lock); |
2098 | if (skb_queue_empty(&iucv->backlog_skb_q)) { | 2097 | if (skb_queue_empty(&iucv->backlog_skb_q)) { |
2099 | if (sock_queue_rcv_skb(sk, skb)) { | 2098 | if (sock_queue_rcv_skb(sk, skb)) { |
@@ -2198,8 +2197,7 @@ static int afiucv_hs_rcv(struct sk_buff *skb, struct net_device *dev, | |||
2198 | /* fall through and receive zero length data */ | 2197 | /* fall through and receive zero length data */ |
2199 | case 0: | 2198 | case 0: |
2200 | /* plain data frame */ | 2199 | /* plain data frame */ |
2201 | memcpy(CB_TRGCLS(skb), &trans_hdr->iucv_hdr.class, | 2200 | IUCV_SKB_CB(skb)->class = trans_hdr->iucv_hdr.class; |
2202 | CB_TRGCLS_LEN); | ||
2203 | err = afiucv_hs_callback_rx(sk, skb); | 2201 | err = afiucv_hs_callback_rx(sk, skb); |
2204 | break; | 2202 | break; |
2205 | default: | 2203 | default: |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 69aaba79a9f7..e8a260f53c16 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata) | |||
78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); | 78 | ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER); |
79 | } | 79 | } |
80 | 80 | ||
81 | u32 ieee80211_idle_off(struct ieee80211_local *local) | 81 | static u32 __ieee80211_idle_off(struct ieee80211_local *local) |
82 | { | 82 | { |
83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) | 83 | if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE)) |
84 | return 0; | 84 | return 0; |
@@ -87,7 +87,7 @@ u32 ieee80211_idle_off(struct ieee80211_local *local) | |||
87 | return IEEE80211_CONF_CHANGE_IDLE; | 87 | return IEEE80211_CONF_CHANGE_IDLE; |
88 | } | 88 | } |
89 | 89 | ||
90 | static u32 ieee80211_idle_on(struct ieee80211_local *local) | 90 | static u32 __ieee80211_idle_on(struct ieee80211_local *local) |
91 | { | 91 | { |
92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) | 92 | if (local->hw.conf.flags & IEEE80211_CONF_IDLE) |
93 | return 0; | 93 | return 0; |
@@ -98,16 +98,18 @@ static u32 ieee80211_idle_on(struct ieee80211_local *local) | |||
98 | return IEEE80211_CONF_CHANGE_IDLE; | 98 | return IEEE80211_CONF_CHANGE_IDLE; |
99 | } | 99 | } |
100 | 100 | ||
101 | void ieee80211_recalc_idle(struct ieee80211_local *local) | 101 | static u32 __ieee80211_recalc_idle(struct ieee80211_local *local, |
102 | bool force_active) | ||
102 | { | 103 | { |
103 | bool working = false, scanning, active; | 104 | bool working = false, scanning, active; |
104 | unsigned int led_trig_start = 0, led_trig_stop = 0; | 105 | unsigned int led_trig_start = 0, led_trig_stop = 0; |
105 | struct ieee80211_roc_work *roc; | 106 | struct ieee80211_roc_work *roc; |
106 | u32 change; | ||
107 | 107 | ||
108 | lockdep_assert_held(&local->mtx); | 108 | lockdep_assert_held(&local->mtx); |
109 | 109 | ||
110 | active = !list_empty(&local->chanctx_list) || local->monitors; | 110 | active = force_active || |
111 | !list_empty(&local->chanctx_list) || | ||
112 | local->monitors; | ||
111 | 113 | ||
112 | if (!local->ops->remain_on_channel) { | 114 | if (!local->ops->remain_on_channel) { |
113 | list_for_each_entry(roc, &local->roc_list, list) { | 115 | list_for_each_entry(roc, &local->roc_list, list) { |
@@ -132,9 +134,18 @@ void ieee80211_recalc_idle(struct ieee80211_local *local) | |||
132 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); | 134 | ieee80211_mod_tpt_led_trig(local, led_trig_start, led_trig_stop); |
133 | 135 | ||
134 | if (working || scanning || active) | 136 | if (working || scanning || active) |
135 | change = ieee80211_idle_off(local); | 137 | return __ieee80211_idle_off(local); |
136 | else | 138 | return __ieee80211_idle_on(local); |
137 | change = ieee80211_idle_on(local); | 139 | } |
140 | |||
141 | u32 ieee80211_idle_off(struct ieee80211_local *local) | ||
142 | { | ||
143 | return __ieee80211_recalc_idle(local, true); | ||
144 | } | ||
145 | |||
146 | void ieee80211_recalc_idle(struct ieee80211_local *local) | ||
147 | { | ||
148 | u32 change = __ieee80211_recalc_idle(local, false); | ||
138 | if (change) | 149 | if (change) |
139 | ieee80211_hw_config(local, change); | 150 | ieee80211_hw_config(local, change); |
140 | } | 151 | } |
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index e06dbbf8cb4c..dec42ab1fa91 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c | |||
@@ -3887,8 +3887,16 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata, | |||
3887 | /* prep auth_data so we don't go into idle on disassoc */ | 3887 | /* prep auth_data so we don't go into idle on disassoc */ |
3888 | ifmgd->auth_data = auth_data; | 3888 | ifmgd->auth_data = auth_data; |
3889 | 3889 | ||
3890 | if (ifmgd->associated) | 3890 | if (ifmgd->associated) { |
3891 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 3891 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3892 | |||
3893 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | ||
3894 | WLAN_REASON_UNSPECIFIED, | ||
3895 | false, frame_buf); | ||
3896 | |||
3897 | __cfg80211_send_deauth(sdata->dev, frame_buf, | ||
3898 | sizeof(frame_buf)); | ||
3899 | } | ||
3892 | 3900 | ||
3893 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); | 3901 | sdata_info(sdata, "authenticate with %pM\n", req->bss->bssid); |
3894 | 3902 | ||
@@ -3948,8 +3956,16 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata, | |||
3948 | 3956 | ||
3949 | mutex_lock(&ifmgd->mtx); | 3957 | mutex_lock(&ifmgd->mtx); |
3950 | 3958 | ||
3951 | if (ifmgd->associated) | 3959 | if (ifmgd->associated) { |
3952 | ieee80211_set_disassoc(sdata, 0, 0, false, NULL); | 3960 | u8 frame_buf[IEEE80211_DEAUTH_FRAME_LEN]; |
3961 | |||
3962 | ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, | ||
3963 | WLAN_REASON_UNSPECIFIED, | ||
3964 | false, frame_buf); | ||
3965 | |||
3966 | __cfg80211_send_deauth(sdata->dev, frame_buf, | ||
3967 | sizeof(frame_buf)); | ||
3968 | } | ||
3953 | 3969 | ||
3954 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { | 3970 | if (ifmgd->auth_data && !ifmgd->auth_data->done) { |
3955 | err = -EBUSY; | 3971 | err = -EBUSY; |
diff --git a/net/netfilter/ipset/ip_set_bitmap_ipmac.c b/net/netfilter/ipset/ip_set_bitmap_ipmac.c index 0f92dc24cb89..d7df6ac2c6f1 100644 --- a/net/netfilter/ipset/ip_set_bitmap_ipmac.c +++ b/net/netfilter/ipset/ip_set_bitmap_ipmac.c | |||
@@ -339,7 +339,11 @@ bitmap_ipmac_tlist(const struct ip_set *set, | |||
339 | nla_put_failure: | 339 | nla_put_failure: |
340 | nla_nest_cancel(skb, nested); | 340 | nla_nest_cancel(skb, nested); |
341 | ipset_nest_end(skb, atd); | 341 | ipset_nest_end(skb, atd); |
342 | return -EMSGSIZE; | 342 | if (unlikely(id == first)) { |
343 | cb->args[2] = 0; | ||
344 | return -EMSGSIZE; | ||
345 | } | ||
346 | return 0; | ||
343 | } | 347 | } |
344 | 348 | ||
345 | static int | 349 | static int |
diff --git a/net/netfilter/ipset/ip_set_hash_ipportnet.c b/net/netfilter/ipset/ip_set_hash_ipportnet.c index f2627226a087..10a30b4fc7db 100644 --- a/net/netfilter/ipset/ip_set_hash_ipportnet.c +++ b/net/netfilter/ipset/ip_set_hash_ipportnet.c | |||
@@ -104,6 +104,15 @@ hash_ipportnet4_data_flags(struct hash_ipportnet4_elem *dst, u32 flags) | |||
104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void | ||
108 | hash_ipportnet4_data_reset_flags(struct hash_ipportnet4_elem *dst, u32 *flags) | ||
109 | { | ||
110 | if (dst->nomatch) { | ||
111 | *flags = IPSET_FLAG_NOMATCH; | ||
112 | dst->nomatch = 0; | ||
113 | } | ||
114 | } | ||
115 | |||
107 | static inline int | 116 | static inline int |
108 | hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem) | 117 | hash_ipportnet4_data_match(const struct hash_ipportnet4_elem *elem) |
109 | { | 118 | { |
@@ -414,6 +423,15 @@ hash_ipportnet6_data_flags(struct hash_ipportnet6_elem *dst, u32 flags) | |||
414 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 423 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
415 | } | 424 | } |
416 | 425 | ||
426 | static inline void | ||
427 | hash_ipportnet6_data_reset_flags(struct hash_ipportnet6_elem *dst, u32 *flags) | ||
428 | { | ||
429 | if (dst->nomatch) { | ||
430 | *flags = IPSET_FLAG_NOMATCH; | ||
431 | dst->nomatch = 0; | ||
432 | } | ||
433 | } | ||
434 | |||
417 | static inline int | 435 | static inline int |
418 | hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) | 436 | hash_ipportnet6_data_match(const struct hash_ipportnet6_elem *elem) |
419 | { | 437 | { |
diff --git a/net/netfilter/ipset/ip_set_hash_net.c b/net/netfilter/ipset/ip_set_hash_net.c index 4b677cf6bf7d..d6a59154d710 100644 --- a/net/netfilter/ipset/ip_set_hash_net.c +++ b/net/netfilter/ipset/ip_set_hash_net.c | |||
@@ -87,7 +87,16 @@ hash_net4_data_copy(struct hash_net4_elem *dst, | |||
87 | static inline void | 87 | static inline void |
88 | hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) | 88 | hash_net4_data_flags(struct hash_net4_elem *dst, u32 flags) |
89 | { | 89 | { |
90 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 90 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
91 | } | ||
92 | |||
93 | static inline void | ||
94 | hash_net4_data_reset_flags(struct hash_net4_elem *dst, u32 *flags) | ||
95 | { | ||
96 | if (dst->nomatch) { | ||
97 | *flags = IPSET_FLAG_NOMATCH; | ||
98 | dst->nomatch = 0; | ||
99 | } | ||
91 | } | 100 | } |
92 | 101 | ||
93 | static inline int | 102 | static inline int |
@@ -308,7 +317,16 @@ hash_net6_data_copy(struct hash_net6_elem *dst, | |||
308 | static inline void | 317 | static inline void |
309 | hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags) | 318 | hash_net6_data_flags(struct hash_net6_elem *dst, u32 flags) |
310 | { | 319 | { |
311 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 320 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
321 | } | ||
322 | |||
323 | static inline void | ||
324 | hash_net6_data_reset_flags(struct hash_net6_elem *dst, u32 *flags) | ||
325 | { | ||
326 | if (dst->nomatch) { | ||
327 | *flags = IPSET_FLAG_NOMATCH; | ||
328 | dst->nomatch = 0; | ||
329 | } | ||
312 | } | 330 | } |
313 | 331 | ||
314 | static inline int | 332 | static inline int |
diff --git a/net/netfilter/ipset/ip_set_hash_netiface.c b/net/netfilter/ipset/ip_set_hash_netiface.c index 6ba985f1c96f..f2b0a3c30130 100644 --- a/net/netfilter/ipset/ip_set_hash_netiface.c +++ b/net/netfilter/ipset/ip_set_hash_netiface.c | |||
@@ -198,7 +198,16 @@ hash_netiface4_data_copy(struct hash_netiface4_elem *dst, | |||
198 | static inline void | 198 | static inline void |
199 | hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) | 199 | hash_netiface4_data_flags(struct hash_netiface4_elem *dst, u32 flags) |
200 | { | 200 | { |
201 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 201 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
202 | } | ||
203 | |||
204 | static inline void | ||
205 | hash_netiface4_data_reset_flags(struct hash_netiface4_elem *dst, u32 *flags) | ||
206 | { | ||
207 | if (dst->nomatch) { | ||
208 | *flags = IPSET_FLAG_NOMATCH; | ||
209 | dst->nomatch = 0; | ||
210 | } | ||
202 | } | 211 | } |
203 | 212 | ||
204 | static inline int | 213 | static inline int |
@@ -494,7 +503,7 @@ hash_netiface6_data_copy(struct hash_netiface6_elem *dst, | |||
494 | static inline void | 503 | static inline void |
495 | hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags) | 504 | hash_netiface6_data_flags(struct hash_netiface6_elem *dst, u32 flags) |
496 | { | 505 | { |
497 | dst->nomatch = flags & IPSET_FLAG_NOMATCH; | 506 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
498 | } | 507 | } |
499 | 508 | ||
500 | static inline int | 509 | static inline int |
@@ -504,6 +513,15 @@ hash_netiface6_data_match(const struct hash_netiface6_elem *elem) | |||
504 | } | 513 | } |
505 | 514 | ||
506 | static inline void | 515 | static inline void |
516 | hash_netiface6_data_reset_flags(struct hash_netiface6_elem *dst, u32 *flags) | ||
517 | { | ||
518 | if (dst->nomatch) { | ||
519 | *flags = IPSET_FLAG_NOMATCH; | ||
520 | dst->nomatch = 0; | ||
521 | } | ||
522 | } | ||
523 | |||
524 | static inline void | ||
507 | hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) | 525 | hash_netiface6_data_zero_out(struct hash_netiface6_elem *elem) |
508 | { | 526 | { |
509 | elem->elem = 0; | 527 | elem->elem = 0; |
diff --git a/net/netfilter/ipset/ip_set_hash_netport.c b/net/netfilter/ipset/ip_set_hash_netport.c index af20c0c5ced2..349deb672a2d 100644 --- a/net/netfilter/ipset/ip_set_hash_netport.c +++ b/net/netfilter/ipset/ip_set_hash_netport.c | |||
@@ -104,6 +104,15 @@ hash_netport4_data_flags(struct hash_netport4_elem *dst, u32 flags) | |||
104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 104 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
105 | } | 105 | } |
106 | 106 | ||
107 | static inline void | ||
108 | hash_netport4_data_reset_flags(struct hash_netport4_elem *dst, u32 *flags) | ||
109 | { | ||
110 | if (dst->nomatch) { | ||
111 | *flags = IPSET_FLAG_NOMATCH; | ||
112 | dst->nomatch = 0; | ||
113 | } | ||
114 | } | ||
115 | |||
107 | static inline int | 116 | static inline int |
108 | hash_netport4_data_match(const struct hash_netport4_elem *elem) | 117 | hash_netport4_data_match(const struct hash_netport4_elem *elem) |
109 | { | 118 | { |
@@ -375,6 +384,15 @@ hash_netport6_data_flags(struct hash_netport6_elem *dst, u32 flags) | |||
375 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); | 384 | dst->nomatch = !!(flags & IPSET_FLAG_NOMATCH); |
376 | } | 385 | } |
377 | 386 | ||
387 | static inline void | ||
388 | hash_netport6_data_reset_flags(struct hash_netport6_elem *dst, u32 *flags) | ||
389 | { | ||
390 | if (dst->nomatch) { | ||
391 | *flags = IPSET_FLAG_NOMATCH; | ||
392 | dst->nomatch = 0; | ||
393 | } | ||
394 | } | ||
395 | |||
378 | static inline int | 396 | static inline int |
379 | hash_netport6_data_match(const struct hash_netport6_elem *elem) | 397 | hash_netport6_data_match(const struct hash_netport6_elem *elem) |
380 | { | 398 | { |
diff --git a/net/netfilter/ipset/ip_set_list_set.c b/net/netfilter/ipset/ip_set_list_set.c index 8371c2bac2e4..09c744aa8982 100644 --- a/net/netfilter/ipset/ip_set_list_set.c +++ b/net/netfilter/ipset/ip_set_list_set.c | |||
@@ -174,9 +174,13 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id, | |||
174 | { | 174 | { |
175 | const struct set_elem *e = list_set_elem(map, i); | 175 | const struct set_elem *e = list_set_elem(map, i); |
176 | 176 | ||
177 | if (i == map->size - 1 && e->id != IPSET_INVALID_ID) | 177 | if (e->id != IPSET_INVALID_ID) { |
178 | /* Last element replaced: e.g. add new,before,last */ | 178 | const struct set_elem *x = list_set_elem(map, map->size - 1); |
179 | ip_set_put_byindex(e->id); | 179 | |
180 | /* Last element replaced or pushed off */ | ||
181 | if (x->id != IPSET_INVALID_ID) | ||
182 | ip_set_put_byindex(x->id); | ||
183 | } | ||
180 | if (with_timeout(map->timeout)) | 184 | if (with_timeout(map->timeout)) |
181 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); | 185 | list_elem_tadd(map, i, id, ip_set_timeout_set(timeout)); |
182 | else | 186 | else |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 0e7d423324c3..e0c4373b4747 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -1593,10 +1593,8 @@ static int sip_help_tcp(struct sk_buff *skb, unsigned int protoff, | |||
1593 | end += strlen("\r\n\r\n") + clen; | 1593 | end += strlen("\r\n\r\n") + clen; |
1594 | 1594 | ||
1595 | msglen = origlen = end - dptr; | 1595 | msglen = origlen = end - dptr; |
1596 | if (msglen > datalen) { | 1596 | if (msglen > datalen) |
1597 | nf_ct_helper_log(skb, ct, "incomplete/bad SIP message"); | 1597 | return NF_ACCEPT; |
1598 | return NF_DROP; | ||
1599 | } | ||
1600 | 1598 | ||
1601 | ret = process_sip_msg(skb, ct, protoff, dataoff, | 1599 | ret = process_sip_msg(skb, ct, protoff, dataoff, |
1602 | &dptr, &msglen); | 1600 | &dptr, &msglen); |
diff --git a/net/netfilter/nf_nat_core.c b/net/netfilter/nf_nat_core.c index 346f871cf096..2e469ca2ca55 100644 --- a/net/netfilter/nf_nat_core.c +++ b/net/netfilter/nf_nat_core.c | |||
@@ -468,33 +468,22 @@ EXPORT_SYMBOL_GPL(nf_nat_packet); | |||
468 | struct nf_nat_proto_clean { | 468 | struct nf_nat_proto_clean { |
469 | u8 l3proto; | 469 | u8 l3proto; |
470 | u8 l4proto; | 470 | u8 l4proto; |
471 | bool hash; | ||
472 | }; | 471 | }; |
473 | 472 | ||
474 | /* Clear NAT section of all conntracks, in case we're loaded again. */ | 473 | /* kill conntracks with affected NAT section */ |
475 | static int nf_nat_proto_clean(struct nf_conn *i, void *data) | 474 | static int nf_nat_proto_remove(struct nf_conn *i, void *data) |
476 | { | 475 | { |
477 | const struct nf_nat_proto_clean *clean = data; | 476 | const struct nf_nat_proto_clean *clean = data; |
478 | struct nf_conn_nat *nat = nfct_nat(i); | 477 | struct nf_conn_nat *nat = nfct_nat(i); |
479 | 478 | ||
480 | if (!nat) | 479 | if (!nat) |
481 | return 0; | 480 | return 0; |
482 | if (!(i->status & IPS_SRC_NAT_DONE)) | 481 | |
483 | return 0; | ||
484 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || | 482 | if ((clean->l3proto && nf_ct_l3num(i) != clean->l3proto) || |
485 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) | 483 | (clean->l4proto && nf_ct_protonum(i) != clean->l4proto)) |
486 | return 0; | 484 | return 0; |
487 | 485 | ||
488 | if (clean->hash) { | 486 | return i->status & IPS_NAT_MASK ? 1 : 0; |
489 | spin_lock_bh(&nf_nat_lock); | ||
490 | hlist_del_rcu(&nat->bysource); | ||
491 | spin_unlock_bh(&nf_nat_lock); | ||
492 | } else { | ||
493 | memset(nat, 0, sizeof(*nat)); | ||
494 | i->status &= ~(IPS_NAT_MASK | IPS_NAT_DONE_MASK | | ||
495 | IPS_SEQ_ADJUST); | ||
496 | } | ||
497 | return 0; | ||
498 | } | 487 | } |
499 | 488 | ||
500 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | 489 | static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) |
@@ -506,16 +495,8 @@ static void nf_nat_l4proto_clean(u8 l3proto, u8 l4proto) | |||
506 | struct net *net; | 495 | struct net *net; |
507 | 496 | ||
508 | rtnl_lock(); | 497 | rtnl_lock(); |
509 | /* Step 1 - remove from bysource hash */ | ||
510 | clean.hash = true; | ||
511 | for_each_net(net) | 498 | for_each_net(net) |
512 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 499 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
513 | synchronize_rcu(); | ||
514 | |||
515 | /* Step 2 - clean NAT section */ | ||
516 | clean.hash = false; | ||
517 | for_each_net(net) | ||
518 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
519 | rtnl_unlock(); | 500 | rtnl_unlock(); |
520 | } | 501 | } |
521 | 502 | ||
@@ -527,16 +508,9 @@ static void nf_nat_l3proto_clean(u8 l3proto) | |||
527 | struct net *net; | 508 | struct net *net; |
528 | 509 | ||
529 | rtnl_lock(); | 510 | rtnl_lock(); |
530 | /* Step 1 - remove from bysource hash */ | ||
531 | clean.hash = true; | ||
532 | for_each_net(net) | ||
533 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | ||
534 | synchronize_rcu(); | ||
535 | 511 | ||
536 | /* Step 2 - clean NAT section */ | ||
537 | clean.hash = false; | ||
538 | for_each_net(net) | 512 | for_each_net(net) |
539 | nf_ct_iterate_cleanup(net, nf_nat_proto_clean, &clean); | 513 | nf_ct_iterate_cleanup(net, nf_nat_proto_remove, &clean); |
540 | rtnl_unlock(); | 514 | rtnl_unlock(); |
541 | } | 515 | } |
542 | 516 | ||
@@ -774,7 +748,7 @@ static void __net_exit nf_nat_net_exit(struct net *net) | |||
774 | { | 748 | { |
775 | struct nf_nat_proto_clean clean = {}; | 749 | struct nf_nat_proto_clean clean = {}; |
776 | 750 | ||
777 | nf_ct_iterate_cleanup(net, &nf_nat_proto_clean, &clean); | 751 | nf_ct_iterate_cleanup(net, &nf_nat_proto_remove, &clean); |
778 | synchronize_rcu(); | 752 | synchronize_rcu(); |
779 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); | 753 | nf_ct_free_hashtable(net->ct.nat_bysource, net->ct.nat_htable_size); |
780 | } | 754 | } |
diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c index 7fcb307dea47..103bd704b5fc 100644 --- a/net/netrom/af_netrom.c +++ b/net/netrom/af_netrom.c | |||
@@ -1173,7 +1173,7 @@ static int nr_recvmsg(struct kiocb *iocb, struct socket *sock, | |||
1173 | } | 1173 | } |
1174 | 1174 | ||
1175 | if (sax != NULL) { | 1175 | if (sax != NULL) { |
1176 | memset(sax, 0, sizeof(sax)); | 1176 | memset(sax, 0, sizeof(*sax)); |
1177 | sax->sax25_family = AF_NETROM; | 1177 | sax->sax25_family = AF_NETROM; |
1178 | skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, | 1178 | skb_copy_from_linear_data_offset(skb, 7, sax->sax25_call.ax25_call, |
1179 | AX25_ADDR_LEN); | 1179 | AX25_ADDR_LEN); |
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c index 7bb5d4f6bb90..d2f9f2e57298 100644 --- a/net/openvswitch/datapath.c +++ b/net/openvswitch/datapath.c | |||
@@ -1681,10 +1681,8 @@ struct sk_buff *ovs_vport_cmd_build_info(struct vport *vport, u32 portid, | |||
1681 | return ERR_PTR(-ENOMEM); | 1681 | return ERR_PTR(-ENOMEM); |
1682 | 1682 | ||
1683 | retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd); | 1683 | retval = ovs_vport_cmd_fill_info(vport, skb, portid, seq, 0, cmd); |
1684 | if (retval < 0) { | 1684 | BUG_ON(retval < 0); |
1685 | kfree_skb(skb); | 1685 | |
1686 | return ERR_PTR(retval); | ||
1687 | } | ||
1688 | return skb; | 1686 | return skb; |
1689 | } | 1687 | } |
1690 | 1688 | ||
@@ -1814,25 +1812,33 @@ static int ovs_vport_cmd_set(struct sk_buff *skb, struct genl_info *info) | |||
1814 | nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) | 1812 | nla_get_u32(a[OVS_VPORT_ATTR_TYPE]) != vport->ops->type) |
1815 | err = -EINVAL; | 1813 | err = -EINVAL; |
1816 | 1814 | ||
1815 | reply = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
1816 | if (!reply) { | ||
1817 | err = -ENOMEM; | ||
1818 | goto exit_unlock; | ||
1819 | } | ||
1820 | |||
1817 | if (!err && a[OVS_VPORT_ATTR_OPTIONS]) | 1821 | if (!err && a[OVS_VPORT_ATTR_OPTIONS]) |
1818 | err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]); | 1822 | err = ovs_vport_set_options(vport, a[OVS_VPORT_ATTR_OPTIONS]); |
1819 | if (err) | 1823 | if (err) |
1820 | goto exit_unlock; | 1824 | goto exit_free; |
1825 | |||
1821 | if (a[OVS_VPORT_ATTR_UPCALL_PID]) | 1826 | if (a[OVS_VPORT_ATTR_UPCALL_PID]) |
1822 | vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); | 1827 | vport->upcall_portid = nla_get_u32(a[OVS_VPORT_ATTR_UPCALL_PID]); |
1823 | 1828 | ||
1824 | reply = ovs_vport_cmd_build_info(vport, info->snd_portid, info->snd_seq, | 1829 | err = ovs_vport_cmd_fill_info(vport, reply, info->snd_portid, |
1825 | OVS_VPORT_CMD_NEW); | 1830 | info->snd_seq, 0, OVS_VPORT_CMD_NEW); |
1826 | if (IS_ERR(reply)) { | 1831 | BUG_ON(err < 0); |
1827 | netlink_set_err(sock_net(skb->sk)->genl_sock, 0, | ||
1828 | ovs_dp_vport_multicast_group.id, PTR_ERR(reply)); | ||
1829 | goto exit_unlock; | ||
1830 | } | ||
1831 | 1832 | ||
1832 | ovs_unlock(); | 1833 | ovs_unlock(); |
1833 | ovs_notify(reply, info, &ovs_dp_vport_multicast_group); | 1834 | ovs_notify(reply, info, &ovs_dp_vport_multicast_group); |
1834 | return 0; | 1835 | return 0; |
1835 | 1836 | ||
1837 | rtnl_unlock(); | ||
1838 | return 0; | ||
1839 | |||
1840 | exit_free: | ||
1841 | kfree_skb(reply); | ||
1836 | exit_unlock: | 1842 | exit_unlock: |
1837 | ovs_unlock(); | 1843 | ovs_unlock(); |
1838 | return err; | 1844 | return err; |
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c index cf9328be75e9..b15321a2228c 100644 --- a/net/openvswitch/flow.c +++ b/net/openvswitch/flow.c | |||
@@ -795,9 +795,9 @@ void ovs_flow_tbl_insert(struct flow_table *table, struct sw_flow *flow) | |||
795 | 795 | ||
796 | void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) | 796 | void ovs_flow_tbl_remove(struct flow_table *table, struct sw_flow *flow) |
797 | { | 797 | { |
798 | BUG_ON(table->count == 0); | ||
798 | hlist_del_rcu(&flow->hash_node[table->node_ver]); | 799 | hlist_del_rcu(&flow->hash_node[table->node_ver]); |
799 | table->count--; | 800 | table->count--; |
800 | BUG_ON(table->count < 0); | ||
801 | } | 801 | } |
802 | 802 | ||
803 | /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */ | 803 | /* The size of the argument for each %OVS_KEY_ATTR_* Netlink attribute. */ |
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c index 1135d8227f9b..9b97172db84a 100644 --- a/net/sched/cls_fw.c +++ b/net/sched/cls_fw.c | |||
@@ -204,7 +204,6 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, | |||
204 | if (err < 0) | 204 | if (err < 0) |
205 | return err; | 205 | return err; |
206 | 206 | ||
207 | err = -EINVAL; | ||
208 | if (tb[TCA_FW_CLASSID]) { | 207 | if (tb[TCA_FW_CLASSID]) { |
209 | f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); | 208 | f->res.classid = nla_get_u32(tb[TCA_FW_CLASSID]); |
210 | tcf_bind_filter(tp, &f->res, base); | 209 | tcf_bind_filter(tp, &f->res, base); |
@@ -218,6 +217,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f, | |||
218 | } | 217 | } |
219 | #endif /* CONFIG_NET_CLS_IND */ | 218 | #endif /* CONFIG_NET_CLS_IND */ |
220 | 219 | ||
220 | err = -EINVAL; | ||
221 | if (tb[TCA_FW_MASK]) { | 221 | if (tb[TCA_FW_MASK]) { |
222 | mask = nla_get_u32(tb[TCA_FW_MASK]); | 222 | mask = nla_get_u32(tb[TCA_FW_MASK]); |
223 | if (mask != head->mask) | 223 | if (mask != head->mask) |
diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index dcc446e7fbf6..d5f35f15af98 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c | |||
@@ -304,10 +304,8 @@ static struct rpc_clnt * rpc_new_client(const struct rpc_create_args *args, stru | |||
304 | err = rpciod_up(); | 304 | err = rpciod_up(); |
305 | if (err) | 305 | if (err) |
306 | goto out_no_rpciod; | 306 | goto out_no_rpciod; |
307 | err = -EINVAL; | ||
308 | if (!xprt) | ||
309 | goto out_no_xprt; | ||
310 | 307 | ||
308 | err = -EINVAL; | ||
311 | if (args->version >= program->nrvers) | 309 | if (args->version >= program->nrvers) |
312 | goto out_err; | 310 | goto out_err; |
313 | version = program->version[args->version]; | 311 | version = program->version[args->version]; |
@@ -382,10 +380,9 @@ out_no_principal: | |||
382 | out_no_stats: | 380 | out_no_stats: |
383 | kfree(clnt); | 381 | kfree(clnt); |
384 | out_err: | 382 | out_err: |
385 | xprt_put(xprt); | ||
386 | out_no_xprt: | ||
387 | rpciod_down(); | 383 | rpciod_down(); |
388 | out_no_rpciod: | 384 | out_no_rpciod: |
385 | xprt_put(xprt); | ||
389 | return ERR_PTR(err); | 386 | return ERR_PTR(err); |
390 | } | 387 | } |
391 | 388 | ||
@@ -512,7 +509,7 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, | |||
512 | new = rpc_new_client(args, xprt); | 509 | new = rpc_new_client(args, xprt); |
513 | if (IS_ERR(new)) { | 510 | if (IS_ERR(new)) { |
514 | err = PTR_ERR(new); | 511 | err = PTR_ERR(new); |
515 | goto out_put; | 512 | goto out_err; |
516 | } | 513 | } |
517 | 514 | ||
518 | atomic_inc(&clnt->cl_count); | 515 | atomic_inc(&clnt->cl_count); |
@@ -525,8 +522,6 @@ static struct rpc_clnt *__rpc_clone_client(struct rpc_create_args *args, | |||
525 | new->cl_chatty = clnt->cl_chatty; | 522 | new->cl_chatty = clnt->cl_chatty; |
526 | return new; | 523 | return new; |
527 | 524 | ||
528 | out_put: | ||
529 | xprt_put(xprt); | ||
530 | out_err: | 525 | out_err: |
531 | dprintk("RPC: %s: returned error %d\n", __func__, err); | 526 | dprintk("RPC: %s: returned error %d\n", __func__, err); |
532 | return ERR_PTR(err); | 527 | return ERR_PTR(err); |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5ca1631de7ef..9efe01113c5c 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1414,7 +1414,7 @@ static void maybe_add_creds(struct sk_buff *skb, const struct socket *sock, | |||
1414 | !other->sk_socket || | 1414 | !other->sk_socket || |
1415 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { | 1415 | test_bit(SOCK_PASSCRED, &other->sk_socket->flags)) { |
1416 | UNIXCB(skb).pid = get_pid(task_tgid(current)); | 1416 | UNIXCB(skb).pid = get_pid(task_tgid(current)); |
1417 | current_euid_egid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); | 1417 | current_uid_gid(&UNIXCB(skb).uid, &UNIXCB(skb).gid); |
1418 | } | 1418 | } |
1419 | } | 1419 | } |
1420 | 1420 | ||