diff options
67 files changed, 544 insertions, 289 deletions
diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt index e2142fe40cda..c4ac35234f05 100644 --- a/Documentation/networking/ip-sysctl.txt +++ b/Documentation/networking/ip-sysctl.txt | |||
| @@ -1337,6 +1337,7 @@ tag - INTEGER | |||
| 1337 | Default value is 0. | 1337 | Default value is 0. |
| 1338 | 1338 | ||
| 1339 | xfrm4_gc_thresh - INTEGER | 1339 | xfrm4_gc_thresh - INTEGER |
| 1340 | (Obsolete since linux-4.14) | ||
| 1340 | The threshold at which we will start garbage collecting for IPv4 | 1341 | The threshold at which we will start garbage collecting for IPv4 |
| 1341 | destination cache entries. At twice this value the system will | 1342 | destination cache entries. At twice this value the system will |
| 1342 | refuse new allocations. | 1343 | refuse new allocations. |
| @@ -1920,6 +1921,7 @@ echo_ignore_all - BOOLEAN | |||
| 1920 | Default: 0 | 1921 | Default: 0 |
| 1921 | 1922 | ||
| 1922 | xfrm6_gc_thresh - INTEGER | 1923 | xfrm6_gc_thresh - INTEGER |
| 1924 | (Obsolete since linux-4.14) | ||
| 1923 | The threshold at which we will start garbage collecting for IPv6 | 1925 | The threshold at which we will start garbage collecting for IPv6 |
| 1924 | destination cache entries. At twice this value the system will | 1926 | destination cache entries. At twice this value the system will |
| 1925 | refuse new allocations. | 1927 | refuse new allocations. |
diff --git a/Documentation/networking/netdev-FAQ.rst b/Documentation/networking/netdev-FAQ.rst index 8c7a713cf657..642fa963be3c 100644 --- a/Documentation/networking/netdev-FAQ.rst +++ b/Documentation/networking/netdev-FAQ.rst | |||
| @@ -132,7 +132,7 @@ version that should be applied. If there is any doubt, the maintainer | |||
| 132 | will reply and ask what should be done. | 132 | will reply and ask what should be done. |
| 133 | 133 | ||
| 134 | Q: I made changes to only a few patches in a patch series should I resend only those changed? | 134 | Q: I made changes to only a few patches in a patch series should I resend only those changed? |
| 135 | -------------------------------------------------------------------------------------------- | 135 | --------------------------------------------------------------------------------------------- |
| 136 | A: No, please resend the entire patch series and make sure you do number your | 136 | A: No, please resend the entire patch series and make sure you do number your |
| 137 | patches such that it is clear this is the latest and greatest set of patches | 137 | patches such that it is clear this is the latest and greatest set of patches |
| 138 | that can be applied. | 138 | that can be applied. |
diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 0effd3cba9a7..98bf0c222b5f 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c | |||
| @@ -186,8 +186,9 @@ enum which_ebpf_reg { | |||
| 186 | * separate frame pointer, so BPF_REG_10 relative accesses are | 186 | * separate frame pointer, so BPF_REG_10 relative accesses are |
| 187 | * adjusted to be $sp relative. | 187 | * adjusted to be $sp relative. |
| 188 | */ | 188 | */ |
| 189 | int ebpf_to_mips_reg(struct jit_ctx *ctx, const struct bpf_insn *insn, | 189 | static int ebpf_to_mips_reg(struct jit_ctx *ctx, |
| 190 | enum which_ebpf_reg w) | 190 | const struct bpf_insn *insn, |
| 191 | enum which_ebpf_reg w) | ||
| 191 | { | 192 | { |
| 192 | int ebpf_reg = (w == src_reg || w == src_reg_no_fp) ? | 193 | int ebpf_reg = (w == src_reg || w == src_reg_no_fp) ? |
| 193 | insn->src_reg : insn->dst_reg; | 194 | insn->src_reg : insn->dst_reg; |
diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c index e6234d209787..4212bc4a5f31 100644 --- a/drivers/net/dsa/bcm_sf2_cfp.c +++ b/drivers/net/dsa/bcm_sf2_cfp.c | |||
| @@ -886,6 +886,9 @@ static int bcm_sf2_cfp_rule_set(struct dsa_switch *ds, int port, | |||
| 886 | fs->m_ext.data[1])) | 886 | fs->m_ext.data[1])) |
| 887 | return -EINVAL; | 887 | return -EINVAL; |
| 888 | 888 | ||
| 889 | if (fs->location != RX_CLS_LOC_ANY && fs->location >= CFP_NUM_RULES) | ||
| 890 | return -EINVAL; | ||
| 891 | |||
| 889 | if (fs->location != RX_CLS_LOC_ANY && | 892 | if (fs->location != RX_CLS_LOC_ANY && |
| 890 | test_bit(fs->location, priv->cfp.used)) | 893 | test_bit(fs->location, priv->cfp.used)) |
| 891 | return -EBUSY; | 894 | return -EBUSY; |
| @@ -974,6 +977,9 @@ static int bcm_sf2_cfp_rule_del(struct bcm_sf2_priv *priv, int port, u32 loc) | |||
| 974 | struct cfp_rule *rule; | 977 | struct cfp_rule *rule; |
| 975 | int ret; | 978 | int ret; |
| 976 | 979 | ||
| 980 | if (loc >= CFP_NUM_RULES) | ||
| 981 | return -EINVAL; | ||
| 982 | |||
| 977 | /* Refuse deleting unused rules, and those that are not unique since | 983 | /* Refuse deleting unused rules, and those that are not unique since |
| 978 | * that could leave IPv6 rules with one of the chained rule in the | 984 | * that could leave IPv6 rules with one of the chained rule in the |
| 979 | * table. | 985 | * table. |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 4c586ba4364b..52ade133b57c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -1625,7 +1625,7 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
| 1625 | netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); | 1625 | netdev_warn(bp->dev, "RX buffer error %x\n", rx_err); |
| 1626 | bnxt_sched_reset(bp, rxr); | 1626 | bnxt_sched_reset(bp, rxr); |
| 1627 | } | 1627 | } |
| 1628 | goto next_rx; | 1628 | goto next_rx_no_len; |
| 1629 | } | 1629 | } |
| 1630 | 1630 | ||
| 1631 | len = le32_to_cpu(rxcmp->rx_cmp_len_flags_type) >> RX_CMP_LEN_SHIFT; | 1631 | len = le32_to_cpu(rxcmp->rx_cmp_len_flags_type) >> RX_CMP_LEN_SHIFT; |
| @@ -1706,12 +1706,13 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, | |||
| 1706 | rc = 1; | 1706 | rc = 1; |
| 1707 | 1707 | ||
| 1708 | next_rx: | 1708 | next_rx: |
| 1709 | rxr->rx_prod = NEXT_RX(prod); | ||
| 1710 | rxr->rx_next_cons = NEXT_RX(cons); | ||
| 1711 | |||
| 1712 | cpr->rx_packets += 1; | 1709 | cpr->rx_packets += 1; |
| 1713 | cpr->rx_bytes += len; | 1710 | cpr->rx_bytes += len; |
| 1714 | 1711 | ||
| 1712 | next_rx_no_len: | ||
| 1713 | rxr->rx_prod = NEXT_RX(prod); | ||
| 1714 | rxr->rx_next_cons = NEXT_RX(cons); | ||
| 1715 | |||
| 1715 | next_rx_no_prod_no_len: | 1716 | next_rx_no_prod_no_len: |
| 1716 | *raw_cons = tmp_raw_cons; | 1717 | *raw_cons = tmp_raw_cons; |
| 1717 | 1718 | ||
| @@ -5135,10 +5136,10 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path) | |||
| 5135 | for (i = 0; i < bp->tx_nr_rings; i++) { | 5136 | for (i = 0; i < bp->tx_nr_rings; i++) { |
| 5136 | struct bnxt_tx_ring_info *txr = &bp->tx_ring[i]; | 5137 | struct bnxt_tx_ring_info *txr = &bp->tx_ring[i]; |
| 5137 | struct bnxt_ring_struct *ring = &txr->tx_ring_struct; | 5138 | struct bnxt_ring_struct *ring = &txr->tx_ring_struct; |
| 5138 | u32 cmpl_ring_id; | ||
| 5139 | 5139 | ||
| 5140 | cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr); | ||
| 5141 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { | 5140 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { |
| 5141 | u32 cmpl_ring_id = bnxt_cp_ring_for_tx(bp, txr); | ||
| 5142 | |||
| 5142 | hwrm_ring_free_send_msg(bp, ring, | 5143 | hwrm_ring_free_send_msg(bp, ring, |
| 5143 | RING_FREE_REQ_RING_TYPE_TX, | 5144 | RING_FREE_REQ_RING_TYPE_TX, |
| 5144 | close_path ? cmpl_ring_id : | 5145 | close_path ? cmpl_ring_id : |
| @@ -5151,10 +5152,10 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path) | |||
| 5151 | struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; | 5152 | struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; |
| 5152 | struct bnxt_ring_struct *ring = &rxr->rx_ring_struct; | 5153 | struct bnxt_ring_struct *ring = &rxr->rx_ring_struct; |
| 5153 | u32 grp_idx = rxr->bnapi->index; | 5154 | u32 grp_idx = rxr->bnapi->index; |
| 5154 | u32 cmpl_ring_id; | ||
| 5155 | 5155 | ||
| 5156 | cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); | ||
| 5157 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { | 5156 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { |
| 5157 | u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); | ||
| 5158 | |||
| 5158 | hwrm_ring_free_send_msg(bp, ring, | 5159 | hwrm_ring_free_send_msg(bp, ring, |
| 5159 | RING_FREE_REQ_RING_TYPE_RX, | 5160 | RING_FREE_REQ_RING_TYPE_RX, |
| 5160 | close_path ? cmpl_ring_id : | 5161 | close_path ? cmpl_ring_id : |
| @@ -5173,10 +5174,10 @@ static void bnxt_hwrm_ring_free(struct bnxt *bp, bool close_path) | |||
| 5173 | struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; | 5174 | struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i]; |
| 5174 | struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct; | 5175 | struct bnxt_ring_struct *ring = &rxr->rx_agg_ring_struct; |
| 5175 | u32 grp_idx = rxr->bnapi->index; | 5176 | u32 grp_idx = rxr->bnapi->index; |
| 5176 | u32 cmpl_ring_id; | ||
| 5177 | 5177 | ||
| 5178 | cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); | ||
| 5179 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { | 5178 | if (ring->fw_ring_id != INVALID_HW_RING_ID) { |
| 5179 | u32 cmpl_ring_id = bnxt_cp_ring_for_rx(bp, rxr); | ||
| 5180 | |||
| 5180 | hwrm_ring_free_send_msg(bp, ring, type, | 5181 | hwrm_ring_free_send_msg(bp, ring, type, |
| 5181 | close_path ? cmpl_ring_id : | 5182 | close_path ? cmpl_ring_id : |
| 5182 | INVALID_HW_RING_ID); | 5183 | INVALID_HW_RING_ID); |
| @@ -5315,17 +5316,16 @@ __bnxt_hwrm_reserve_pf_rings(struct bnxt *bp, struct hwrm_func_cfg_input *req, | |||
| 5315 | req->num_tx_rings = cpu_to_le16(tx_rings); | 5316 | req->num_tx_rings = cpu_to_le16(tx_rings); |
| 5316 | if (BNXT_NEW_RM(bp)) { | 5317 | if (BNXT_NEW_RM(bp)) { |
| 5317 | enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; | 5318 | enables |= rx_rings ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0; |
| 5319 | enables |= stats ? FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5318 | if (bp->flags & BNXT_FLAG_CHIP_P5) { | 5320 | if (bp->flags & BNXT_FLAG_CHIP_P5) { |
| 5319 | enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_MSIX : 0; | 5321 | enables |= cp_rings ? FUNC_CFG_REQ_ENABLES_NUM_MSIX : 0; |
| 5320 | enables |= tx_rings + ring_grps ? | 5322 | enables |= tx_rings + ring_grps ? |
| 5321 | FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | 5323 | FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; |
| 5322 | FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5323 | enables |= rx_rings ? | 5324 | enables |= rx_rings ? |
| 5324 | FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; | 5325 | FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; |
| 5325 | } else { | 5326 | } else { |
| 5326 | enables |= cp_rings ? | 5327 | enables |= cp_rings ? |
| 5327 | FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | 5328 | FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; |
| 5328 | FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5329 | enables |= ring_grps ? | 5329 | enables |= ring_grps ? |
| 5330 | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS | | 5330 | FUNC_CFG_REQ_ENABLES_NUM_HW_RING_GRPS | |
| 5331 | FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; | 5331 | FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; |
| @@ -5365,14 +5365,13 @@ __bnxt_hwrm_reserve_vf_rings(struct bnxt *bp, | |||
| 5365 | enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; | 5365 | enables |= tx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_TX_RINGS : 0; |
| 5366 | enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS | | 5366 | enables |= rx_rings ? FUNC_VF_CFG_REQ_ENABLES_NUM_RX_RINGS | |
| 5367 | FUNC_VF_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; | 5367 | FUNC_VF_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0; |
| 5368 | enables |= stats ? FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5368 | if (bp->flags & BNXT_FLAG_CHIP_P5) { | 5369 | if (bp->flags & BNXT_FLAG_CHIP_P5) { |
| 5369 | enables |= tx_rings + ring_grps ? | 5370 | enables |= tx_rings + ring_grps ? |
| 5370 | FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | 5371 | FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; |
| 5371 | FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5372 | } else { | 5372 | } else { |
| 5373 | enables |= cp_rings ? | 5373 | enables |= cp_rings ? |
| 5374 | FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS | | 5374 | FUNC_VF_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0; |
| 5375 | FUNC_VF_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0; | ||
| 5376 | enables |= ring_grps ? | 5375 | enables |= ring_grps ? |
| 5377 | FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; | 5376 | FUNC_VF_CFG_REQ_ENABLES_NUM_HW_RING_GRPS : 0; |
| 5378 | } | 5377 | } |
| @@ -6753,6 +6752,7 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp) | |||
| 6753 | struct hwrm_queue_pri2cos_qcfg_input req2 = {0}; | 6752 | struct hwrm_queue_pri2cos_qcfg_input req2 = {0}; |
| 6754 | struct hwrm_port_qstats_ext_input req = {0}; | 6753 | struct hwrm_port_qstats_ext_input req = {0}; |
| 6755 | struct bnxt_pf_info *pf = &bp->pf; | 6754 | struct bnxt_pf_info *pf = &bp->pf; |
| 6755 | u32 tx_stat_size; | ||
| 6756 | int rc; | 6756 | int rc; |
| 6757 | 6757 | ||
| 6758 | if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT)) | 6758 | if (!(bp->flags & BNXT_FLAG_PORT_STATS_EXT)) |
| @@ -6762,13 +6762,16 @@ static int bnxt_hwrm_port_qstats_ext(struct bnxt *bp) | |||
| 6762 | req.port_id = cpu_to_le16(pf->port_id); | 6762 | req.port_id = cpu_to_le16(pf->port_id); |
| 6763 | req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext)); | 6763 | req.rx_stat_size = cpu_to_le16(sizeof(struct rx_port_stats_ext)); |
| 6764 | req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map); | 6764 | req.rx_stat_host_addr = cpu_to_le64(bp->hw_rx_port_stats_ext_map); |
| 6765 | req.tx_stat_size = cpu_to_le16(sizeof(struct tx_port_stats_ext)); | 6765 | tx_stat_size = bp->hw_tx_port_stats_ext ? |
| 6766 | sizeof(*bp->hw_tx_port_stats_ext) : 0; | ||
| 6767 | req.tx_stat_size = cpu_to_le16(tx_stat_size); | ||
| 6766 | req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_ext_map); | 6768 | req.tx_stat_host_addr = cpu_to_le64(bp->hw_tx_port_stats_ext_map); |
| 6767 | mutex_lock(&bp->hwrm_cmd_lock); | 6769 | mutex_lock(&bp->hwrm_cmd_lock); |
| 6768 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); | 6770 | rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); |
| 6769 | if (!rc) { | 6771 | if (!rc) { |
| 6770 | bp->fw_rx_stats_ext_size = le16_to_cpu(resp->rx_stat_size) / 8; | 6772 | bp->fw_rx_stats_ext_size = le16_to_cpu(resp->rx_stat_size) / 8; |
| 6771 | bp->fw_tx_stats_ext_size = le16_to_cpu(resp->tx_stat_size) / 8; | 6773 | bp->fw_tx_stats_ext_size = tx_stat_size ? |
| 6774 | le16_to_cpu(resp->tx_stat_size) / 8 : 0; | ||
| 6772 | } else { | 6775 | } else { |
| 6773 | bp->fw_rx_stats_ext_size = 0; | 6776 | bp->fw_rx_stats_ext_size = 0; |
| 6774 | bp->fw_tx_stats_ext_size = 0; | 6777 | bp->fw_tx_stats_ext_size = 0; |
| @@ -8961,8 +8964,15 @@ static int bnxt_cfg_rx_mode(struct bnxt *bp) | |||
| 8961 | 8964 | ||
| 8962 | skip_uc: | 8965 | skip_uc: |
| 8963 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); | 8966 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); |
| 8967 | if (rc && vnic->mc_list_count) { | ||
| 8968 | netdev_info(bp->dev, "Failed setting MC filters rc: %d, turning on ALL_MCAST mode\n", | ||
| 8969 | rc); | ||
| 8970 | vnic->rx_mask |= CFA_L2_SET_RX_MASK_REQ_MASK_ALL_MCAST; | ||
| 8971 | vnic->mc_list_count = 0; | ||
| 8972 | rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, 0); | ||
| 8973 | } | ||
| 8964 | if (rc) | 8974 | if (rc) |
| 8965 | netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %x\n", | 8975 | netdev_err(bp->dev, "HWRM cfa l2 rx mask failure rc: %d\n", |
| 8966 | rc); | 8976 | rc); |
| 8967 | 8977 | ||
| 8968 | return rc; | 8978 | return rc; |
| @@ -10685,6 +10695,7 @@ init_err_cleanup_tc: | |||
| 10685 | bnxt_clear_int_mode(bp); | 10695 | bnxt_clear_int_mode(bp); |
| 10686 | 10696 | ||
| 10687 | init_err_pci_clean: | 10697 | init_err_pci_clean: |
| 10698 | bnxt_free_hwrm_short_cmd_req(bp); | ||
| 10688 | bnxt_free_hwrm_resources(bp); | 10699 | bnxt_free_hwrm_resources(bp); |
| 10689 | bnxt_free_ctx_mem(bp); | 10700 | bnxt_free_ctx_mem(bp); |
| 10690 | kfree(bp->ctx); | 10701 | kfree(bp->ctx); |
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c index 062a600fa5a7..21428537e231 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-stm32.c | |||
| @@ -333,6 +333,9 @@ static int stm32mp1_parse_data(struct stm32_dwmac *dwmac, | |||
| 333 | */ | 333 | */ |
| 334 | dwmac->irq_pwr_wakeup = platform_get_irq_byname(pdev, | 334 | dwmac->irq_pwr_wakeup = platform_get_irq_byname(pdev, |
| 335 | "stm32_pwr_wakeup"); | 335 | "stm32_pwr_wakeup"); |
| 336 | if (dwmac->irq_pwr_wakeup == -EPROBE_DEFER) | ||
| 337 | return -EPROBE_DEFER; | ||
| 338 | |||
| 336 | if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { | 339 | if (!dwmac->clk_eth_ck && dwmac->irq_pwr_wakeup >= 0) { |
| 337 | err = device_init_wakeup(&pdev->dev, true); | 340 | err = device_init_wakeup(&pdev->dev, true); |
| 338 | if (err) { | 341 | if (err) { |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index cc1e887e47b5..26db6aa002d1 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | |||
| @@ -160,7 +160,7 @@ static const struct dmi_system_id quark_pci_dmi[] = { | |||
| 160 | .driver_data = (void *)&galileo_stmmac_dmi_data, | 160 | .driver_data = (void *)&galileo_stmmac_dmi_data, |
| 161 | }, | 161 | }, |
| 162 | /* | 162 | /* |
| 163 | * There are 2 types of SIMATIC IOT2000: IOT20202 and IOT2040. | 163 | * There are 2 types of SIMATIC IOT2000: IOT2020 and IOT2040. |
| 164 | * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which | 164 | * The asset tag "6ES7647-0AA00-0YA2" is only for IOT2020 which |
| 165 | * has only one pci network device while other asset tags are | 165 | * has only one pci network device while other asset tags are |
| 166 | * for IOT2040 which has two. | 166 | * for IOT2040 which has two. |
diff --git a/drivers/net/ieee802154/mcr20a.c b/drivers/net/ieee802154/mcr20a.c index c589f5ae75bb..8bb53ec8d9cf 100644 --- a/drivers/net/ieee802154/mcr20a.c +++ b/drivers/net/ieee802154/mcr20a.c | |||
| @@ -533,6 +533,8 @@ mcr20a_start(struct ieee802154_hw *hw) | |||
| 533 | dev_dbg(printdev(lp), "no slotted operation\n"); | 533 | dev_dbg(printdev(lp), "no slotted operation\n"); |
| 534 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | 534 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, |
| 535 | DAR_PHY_CTRL1_SLOTTED, 0x0); | 535 | DAR_PHY_CTRL1_SLOTTED, 0x0); |
| 536 | if (ret < 0) | ||
| 537 | return ret; | ||
| 536 | 538 | ||
| 537 | /* enable irq */ | 539 | /* enable irq */ |
| 538 | enable_irq(lp->spi->irq); | 540 | enable_irq(lp->spi->irq); |
| @@ -540,11 +542,15 @@ mcr20a_start(struct ieee802154_hw *hw) | |||
| 540 | /* Unmask SEQ interrupt */ | 542 | /* Unmask SEQ interrupt */ |
| 541 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL2, | 543 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL2, |
| 542 | DAR_PHY_CTRL2_SEQMSK, 0x0); | 544 | DAR_PHY_CTRL2_SEQMSK, 0x0); |
| 545 | if (ret < 0) | ||
| 546 | return ret; | ||
| 543 | 547 | ||
| 544 | /* Start the RX sequence */ | 548 | /* Start the RX sequence */ |
| 545 | dev_dbg(printdev(lp), "start the RX sequence\n"); | 549 | dev_dbg(printdev(lp), "start the RX sequence\n"); |
| 546 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, | 550 | ret = regmap_update_bits(lp->regmap_dar, DAR_PHY_CTRL1, |
| 547 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX); | 551 | DAR_PHY_CTRL1_XCVSEQ_MASK, MCR20A_XCVSEQ_RX); |
| 552 | if (ret < 0) | ||
| 553 | return ret; | ||
| 548 | 554 | ||
| 549 | return 0; | 555 | return 0; |
| 550 | } | 556 | } |
diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c index 3ccba37bd6dd..f76c4048b978 100644 --- a/drivers/net/phy/marvell.c +++ b/drivers/net/phy/marvell.c | |||
| @@ -1489,9 +1489,10 @@ static int marvell_get_sset_count(struct phy_device *phydev) | |||
| 1489 | 1489 | ||
| 1490 | static void marvell_get_strings(struct phy_device *phydev, u8 *data) | 1490 | static void marvell_get_strings(struct phy_device *phydev, u8 *data) |
| 1491 | { | 1491 | { |
| 1492 | int count = marvell_get_sset_count(phydev); | ||
| 1492 | int i; | 1493 | int i; |
| 1493 | 1494 | ||
| 1494 | for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) { | 1495 | for (i = 0; i < count; i++) { |
| 1495 | strlcpy(data + i * ETH_GSTRING_LEN, | 1496 | strlcpy(data + i * ETH_GSTRING_LEN, |
| 1496 | marvell_hw_stats[i].string, ETH_GSTRING_LEN); | 1497 | marvell_hw_stats[i].string, ETH_GSTRING_LEN); |
| 1497 | } | 1498 | } |
| @@ -1519,9 +1520,10 @@ static u64 marvell_get_stat(struct phy_device *phydev, int i) | |||
| 1519 | static void marvell_get_stats(struct phy_device *phydev, | 1520 | static void marvell_get_stats(struct phy_device *phydev, |
| 1520 | struct ethtool_stats *stats, u64 *data) | 1521 | struct ethtool_stats *stats, u64 *data) |
| 1521 | { | 1522 | { |
| 1523 | int count = marvell_get_sset_count(phydev); | ||
| 1522 | int i; | 1524 | int i; |
| 1523 | 1525 | ||
| 1524 | for (i = 0; i < ARRAY_SIZE(marvell_hw_stats); i++) | 1526 | for (i = 0; i < count; i++) |
| 1525 | data[i] = marvell_get_stat(phydev, i); | 1527 | data[i] = marvell_get_stat(phydev, i); |
| 1526 | } | 1528 | } |
| 1527 | 1529 | ||
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 9195f3476b1d..679e404a5224 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
| @@ -1122,9 +1122,16 @@ static const struct usb_device_id products[] = { | |||
| 1122 | {QMI_FIXED_INTF(0x0846, 0x68d3, 8)}, /* Netgear Aircard 779S */ | 1122 | {QMI_FIXED_INTF(0x0846, 0x68d3, 8)}, /* Netgear Aircard 779S */ |
| 1123 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | 1123 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ |
| 1124 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ | 1124 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ |
| 1125 | {QMI_FIXED_INTF(0x1435, 0x0918, 3)}, /* Wistron NeWeb D16Q1 */ | ||
| 1126 | {QMI_FIXED_INTF(0x1435, 0x0918, 4)}, /* Wistron NeWeb D16Q1 */ | ||
| 1127 | {QMI_FIXED_INTF(0x1435, 0x0918, 5)}, /* Wistron NeWeb D16Q1 */ | ||
| 1128 | {QMI_FIXED_INTF(0x1435, 0x3185, 4)}, /* Wistron NeWeb M18Q5 */ | ||
| 1129 | {QMI_FIXED_INTF(0x1435, 0xd111, 4)}, /* M9615A DM11-1 D51QC */ | ||
| 1125 | {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */ | 1130 | {QMI_FIXED_INTF(0x1435, 0xd181, 3)}, /* Wistron NeWeb D18Q1 */ |
| 1126 | {QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */ | 1131 | {QMI_FIXED_INTF(0x1435, 0xd181, 4)}, /* Wistron NeWeb D18Q1 */ |
| 1127 | {QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */ | 1132 | {QMI_FIXED_INTF(0x1435, 0xd181, 5)}, /* Wistron NeWeb D18Q1 */ |
| 1133 | {QMI_FIXED_INTF(0x1435, 0xd182, 4)}, /* Wistron NeWeb D18 */ | ||
| 1134 | {QMI_FIXED_INTF(0x1435, 0xd182, 5)}, /* Wistron NeWeb D18 */ | ||
| 1128 | {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ | 1135 | {QMI_FIXED_INTF(0x1435, 0xd191, 4)}, /* Wistron NeWeb D19Q1 */ |
| 1129 | {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ | 1136 | {QMI_QUIRK_SET_DTR(0x1508, 0x1001, 4)}, /* Fibocom NL668 series */ |
| 1130 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ | 1137 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ |
| @@ -1180,6 +1187,7 @@ static const struct usb_device_id products[] = { | |||
| 1180 | {QMI_FIXED_INTF(0x19d2, 0x0265, 4)}, /* ONDA MT8205 4G LTE */ | 1187 | {QMI_FIXED_INTF(0x19d2, 0x0265, 4)}, /* ONDA MT8205 4G LTE */ |
| 1181 | {QMI_FIXED_INTF(0x19d2, 0x0284, 4)}, /* ZTE MF880 */ | 1188 | {QMI_FIXED_INTF(0x19d2, 0x0284, 4)}, /* ZTE MF880 */ |
| 1182 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ | 1189 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ |
| 1190 | {QMI_FIXED_INTF(0x19d2, 0x0396, 3)}, /* ZTE ZM8620 */ | ||
| 1183 | {QMI_FIXED_INTF(0x19d2, 0x0412, 4)}, /* Telewell TW-LTE 4G */ | 1191 | {QMI_FIXED_INTF(0x19d2, 0x0412, 4)}, /* Telewell TW-LTE 4G */ |
| 1184 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ | 1192 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ |
| 1185 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ | 1193 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ |
| @@ -1200,7 +1208,9 @@ static const struct usb_device_id products[] = { | |||
| 1200 | {QMI_FIXED_INTF(0x19d2, 0x1425, 2)}, | 1208 | {QMI_FIXED_INTF(0x19d2, 0x1425, 2)}, |
| 1201 | {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ | 1209 | {QMI_FIXED_INTF(0x19d2, 0x1426, 2)}, /* ZTE MF91 */ |
| 1202 | {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ | 1210 | {QMI_FIXED_INTF(0x19d2, 0x1428, 2)}, /* Telewell TW-LTE 4G v2 */ |
| 1211 | {QMI_FIXED_INTF(0x19d2, 0x1432, 3)}, /* ZTE ME3620 */ | ||
| 1203 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ | 1212 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ |
| 1213 | {QMI_FIXED_INTF(0x2001, 0x7e16, 3)}, /* D-Link DWM-221 */ | ||
| 1204 | {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ | 1214 | {QMI_FIXED_INTF(0x2001, 0x7e19, 4)}, /* D-Link DWM-221 B1 */ |
| 1205 | {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ | 1215 | {QMI_FIXED_INTF(0x2001, 0x7e35, 4)}, /* D-Link DWM-222 */ |
| 1206 | {QMI_FIXED_INTF(0x2020, 0x2031, 4)}, /* Olicard 600 */ | 1216 | {QMI_FIXED_INTF(0x2020, 0x2031, 4)}, /* Olicard 600 */ |
diff --git a/drivers/net/wireless/ath/ath10k/ce.c b/drivers/net/wireless/ath/ath10k/ce.c index 24b983edb357..eca87f7c5b6c 100644 --- a/drivers/net/wireless/ath/ath10k/ce.c +++ b/drivers/net/wireless/ath/ath10k/ce.c | |||
| @@ -1855,7 +1855,7 @@ void ath10k_ce_dump_registers(struct ath10k *ar, | |||
| 1855 | struct ath10k_ce_crash_data ce_data; | 1855 | struct ath10k_ce_crash_data ce_data; |
| 1856 | u32 addr, id; | 1856 | u32 addr, id; |
| 1857 | 1857 | ||
| 1858 | lockdep_assert_held(&ar->data_lock); | 1858 | lockdep_assert_held(&ar->dump_mutex); |
| 1859 | 1859 | ||
| 1860 | ath10k_err(ar, "Copy Engine register dump:\n"); | 1860 | ath10k_err(ar, "Copy Engine register dump:\n"); |
| 1861 | 1861 | ||
diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c index 835b8de92d55..aff585658fc0 100644 --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c | |||
| @@ -3119,6 +3119,7 @@ struct ath10k *ath10k_core_create(size_t priv_size, struct device *dev, | |||
| 3119 | goto err_free_wq; | 3119 | goto err_free_wq; |
| 3120 | 3120 | ||
| 3121 | mutex_init(&ar->conf_mutex); | 3121 | mutex_init(&ar->conf_mutex); |
| 3122 | mutex_init(&ar->dump_mutex); | ||
| 3122 | spin_lock_init(&ar->data_lock); | 3123 | spin_lock_init(&ar->data_lock); |
| 3123 | 3124 | ||
| 3124 | INIT_LIST_HEAD(&ar->peers); | 3125 | INIT_LIST_HEAD(&ar->peers); |
diff --git a/drivers/net/wireless/ath/ath10k/core.h b/drivers/net/wireless/ath/ath10k/core.h index e08a17b01e03..e35aae5146f1 100644 --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h | |||
| @@ -1063,6 +1063,9 @@ struct ath10k { | |||
| 1063 | /* prevents concurrent FW reconfiguration */ | 1063 | /* prevents concurrent FW reconfiguration */ |
| 1064 | struct mutex conf_mutex; | 1064 | struct mutex conf_mutex; |
| 1065 | 1065 | ||
| 1066 | /* protects coredump data */ | ||
| 1067 | struct mutex dump_mutex; | ||
| 1068 | |||
| 1066 | /* protects shared structure data */ | 1069 | /* protects shared structure data */ |
| 1067 | spinlock_t data_lock; | 1070 | spinlock_t data_lock; |
| 1068 | 1071 | ||
diff --git a/drivers/net/wireless/ath/ath10k/coredump.c b/drivers/net/wireless/ath/ath10k/coredump.c index 33838d9c1cb6..45a355fb62b9 100644 --- a/drivers/net/wireless/ath/ath10k/coredump.c +++ b/drivers/net/wireless/ath/ath10k/coredump.c | |||
| @@ -1102,7 +1102,7 @@ struct ath10k_fw_crash_data *ath10k_coredump_new(struct ath10k *ar) | |||
| 1102 | { | 1102 | { |
| 1103 | struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data; | 1103 | struct ath10k_fw_crash_data *crash_data = ar->coredump.fw_crash_data; |
| 1104 | 1104 | ||
| 1105 | lockdep_assert_held(&ar->data_lock); | 1105 | lockdep_assert_held(&ar->dump_mutex); |
| 1106 | 1106 | ||
| 1107 | if (ath10k_coredump_mask == 0) | 1107 | if (ath10k_coredump_mask == 0) |
| 1108 | /* coredump disabled */ | 1108 | /* coredump disabled */ |
| @@ -1146,7 +1146,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar) | |||
| 1146 | if (!buf) | 1146 | if (!buf) |
| 1147 | return NULL; | 1147 | return NULL; |
| 1148 | 1148 | ||
| 1149 | spin_lock_bh(&ar->data_lock); | 1149 | mutex_lock(&ar->dump_mutex); |
| 1150 | 1150 | ||
| 1151 | dump_data = (struct ath10k_dump_file_data *)(buf); | 1151 | dump_data = (struct ath10k_dump_file_data *)(buf); |
| 1152 | strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", | 1152 | strlcpy(dump_data->df_magic, "ATH10K-FW-DUMP", |
| @@ -1213,7 +1213,7 @@ static struct ath10k_dump_file_data *ath10k_coredump_build(struct ath10k *ar) | |||
| 1213 | sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len; | 1213 | sofar += sizeof(*dump_tlv) + crash_data->ramdump_buf_len; |
| 1214 | } | 1214 | } |
| 1215 | 1215 | ||
| 1216 | spin_unlock_bh(&ar->data_lock); | 1216 | mutex_unlock(&ar->dump_mutex); |
| 1217 | 1217 | ||
| 1218 | return dump_data; | 1218 | return dump_data; |
| 1219 | } | 1219 | } |
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c index 41e89db244d2..9c703d287333 100644 --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c | |||
| @@ -5774,7 +5774,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
| 5774 | } | 5774 | } |
| 5775 | 5775 | ||
| 5776 | if (changed & BSS_CHANGED_MCAST_RATE && | 5776 | if (changed & BSS_CHANGED_MCAST_RATE && |
| 5777 | !WARN_ON(ath10k_mac_vif_chan(arvif->vif, &def))) { | 5777 | !ath10k_mac_vif_chan(arvif->vif, &def)) { |
| 5778 | band = def.chan->band; | 5778 | band = def.chan->band; |
| 5779 | rateidx = vif->bss_conf.mcast_rate[band] - 1; | 5779 | rateidx = vif->bss_conf.mcast_rate[band] - 1; |
| 5780 | 5780 | ||
| @@ -5812,7 +5812,7 @@ static void ath10k_bss_info_changed(struct ieee80211_hw *hw, | |||
| 5812 | } | 5812 | } |
| 5813 | 5813 | ||
| 5814 | if (changed & BSS_CHANGED_BASIC_RATES) { | 5814 | if (changed & BSS_CHANGED_BASIC_RATES) { |
| 5815 | if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) { | 5815 | if (ath10k_mac_vif_chan(vif, &def)) { |
| 5816 | mutex_unlock(&ar->conf_mutex); | 5816 | mutex_unlock(&ar->conf_mutex); |
| 5817 | return; | 5817 | return; |
| 5818 | } | 5818 | } |
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c index 271f92c24d44..2c27f407a851 100644 --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c | |||
| @@ -1441,7 +1441,7 @@ static void ath10k_pci_dump_registers(struct ath10k *ar, | |||
| 1441 | __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; | 1441 | __le32 reg_dump_values[REG_DUMP_COUNT_QCA988X] = {}; |
| 1442 | int i, ret; | 1442 | int i, ret; |
| 1443 | 1443 | ||
| 1444 | lockdep_assert_held(&ar->data_lock); | 1444 | lockdep_assert_held(&ar->dump_mutex); |
| 1445 | 1445 | ||
| 1446 | ret = ath10k_pci_diag_read_hi(ar, ®_dump_values[0], | 1446 | ret = ath10k_pci_diag_read_hi(ar, ®_dump_values[0], |
| 1447 | hi_failure_state, | 1447 | hi_failure_state, |
| @@ -1656,7 +1656,7 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, | |||
| 1656 | int ret, i; | 1656 | int ret, i; |
| 1657 | u8 *buf; | 1657 | u8 *buf; |
| 1658 | 1658 | ||
| 1659 | lockdep_assert_held(&ar->data_lock); | 1659 | lockdep_assert_held(&ar->dump_mutex); |
| 1660 | 1660 | ||
| 1661 | if (!crash_data) | 1661 | if (!crash_data) |
| 1662 | return; | 1662 | return; |
| @@ -1734,14 +1734,19 @@ static void ath10k_pci_dump_memory(struct ath10k *ar, | |||
| 1734 | } | 1734 | } |
| 1735 | } | 1735 | } |
| 1736 | 1736 | ||
| 1737 | static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) | 1737 | static void ath10k_pci_fw_dump_work(struct work_struct *work) |
| 1738 | { | 1738 | { |
| 1739 | struct ath10k_pci *ar_pci = container_of(work, struct ath10k_pci, | ||
| 1740 | dump_work); | ||
| 1739 | struct ath10k_fw_crash_data *crash_data; | 1741 | struct ath10k_fw_crash_data *crash_data; |
| 1742 | struct ath10k *ar = ar_pci->ar; | ||
| 1740 | char guid[UUID_STRING_LEN + 1]; | 1743 | char guid[UUID_STRING_LEN + 1]; |
| 1741 | 1744 | ||
| 1742 | spin_lock_bh(&ar->data_lock); | 1745 | mutex_lock(&ar->dump_mutex); |
| 1743 | 1746 | ||
| 1747 | spin_lock_bh(&ar->data_lock); | ||
| 1744 | ar->stats.fw_crash_counter++; | 1748 | ar->stats.fw_crash_counter++; |
| 1749 | spin_unlock_bh(&ar->data_lock); | ||
| 1745 | 1750 | ||
| 1746 | crash_data = ath10k_coredump_new(ar); | 1751 | crash_data = ath10k_coredump_new(ar); |
| 1747 | 1752 | ||
| @@ -1756,11 +1761,18 @@ static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) | |||
| 1756 | ath10k_ce_dump_registers(ar, crash_data); | 1761 | ath10k_ce_dump_registers(ar, crash_data); |
| 1757 | ath10k_pci_dump_memory(ar, crash_data); | 1762 | ath10k_pci_dump_memory(ar, crash_data); |
| 1758 | 1763 | ||
| 1759 | spin_unlock_bh(&ar->data_lock); | 1764 | mutex_unlock(&ar->dump_mutex); |
| 1760 | 1765 | ||
| 1761 | queue_work(ar->workqueue, &ar->restart_work); | 1766 | queue_work(ar->workqueue, &ar->restart_work); |
| 1762 | } | 1767 | } |
| 1763 | 1768 | ||
| 1769 | static void ath10k_pci_fw_crashed_dump(struct ath10k *ar) | ||
| 1770 | { | ||
| 1771 | struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); | ||
| 1772 | |||
| 1773 | queue_work(ar->workqueue, &ar_pci->dump_work); | ||
| 1774 | } | ||
| 1775 | |||
| 1764 | void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, | 1776 | void ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, |
| 1765 | int force) | 1777 | int force) |
| 1766 | { | 1778 | { |
| @@ -3442,6 +3454,8 @@ int ath10k_pci_setup_resource(struct ath10k *ar) | |||
| 3442 | spin_lock_init(&ar_pci->ps_lock); | 3454 | spin_lock_init(&ar_pci->ps_lock); |
| 3443 | mutex_init(&ar_pci->ce_diag_mutex); | 3455 | mutex_init(&ar_pci->ce_diag_mutex); |
| 3444 | 3456 | ||
| 3457 | INIT_WORK(&ar_pci->dump_work, ath10k_pci_fw_dump_work); | ||
| 3458 | |||
| 3445 | timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); | 3459 | timer_setup(&ar_pci->rx_post_retry, ath10k_pci_rx_replenish_retry, 0); |
| 3446 | 3460 | ||
| 3447 | if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) | 3461 | if (QCA_REV_6174(ar) || QCA_REV_9377(ar)) |
diff --git a/drivers/net/wireless/ath/ath10k/pci.h b/drivers/net/wireless/ath/ath10k/pci.h index 3773c79f322f..4455ed6c5275 100644 --- a/drivers/net/wireless/ath/ath10k/pci.h +++ b/drivers/net/wireless/ath/ath10k/pci.h | |||
| @@ -121,6 +121,8 @@ struct ath10k_pci { | |||
| 121 | /* For protecting ce_diag */ | 121 | /* For protecting ce_diag */ |
| 122 | struct mutex ce_diag_mutex; | 122 | struct mutex ce_diag_mutex; |
| 123 | 123 | ||
| 124 | struct work_struct dump_work; | ||
| 125 | |||
| 124 | struct ath10k_ce ce; | 126 | struct ath10k_ce ce; |
| 125 | struct timer_list rx_post_retry; | 127 | struct timer_list rx_post_retry; |
| 126 | 128 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c index eb6defb6d0cd..0a87d87fbb4f 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/22000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/22000.c | |||
| @@ -201,7 +201,7 @@ static const struct iwl_ht_params iwl_22000_ht_params = { | |||
| 201 | #define IWL_DEVICE_AX210 \ | 201 | #define IWL_DEVICE_AX210 \ |
| 202 | IWL_DEVICE_AX200_COMMON, \ | 202 | IWL_DEVICE_AX200_COMMON, \ |
| 203 | .device_family = IWL_DEVICE_FAMILY_AX210, \ | 203 | .device_family = IWL_DEVICE_FAMILY_AX210, \ |
| 204 | .base_params = &iwl_22000_base_params, \ | 204 | .base_params = &iwl_22560_base_params, \ |
| 205 | .csr = &iwl_csr_v1, \ | 205 | .csr = &iwl_csr_v1, \ |
| 206 | .min_txq_size = 128 | 206 | .min_txq_size = 128 |
| 207 | 207 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c index 575a7022d045..3846064d51a5 100644 --- a/drivers/net/wireless/intel/iwlwifi/cfg/5000.c +++ b/drivers/net/wireless/intel/iwlwifi/cfg/5000.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /****************************************************************************** | 1 | /****************************************************************************** |
| 2 | * | 2 | * |
| 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. | 3 | * Copyright(c) 2007 - 2014 Intel Corporation. All rights reserved. |
| 4 | * Copyright(c) 2018 Intel Corporation | 4 | * Copyright(c) 2018 - 2019 Intel Corporation |
| 5 | * | 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify it | 6 | * This program is free software; you can redistribute it and/or modify it |
| 7 | * under the terms of version 2 of the GNU General Public License as | 7 | * under the terms of version 2 of the GNU General Public License as |
| @@ -136,6 +136,7 @@ const struct iwl_cfg iwl5350_agn_cfg = { | |||
| 136 | .ht_params = &iwl5000_ht_params, | 136 | .ht_params = &iwl5000_ht_params, |
| 137 | .led_mode = IWL_LED_BLINK, | 137 | .led_mode = IWL_LED_BLINK, |
| 138 | .internal_wimax_coex = true, | 138 | .internal_wimax_coex = true, |
| 139 | .csr = &iwl_csr_v1, | ||
| 139 | }; | 140 | }; |
| 140 | 141 | ||
| 141 | #define IWL_DEVICE_5150 \ | 142 | #define IWL_DEVICE_5150 \ |
diff --git a/drivers/net/wireless/intel/iwlwifi/fw/file.h b/drivers/net/wireless/intel/iwlwifi/fw/file.h index 641c95d03b15..e06407dc088b 100644 --- a/drivers/net/wireless/intel/iwlwifi/fw/file.h +++ b/drivers/net/wireless/intel/iwlwifi/fw/file.h | |||
| @@ -93,7 +93,7 @@ struct iwl_ucode_header { | |||
| 93 | } u; | 93 | } u; |
| 94 | }; | 94 | }; |
| 95 | 95 | ||
| 96 | #define IWL_UCODE_INI_TLV_GROUP BIT(24) | 96 | #define IWL_UCODE_INI_TLV_GROUP 0x1000000 |
| 97 | 97 | ||
| 98 | /* | 98 | /* |
| 99 | * new TLV uCode file layout | 99 | * new TLV uCode file layout |
| @@ -148,11 +148,14 @@ enum iwl_ucode_tlv_type { | |||
| 148 | IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54, | 148 | IWL_UCODE_TLV_UMAC_DEBUG_ADDRS = 54, |
| 149 | IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55, | 149 | IWL_UCODE_TLV_LMAC_DEBUG_ADDRS = 55, |
| 150 | IWL_UCODE_TLV_FW_RECOVERY_INFO = 57, | 150 | IWL_UCODE_TLV_FW_RECOVERY_INFO = 57, |
| 151 | IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP | 0x1, | 151 | |
| 152 | IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP | 0x2, | 152 | IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION = IWL_UCODE_INI_TLV_GROUP + 0x1, |
| 153 | IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP | 0x3, | 153 | IWL_UCODE_TLV_DEBUG_BASE = IWL_UCODE_TLV_TYPE_BUFFER_ALLOCATION, |
| 154 | IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_INI_TLV_GROUP | 0x4, | 154 | IWL_UCODE_TLV_TYPE_HCMD = IWL_UCODE_INI_TLV_GROUP + 0x2, |
| 155 | IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_INI_TLV_GROUP | 0x5, | 155 | IWL_UCODE_TLV_TYPE_REGIONS = IWL_UCODE_INI_TLV_GROUP + 0x3, |
| 156 | IWL_UCODE_TLV_TYPE_TRIGGERS = IWL_UCODE_INI_TLV_GROUP + 0x4, | ||
| 157 | IWL_UCODE_TLV_TYPE_DEBUG_FLOW = IWL_UCODE_INI_TLV_GROUP + 0x5, | ||
| 158 | IWL_UCODE_TLV_DEBUG_MAX = IWL_UCODE_TLV_TYPE_DEBUG_FLOW, | ||
| 156 | 159 | ||
| 157 | /* TLVs 0x1000-0x2000 are for internal driver usage */ | 160 | /* TLVs 0x1000-0x2000 are for internal driver usage */ |
| 158 | IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000, | 161 | IWL_UCODE_TLV_FW_DBG_DUMP_LST = 0x1000, |
diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c index 5798f434f68f..c7070760a10a 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c | |||
| @@ -126,7 +126,8 @@ void iwl_alloc_dbg_tlv(struct iwl_trans *trans, size_t len, const u8 *data, | |||
| 126 | len -= ALIGN(tlv_len, 4); | 126 | len -= ALIGN(tlv_len, 4); |
| 127 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); | 127 | data += sizeof(*tlv) + ALIGN(tlv_len, 4); |
| 128 | 128 | ||
| 129 | if (!(tlv_type & IWL_UCODE_INI_TLV_GROUP)) | 129 | if (tlv_type < IWL_UCODE_TLV_DEBUG_BASE || |
| 130 | tlv_type > IWL_UCODE_TLV_DEBUG_MAX) | ||
| 130 | continue; | 131 | continue; |
| 131 | 132 | ||
| 132 | hdr = (void *)&tlv->data[0]; | 133 | hdr = (void *)&tlv->data[0]; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c index 2453ceabf00d..6925527d8457 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/debugfs-vif.c | |||
| @@ -774,8 +774,7 @@ void iwl_mvm_vif_dbgfs_register(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | |||
| 774 | return; | 774 | return; |
| 775 | 775 | ||
| 776 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); | 776 | mvmvif->dbgfs_dir = debugfs_create_dir("iwlmvm", dbgfs_dir); |
| 777 | 777 | if (IS_ERR_OR_NULL(mvmvif->dbgfs_dir)) { | |
| 778 | if (!mvmvif->dbgfs_dir) { | ||
| 779 | IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n", | 778 | IWL_ERR(mvm, "Failed to create debugfs directory under %pd\n", |
| 780 | dbgfs_dir); | 779 | dbgfs_dir); |
| 781 | return; | 780 | return; |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c index 00a47f6f1d81..ab68b5d53ec9 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/fw.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/fw.c | |||
| @@ -1121,7 +1121,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm) | |||
| 1121 | ret = iwl_mvm_load_rt_fw(mvm); | 1121 | ret = iwl_mvm_load_rt_fw(mvm); |
| 1122 | if (ret) { | 1122 | if (ret) { |
| 1123 | IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); | 1123 | IWL_ERR(mvm, "Failed to start RT ucode: %d\n", ret); |
| 1124 | iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); | 1124 | if (ret != -ERFKILL) |
| 1125 | iwl_fw_dbg_error_collect(&mvm->fwrt, | ||
| 1126 | FW_DBG_TRIGGER_DRIVER); | ||
| 1125 | goto error; | 1127 | goto error; |
| 1126 | } | 1128 | } |
| 1127 | 1129 | ||
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c index ba27dce4c2bb..13681b03c10e 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/ops.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/ops.c | |||
| @@ -834,7 +834,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, | |||
| 834 | mutex_lock(&mvm->mutex); | 834 | mutex_lock(&mvm->mutex); |
| 835 | iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); | 835 | iwl_mvm_ref(mvm, IWL_MVM_REF_INIT_UCODE); |
| 836 | err = iwl_run_init_mvm_ucode(mvm, true); | 836 | err = iwl_run_init_mvm_ucode(mvm, true); |
| 837 | if (err) | 837 | if (err && err != -ERFKILL) |
| 838 | iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); | 838 | iwl_fw_dbg_error_collect(&mvm->fwrt, FW_DBG_TRIGGER_DRIVER); |
| 839 | if (!iwlmvm_mod_params.init_dbg || !err) | 839 | if (!iwlmvm_mod_params.init_dbg || !err) |
| 840 | iwl_mvm_stop_device(mvm); | 840 | iwl_mvm_stop_device(mvm); |
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c index 1e03acf30762..b516fd1867ec 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c | |||
| @@ -169,9 +169,9 @@ static inline int iwl_mvm_check_pn(struct iwl_mvm *mvm, struct sk_buff *skb, | |||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | /* iwl_mvm_create_skb Adds the rxb to a new skb */ | 171 | /* iwl_mvm_create_skb Adds the rxb to a new skb */ |
| 172 | static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | 172 | static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb, |
| 173 | u16 len, u8 crypt_len, | 173 | struct ieee80211_hdr *hdr, u16 len, u8 crypt_len, |
| 174 | struct iwl_rx_cmd_buffer *rxb) | 174 | struct iwl_rx_cmd_buffer *rxb) |
| 175 | { | 175 | { |
| 176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); | 176 | struct iwl_rx_packet *pkt = rxb_addr(rxb); |
| 177 | struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; | 177 | struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; |
| @@ -204,6 +204,20 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | |||
| 204 | * present before copying packet data. | 204 | * present before copying packet data. |
| 205 | */ | 205 | */ |
| 206 | hdrlen += crypt_len; | 206 | hdrlen += crypt_len; |
| 207 | |||
| 208 | if (WARN_ONCE(headlen < hdrlen, | ||
| 209 | "invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n", | ||
| 210 | hdrlen, len, crypt_len)) { | ||
| 211 | /* | ||
| 212 | * We warn and trace because we want to be able to see | ||
| 213 | * it in trace-cmd as well. | ||
| 214 | */ | ||
| 215 | IWL_DEBUG_RX(mvm, | ||
| 216 | "invalid packet lengths (hdrlen=%d, len=%d, crypt_len=%d)\n", | ||
| 217 | hdrlen, len, crypt_len); | ||
| 218 | return -EINVAL; | ||
| 219 | } | ||
| 220 | |||
| 207 | skb_put_data(skb, hdr, hdrlen); | 221 | skb_put_data(skb, hdr, hdrlen); |
| 208 | skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen); | 222 | skb_put_data(skb, (u8 *)hdr + hdrlen + pad_len, headlen - hdrlen); |
| 209 | 223 | ||
| @@ -216,6 +230,8 @@ static void iwl_mvm_create_skb(struct sk_buff *skb, struct ieee80211_hdr *hdr, | |||
| 216 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, | 230 | skb_add_rx_frag(skb, 0, rxb_steal_page(rxb), offset, |
| 217 | fraglen, rxb->truesize); | 231 | fraglen, rxb->truesize); |
| 218 | } | 232 | } |
| 233 | |||
| 234 | return 0; | ||
| 219 | } | 235 | } |
| 220 | 236 | ||
| 221 | static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, | 237 | static void iwl_mvm_add_rtap_sniffer_config(struct iwl_mvm *mvm, |
| @@ -1671,7 +1687,11 @@ void iwl_mvm_rx_mpdu_mq(struct iwl_mvm *mvm, struct napi_struct *napi, | |||
| 1671 | rx_status->boottime_ns = ktime_get_boot_ns(); | 1687 | rx_status->boottime_ns = ktime_get_boot_ns(); |
| 1672 | } | 1688 | } |
| 1673 | 1689 | ||
| 1674 | iwl_mvm_create_skb(skb, hdr, len, crypt_len, rxb); | 1690 | if (iwl_mvm_create_skb(mvm, skb, hdr, len, crypt_len, rxb)) { |
| 1691 | kfree_skb(skb); | ||
| 1692 | goto out; | ||
| 1693 | } | ||
| 1694 | |||
| 1675 | if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) | 1695 | if (!iwl_mvm_reorder(mvm, napi, queue, sta, skb, desc)) |
| 1676 | iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, | 1696 | iwl_mvm_pass_packet_to_mac80211(mvm, napi, skb, queue, |
| 1677 | sta, csi); | 1697 | sta, csi); |
diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c index 79c1dc05f948..c4375b868901 100644 --- a/drivers/net/wireless/intel/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/intel/iwlwifi/pcie/trans.c | |||
| @@ -3644,20 +3644,27 @@ out_no_pci: | |||
| 3644 | 3644 | ||
| 3645 | void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) | 3645 | void iwl_trans_pcie_sync_nmi(struct iwl_trans *trans) |
| 3646 | { | 3646 | { |
| 3647 | struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); | ||
| 3647 | unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT; | 3648 | unsigned long timeout = jiffies + IWL_TRANS_NMI_TIMEOUT; |
| 3649 | u32 inta_addr, sw_err_bit; | ||
| 3650 | |||
| 3651 | if (trans_pcie->msix_enabled) { | ||
| 3652 | inta_addr = CSR_MSIX_HW_INT_CAUSES_AD; | ||
| 3653 | sw_err_bit = MSIX_HW_INT_CAUSES_REG_SW_ERR; | ||
| 3654 | } else { | ||
| 3655 | inta_addr = CSR_INT; | ||
| 3656 | sw_err_bit = CSR_INT_BIT_SW_ERR; | ||
| 3657 | } | ||
| 3648 | 3658 | ||
| 3649 | iwl_disable_interrupts(trans); | 3659 | iwl_disable_interrupts(trans); |
| 3650 | iwl_force_nmi(trans); | 3660 | iwl_force_nmi(trans); |
| 3651 | while (time_after(timeout, jiffies)) { | 3661 | while (time_after(timeout, jiffies)) { |
| 3652 | u32 inta_hw = iwl_read32(trans, | 3662 | u32 inta_hw = iwl_read32(trans, inta_addr); |
| 3653 | CSR_MSIX_HW_INT_CAUSES_AD); | ||
| 3654 | 3663 | ||
| 3655 | /* Error detected by uCode */ | 3664 | /* Error detected by uCode */ |
| 3656 | if (inta_hw & MSIX_HW_INT_CAUSES_REG_SW_ERR) { | 3665 | if (inta_hw & sw_err_bit) { |
| 3657 | /* Clear causes register */ | 3666 | /* Clear causes register */ |
| 3658 | iwl_write32(trans, CSR_MSIX_HW_INT_CAUSES_AD, | 3667 | iwl_write32(trans, inta_addr, inta_hw & sw_err_bit); |
| 3659 | inta_hw & | ||
| 3660 | MSIX_HW_INT_CAUSES_REG_SW_ERR); | ||
| 3661 | break; | 3668 | break; |
| 3662 | } | 3669 | } |
| 3663 | 3670 | ||
diff --git a/drivers/net/wireless/marvell/mwifiex/sdio.c b/drivers/net/wireless/marvell/mwifiex/sdio.c index a85648342d15..d5a70340a945 100644 --- a/drivers/net/wireless/marvell/mwifiex/sdio.c +++ b/drivers/net/wireless/marvell/mwifiex/sdio.c | |||
| @@ -181,7 +181,7 @@ static int mwifiex_sdio_resume(struct device *dev) | |||
| 181 | 181 | ||
| 182 | adapter = card->adapter; | 182 | adapter = card->adapter; |
| 183 | 183 | ||
| 184 | if (test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) { | 184 | if (!test_bit(MWIFIEX_IS_SUSPENDED, &adapter->work_flags)) { |
| 185 | mwifiex_dbg(adapter, WARN, | 185 | mwifiex_dbg(adapter, WARN, |
| 186 | "device already resumed\n"); | 186 | "device already resumed\n"); |
| 187 | return 0; | 187 | return 0; |
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index f02367faa58d..944ccc310201 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h | |||
| @@ -510,7 +510,7 @@ int bpf_prog_array_copy(struct bpf_prog_array __rcu *old_array, | |||
| 510 | } \ | 510 | } \ |
| 511 | _out: \ | 511 | _out: \ |
| 512 | rcu_read_unlock(); \ | 512 | rcu_read_unlock(); \ |
| 513 | preempt_enable_no_resched(); \ | 513 | preempt_enable(); \ |
| 514 | _ret; \ | 514 | _ret; \ |
| 515 | }) | 515 | }) |
| 516 | 516 | ||
diff --git a/include/net/sctp/command.h b/include/net/sctp/command.h index 6640f84fe536..6d5beac29bc1 100644 --- a/include/net/sctp/command.h +++ b/include/net/sctp/command.h | |||
| @@ -105,7 +105,6 @@ enum sctp_verb { | |||
| 105 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ | 105 | SCTP_CMD_T1_RETRAN, /* Mark for retransmission after T1 timeout */ |
| 106 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ | 106 | SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */ |
| 107 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ | 107 | SCTP_CMD_SEND_MSG, /* Send the whole use message */ |
| 108 | SCTP_CMD_SEND_NEXT_ASCONF, /* Send the next ASCONF after ACK */ | ||
| 109 | SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ | 108 | SCTP_CMD_PURGE_ASCONF_QUEUE, /* Purge all asconf queues.*/ |
| 110 | SCTP_CMD_SET_ASOC, /* Restore association context */ | 109 | SCTP_CMD_SET_ASOC, /* Restore association context */ |
| 111 | SCTP_CMD_LAST | 110 | SCTP_CMD_LAST |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 85386becbaea..c9b0b2b5d672 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
| @@ -295,7 +295,8 @@ struct xfrm_replay { | |||
| 295 | }; | 295 | }; |
| 296 | 296 | ||
| 297 | struct xfrm_if_cb { | 297 | struct xfrm_if_cb { |
| 298 | struct xfrm_if *(*decode_session)(struct sk_buff *skb); | 298 | struct xfrm_if *(*decode_session)(struct sk_buff *skb, |
| 299 | unsigned short family); | ||
| 299 | }; | 300 | }; |
| 300 | 301 | ||
| 301 | void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb); | 302 | void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb); |
| @@ -1404,6 +1405,23 @@ static inline int xfrm_state_kern(const struct xfrm_state *x) | |||
| 1404 | return atomic_read(&x->tunnel_users); | 1405 | return atomic_read(&x->tunnel_users); |
| 1405 | } | 1406 | } |
| 1406 | 1407 | ||
| 1408 | static inline bool xfrm_id_proto_valid(u8 proto) | ||
| 1409 | { | ||
| 1410 | switch (proto) { | ||
| 1411 | case IPPROTO_AH: | ||
| 1412 | case IPPROTO_ESP: | ||
| 1413 | case IPPROTO_COMP: | ||
| 1414 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 1415 | case IPPROTO_ROUTING: | ||
| 1416 | case IPPROTO_DSTOPTS: | ||
| 1417 | #endif | ||
| 1418 | return true; | ||
| 1419 | default: | ||
| 1420 | return false; | ||
| 1421 | } | ||
| 1422 | } | ||
| 1423 | |||
| 1424 | /* IPSEC_PROTO_ANY only matches 3 IPsec protocols, 0 could match all. */ | ||
| 1407 | static inline int xfrm_id_proto_match(u8 proto, u8 userproto) | 1425 | static inline int xfrm_id_proto_match(u8 proto, u8 userproto) |
| 1408 | { | 1426 | { |
| 1409 | return (!userproto || proto == userproto || | 1427 | return (!userproto || proto == userproto || |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 6c5a41f7f338..09d5d972c9ff 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -4138,15 +4138,35 @@ static int check_alu_op(struct bpf_verifier_env *env, struct bpf_insn *insn) | |||
| 4138 | return 0; | 4138 | return 0; |
| 4139 | } | 4139 | } |
| 4140 | 4140 | ||
| 4141 | static void __find_good_pkt_pointers(struct bpf_func_state *state, | ||
| 4142 | struct bpf_reg_state *dst_reg, | ||
| 4143 | enum bpf_reg_type type, u16 new_range) | ||
| 4144 | { | ||
| 4145 | struct bpf_reg_state *reg; | ||
| 4146 | int i; | ||
| 4147 | |||
| 4148 | for (i = 0; i < MAX_BPF_REG; i++) { | ||
| 4149 | reg = &state->regs[i]; | ||
| 4150 | if (reg->type == type && reg->id == dst_reg->id) | ||
| 4151 | /* keep the maximum range already checked */ | ||
| 4152 | reg->range = max(reg->range, new_range); | ||
| 4153 | } | ||
| 4154 | |||
| 4155 | bpf_for_each_spilled_reg(i, state, reg) { | ||
| 4156 | if (!reg) | ||
| 4157 | continue; | ||
| 4158 | if (reg->type == type && reg->id == dst_reg->id) | ||
| 4159 | reg->range = max(reg->range, new_range); | ||
| 4160 | } | ||
| 4161 | } | ||
| 4162 | |||
| 4141 | static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, | 4163 | static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, |
| 4142 | struct bpf_reg_state *dst_reg, | 4164 | struct bpf_reg_state *dst_reg, |
| 4143 | enum bpf_reg_type type, | 4165 | enum bpf_reg_type type, |
| 4144 | bool range_right_open) | 4166 | bool range_right_open) |
| 4145 | { | 4167 | { |
| 4146 | struct bpf_func_state *state = vstate->frame[vstate->curframe]; | ||
| 4147 | struct bpf_reg_state *regs = state->regs, *reg; | ||
| 4148 | u16 new_range; | 4168 | u16 new_range; |
| 4149 | int i, j; | 4169 | int i; |
| 4150 | 4170 | ||
| 4151 | if (dst_reg->off < 0 || | 4171 | if (dst_reg->off < 0 || |
| 4152 | (dst_reg->off == 0 && range_right_open)) | 4172 | (dst_reg->off == 0 && range_right_open)) |
| @@ -4211,20 +4231,9 @@ static void find_good_pkt_pointers(struct bpf_verifier_state *vstate, | |||
| 4211 | * the range won't allow anything. | 4231 | * the range won't allow anything. |
| 4212 | * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16. | 4232 | * dst_reg->off is known < MAX_PACKET_OFF, therefore it fits in a u16. |
| 4213 | */ | 4233 | */ |
| 4214 | for (i = 0; i < MAX_BPF_REG; i++) | 4234 | for (i = 0; i <= vstate->curframe; i++) |
| 4215 | if (regs[i].type == type && regs[i].id == dst_reg->id) | 4235 | __find_good_pkt_pointers(vstate->frame[i], dst_reg, type, |
| 4216 | /* keep the maximum range already checked */ | 4236 | new_range); |
| 4217 | regs[i].range = max(regs[i].range, new_range); | ||
| 4218 | |||
| 4219 | for (j = 0; j <= vstate->curframe; j++) { | ||
| 4220 | state = vstate->frame[j]; | ||
| 4221 | bpf_for_each_spilled_reg(i, state, reg) { | ||
| 4222 | if (!reg) | ||
| 4223 | continue; | ||
| 4224 | if (reg->type == type && reg->id == dst_reg->id) | ||
| 4225 | reg->range = max(reg->range, new_range); | ||
| 4226 | } | ||
| 4227 | } | ||
| 4228 | } | 4237 | } |
| 4229 | 4238 | ||
| 4230 | /* compute branch direction of the expression "if (reg opcode val) goto target;" | 4239 | /* compute branch direction of the expression "if (reg opcode val) goto target;" |
| @@ -4698,6 +4707,22 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state, | |||
| 4698 | } | 4707 | } |
| 4699 | } | 4708 | } |
| 4700 | 4709 | ||
| 4710 | static void __mark_ptr_or_null_regs(struct bpf_func_state *state, u32 id, | ||
| 4711 | bool is_null) | ||
| 4712 | { | ||
| 4713 | struct bpf_reg_state *reg; | ||
| 4714 | int i; | ||
| 4715 | |||
| 4716 | for (i = 0; i < MAX_BPF_REG; i++) | ||
| 4717 | mark_ptr_or_null_reg(state, &state->regs[i], id, is_null); | ||
| 4718 | |||
| 4719 | bpf_for_each_spilled_reg(i, state, reg) { | ||
| 4720 | if (!reg) | ||
| 4721 | continue; | ||
| 4722 | mark_ptr_or_null_reg(state, reg, id, is_null); | ||
| 4723 | } | ||
| 4724 | } | ||
| 4725 | |||
| 4701 | /* The logic is similar to find_good_pkt_pointers(), both could eventually | 4726 | /* The logic is similar to find_good_pkt_pointers(), both could eventually |
| 4702 | * be folded together at some point. | 4727 | * be folded together at some point. |
| 4703 | */ | 4728 | */ |
| @@ -4705,10 +4730,10 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno, | |||
| 4705 | bool is_null) | 4730 | bool is_null) |
| 4706 | { | 4731 | { |
| 4707 | struct bpf_func_state *state = vstate->frame[vstate->curframe]; | 4732 | struct bpf_func_state *state = vstate->frame[vstate->curframe]; |
| 4708 | struct bpf_reg_state *reg, *regs = state->regs; | 4733 | struct bpf_reg_state *regs = state->regs; |
| 4709 | u32 ref_obj_id = regs[regno].ref_obj_id; | 4734 | u32 ref_obj_id = regs[regno].ref_obj_id; |
| 4710 | u32 id = regs[regno].id; | 4735 | u32 id = regs[regno].id; |
| 4711 | int i, j; | 4736 | int i; |
| 4712 | 4737 | ||
| 4713 | if (ref_obj_id && ref_obj_id == id && is_null) | 4738 | if (ref_obj_id && ref_obj_id == id && is_null) |
| 4714 | /* regs[regno] is in the " == NULL" branch. | 4739 | /* regs[regno] is in the " == NULL" branch. |
| @@ -4717,17 +4742,8 @@ static void mark_ptr_or_null_regs(struct bpf_verifier_state *vstate, u32 regno, | |||
| 4717 | */ | 4742 | */ |
| 4718 | WARN_ON_ONCE(release_reference_state(state, id)); | 4743 | WARN_ON_ONCE(release_reference_state(state, id)); |
| 4719 | 4744 | ||
| 4720 | for (i = 0; i < MAX_BPF_REG; i++) | 4745 | for (i = 0; i <= vstate->curframe; i++) |
| 4721 | mark_ptr_or_null_reg(state, ®s[i], id, is_null); | 4746 | __mark_ptr_or_null_regs(vstate->frame[i], id, is_null); |
| 4722 | |||
| 4723 | for (j = 0; j <= vstate->curframe; j++) { | ||
| 4724 | state = vstate->frame[j]; | ||
| 4725 | bpf_for_each_spilled_reg(i, state, reg) { | ||
| 4726 | if (!reg) | ||
| 4727 | continue; | ||
| 4728 | mark_ptr_or_null_reg(state, reg, id, is_null); | ||
| 4729 | } | ||
| 4730 | } | ||
| 4731 | } | 4747 | } |
| 4732 | 4748 | ||
| 4733 | static bool try_match_pkt_pointers(const struct bpf_insn *insn, | 4749 | static bool try_match_pkt_pointers(const struct bpf_insn *insn, |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 709d2542f729..dbe8b1993be9 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
| @@ -1920,6 +1920,7 @@ static int __init atalk_init(void) | |||
| 1920 | ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); | 1920 | ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); |
| 1921 | if (!ddp_dl) { | 1921 | if (!ddp_dl) { |
| 1922 | pr_crit("Unable to register DDP with SNAP.\n"); | 1922 | pr_crit("Unable to register DDP with SNAP.\n"); |
| 1923 | rc = -ENOMEM; | ||
| 1923 | goto out_sock; | 1924 | goto out_sock; |
| 1924 | } | 1925 | } |
| 1925 | 1926 | ||
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c index 10e809b296ec..fb065a8937ea 100644 --- a/net/ipv4/esp4.c +++ b/net/ipv4/esp4.c | |||
| @@ -226,7 +226,7 @@ static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) | |||
| 226 | tail[plen - 1] = proto; | 226 | tail[plen - 1] = proto; |
| 227 | } | 227 | } |
| 228 | 228 | ||
| 229 | static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) | 229 | static int esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) |
| 230 | { | 230 | { |
| 231 | int encap_type; | 231 | int encap_type; |
| 232 | struct udphdr *uh; | 232 | struct udphdr *uh; |
| @@ -234,6 +234,7 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru | |||
| 234 | __be16 sport, dport; | 234 | __be16 sport, dport; |
| 235 | struct xfrm_encap_tmpl *encap = x->encap; | 235 | struct xfrm_encap_tmpl *encap = x->encap; |
| 236 | struct ip_esp_hdr *esph = esp->esph; | 236 | struct ip_esp_hdr *esph = esp->esph; |
| 237 | unsigned int len; | ||
| 237 | 238 | ||
| 238 | spin_lock_bh(&x->lock); | 239 | spin_lock_bh(&x->lock); |
| 239 | sport = encap->encap_sport; | 240 | sport = encap->encap_sport; |
| @@ -241,11 +242,14 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru | |||
| 241 | encap_type = encap->encap_type; | 242 | encap_type = encap->encap_type; |
| 242 | spin_unlock_bh(&x->lock); | 243 | spin_unlock_bh(&x->lock); |
| 243 | 244 | ||
| 245 | len = skb->len + esp->tailen - skb_transport_offset(skb); | ||
| 246 | if (len + sizeof(struct iphdr) >= IP_MAX_MTU) | ||
| 247 | return -EMSGSIZE; | ||
| 248 | |||
| 244 | uh = (struct udphdr *)esph; | 249 | uh = (struct udphdr *)esph; |
| 245 | uh->source = sport; | 250 | uh->source = sport; |
| 246 | uh->dest = dport; | 251 | uh->dest = dport; |
| 247 | uh->len = htons(skb->len + esp->tailen | 252 | uh->len = htons(len); |
| 248 | - skb_transport_offset(skb)); | ||
| 249 | uh->check = 0; | 253 | uh->check = 0; |
| 250 | 254 | ||
| 251 | switch (encap_type) { | 255 | switch (encap_type) { |
| @@ -262,6 +266,8 @@ static void esp_output_udp_encap(struct xfrm_state *x, struct sk_buff *skb, stru | |||
| 262 | 266 | ||
| 263 | *skb_mac_header(skb) = IPPROTO_UDP; | 267 | *skb_mac_header(skb) = IPPROTO_UDP; |
| 264 | esp->esph = esph; | 268 | esp->esph = esph; |
| 269 | |||
| 270 | return 0; | ||
| 265 | } | 271 | } |
| 266 | 272 | ||
| 267 | int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) | 273 | int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) |
| @@ -275,8 +281,12 @@ int esp_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info * | |||
| 275 | int tailen = esp->tailen; | 281 | int tailen = esp->tailen; |
| 276 | 282 | ||
| 277 | /* this is non-NULL only with UDP Encapsulation */ | 283 | /* this is non-NULL only with UDP Encapsulation */ |
| 278 | if (x->encap) | 284 | if (x->encap) { |
| 279 | esp_output_udp_encap(x, skb, esp); | 285 | int err = esp_output_udp_encap(x, skb, esp); |
| 286 | |||
| 287 | if (err < 0) | ||
| 288 | return err; | ||
| 289 | } | ||
| 280 | 290 | ||
| 281 | if (!skb_cloned(skb)) { | 291 | if (!skb_cloned(skb)) { |
| 282 | if (tailen <= skb_tailroom(skb)) { | 292 | if (tailen <= skb_tailroom(skb)) { |
diff --git a/net/ipv4/esp4_offload.c b/net/ipv4/esp4_offload.c index 8756e0e790d2..d3170a8001b2 100644 --- a/net/ipv4/esp4_offload.c +++ b/net/ipv4/esp4_offload.c | |||
| @@ -52,13 +52,13 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head, | |||
| 52 | goto out; | 52 | goto out; |
| 53 | 53 | ||
| 54 | if (sp->len == XFRM_MAX_DEPTH) | 54 | if (sp->len == XFRM_MAX_DEPTH) |
| 55 | goto out; | 55 | goto out_reset; |
| 56 | 56 | ||
| 57 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, | 57 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, |
| 58 | (xfrm_address_t *)&ip_hdr(skb)->daddr, | 58 | (xfrm_address_t *)&ip_hdr(skb)->daddr, |
| 59 | spi, IPPROTO_ESP, AF_INET); | 59 | spi, IPPROTO_ESP, AF_INET); |
| 60 | if (!x) | 60 | if (!x) |
| 61 | goto out; | 61 | goto out_reset; |
| 62 | 62 | ||
| 63 | sp->xvec[sp->len++] = x; | 63 | sp->xvec[sp->len++] = x; |
| 64 | sp->olen++; | 64 | sp->olen++; |
| @@ -66,7 +66,7 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head, | |||
| 66 | xo = xfrm_offload(skb); | 66 | xo = xfrm_offload(skb); |
| 67 | if (!xo) { | 67 | if (!xo) { |
| 68 | xfrm_state_put(x); | 68 | xfrm_state_put(x); |
| 69 | goto out; | 69 | goto out_reset; |
| 70 | } | 70 | } |
| 71 | } | 71 | } |
| 72 | 72 | ||
| @@ -82,6 +82,8 @@ static struct sk_buff *esp4_gro_receive(struct list_head *head, | |||
| 82 | xfrm_input(skb, IPPROTO_ESP, spi, -2); | 82 | xfrm_input(skb, IPPROTO_ESP, spi, -2); |
| 83 | 83 | ||
| 84 | return ERR_PTR(-EINPROGRESS); | 84 | return ERR_PTR(-EINPROGRESS); |
| 85 | out_reset: | ||
| 86 | secpath_reset(skb); | ||
| 85 | out: | 87 | out: |
| 86 | skb_push(skb, offset); | 88 | skb_push(skb, offset); |
| 87 | NAPI_GRO_CB(skb)->same_flow = 0; | 89 | NAPI_GRO_CB(skb)->same_flow = 0; |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index c80188875f39..e8bb2e85c5a4 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
| @@ -519,6 +519,7 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
| 519 | to->pkt_type = from->pkt_type; | 519 | to->pkt_type = from->pkt_type; |
| 520 | to->priority = from->priority; | 520 | to->priority = from->priority; |
| 521 | to->protocol = from->protocol; | 521 | to->protocol = from->protocol; |
| 522 | to->skb_iif = from->skb_iif; | ||
| 522 | skb_dst_drop(to); | 523 | skb_dst_drop(to); |
| 523 | skb_dst_copy(to, from); | 524 | skb_dst_copy(to, from); |
| 524 | to->dev = from->dev; | 525 | to->dev = from->dev; |
diff --git a/net/ipv4/ip_vti.c b/net/ipv4/ip_vti.c index 68a21bf75dd0..35d8346742e2 100644 --- a/net/ipv4/ip_vti.c +++ b/net/ipv4/ip_vti.c | |||
| @@ -646,10 +646,8 @@ static int __init vti_init(void) | |||
| 646 | 646 | ||
| 647 | msg = "ipip tunnel"; | 647 | msg = "ipip tunnel"; |
| 648 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); | 648 | err = xfrm4_tunnel_register(&ipip_handler, AF_INET); |
| 649 | if (err < 0) { | 649 | if (err < 0) |
| 650 | pr_info("%s: cant't register tunnel\n",__func__); | ||
| 651 | goto xfrm_tunnel_failed; | 650 | goto xfrm_tunnel_failed; |
| 652 | } | ||
| 653 | 651 | ||
| 654 | msg = "netlink interface"; | 652 | msg = "netlink interface"; |
| 655 | err = rtnl_link_register(&vti_link_ops); | 653 | err = rtnl_link_register(&vti_link_ops); |
| @@ -659,9 +657,9 @@ static int __init vti_init(void) | |||
| 659 | return err; | 657 | return err; |
| 660 | 658 | ||
| 661 | rtnl_link_failed: | 659 | rtnl_link_failed: |
| 662 | xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); | ||
| 663 | xfrm_tunnel_failed: | ||
| 664 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | 660 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); |
| 661 | xfrm_tunnel_failed: | ||
| 662 | xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); | ||
| 665 | xfrm_proto_comp_failed: | 663 | xfrm_proto_comp_failed: |
| 666 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); | 664 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); |
| 667 | xfrm_proto_ah_failed: | 665 | xfrm_proto_ah_failed: |
| @@ -676,6 +674,7 @@ pernet_dev_failed: | |||
| 676 | static void __exit vti_fini(void) | 674 | static void __exit vti_fini(void) |
| 677 | { | 675 | { |
| 678 | rtnl_link_unregister(&vti_link_ops); | 676 | rtnl_link_unregister(&vti_link_ops); |
| 677 | xfrm4_tunnel_deregister(&ipip_handler, AF_INET); | ||
| 679 | xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); | 678 | xfrm4_protocol_deregister(&vti_ipcomp4_protocol, IPPROTO_COMP); |
| 680 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); | 679 | xfrm4_protocol_deregister(&vti_ah4_protocol, IPPROTO_AH); |
| 681 | xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); | 680 | xfrm4_protocol_deregister(&vti_esp4_protocol, IPPROTO_ESP); |
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 2f8039a26b08..a2896944aa37 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
| @@ -1673,7 +1673,9 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) | |||
| 1673 | if (TCP_SKB_CB(tail)->end_seq != TCP_SKB_CB(skb)->seq || | 1673 | if (TCP_SKB_CB(tail)->end_seq != TCP_SKB_CB(skb)->seq || |
| 1674 | TCP_SKB_CB(tail)->ip_dsfield != TCP_SKB_CB(skb)->ip_dsfield || | 1674 | TCP_SKB_CB(tail)->ip_dsfield != TCP_SKB_CB(skb)->ip_dsfield || |
| 1675 | ((TCP_SKB_CB(tail)->tcp_flags | | 1675 | ((TCP_SKB_CB(tail)->tcp_flags | |
| 1676 | TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_URG) || | 1676 | TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_SYN | TCPHDR_RST | TCPHDR_URG)) || |
| 1677 | !((TCP_SKB_CB(tail)->tcp_flags & | ||
| 1678 | TCP_SKB_CB(skb)->tcp_flags) & TCPHDR_ACK) || | ||
| 1677 | ((TCP_SKB_CB(tail)->tcp_flags ^ | 1679 | ((TCP_SKB_CB(tail)->tcp_flags ^ |
| 1678 | TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) || | 1680 | TCP_SKB_CB(skb)->tcp_flags) & (TCPHDR_ECE | TCPHDR_CWR)) || |
| 1679 | #ifdef CONFIG_TLS_DEVICE | 1681 | #ifdef CONFIG_TLS_DEVICE |
| @@ -1692,6 +1694,15 @@ bool tcp_add_backlog(struct sock *sk, struct sk_buff *skb) | |||
| 1692 | if (after(TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(tail)->ack_seq)) | 1694 | if (after(TCP_SKB_CB(skb)->ack_seq, TCP_SKB_CB(tail)->ack_seq)) |
| 1693 | TCP_SKB_CB(tail)->ack_seq = TCP_SKB_CB(skb)->ack_seq; | 1695 | TCP_SKB_CB(tail)->ack_seq = TCP_SKB_CB(skb)->ack_seq; |
| 1694 | 1696 | ||
| 1697 | /* We have to update both TCP_SKB_CB(tail)->tcp_flags and | ||
| 1698 | * thtail->fin, so that the fast path in tcp_rcv_established() | ||
| 1699 | * is not entered if we append a packet with a FIN. | ||
| 1700 | * SYN, RST, URG are not present. | ||
| 1701 | * ACK is set on both packets. | ||
| 1702 | * PSH : we do not really care in TCP stack, | ||
| 1703 | * at least for 'GRO' packets. | ||
| 1704 | */ | ||
| 1705 | thtail->fin |= th->fin; | ||
| 1695 | TCP_SKB_CB(tail)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; | 1706 | TCP_SKB_CB(tail)->tcp_flags |= TCP_SKB_CB(skb)->tcp_flags; |
| 1696 | 1707 | ||
| 1697 | if (TCP_SKB_CB(skb)->has_rxtstamp) { | 1708 | if (TCP_SKB_CB(skb)->has_rxtstamp) { |
diff --git a/net/ipv4/udp_offload.c b/net/ipv4/udp_offload.c index 64f9715173ac..065334b41d57 100644 --- a/net/ipv4/udp_offload.c +++ b/net/ipv4/udp_offload.c | |||
| @@ -352,6 +352,7 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head, | |||
| 352 | struct sk_buff *pp = NULL; | 352 | struct sk_buff *pp = NULL; |
| 353 | struct udphdr *uh2; | 353 | struct udphdr *uh2; |
| 354 | struct sk_buff *p; | 354 | struct sk_buff *p; |
| 355 | unsigned int ulen; | ||
| 355 | 356 | ||
| 356 | /* requires non zero csum, for symmetry with GSO */ | 357 | /* requires non zero csum, for symmetry with GSO */ |
| 357 | if (!uh->check) { | 358 | if (!uh->check) { |
| @@ -359,6 +360,12 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head, | |||
| 359 | return NULL; | 360 | return NULL; |
| 360 | } | 361 | } |
| 361 | 362 | ||
| 363 | /* Do not deal with padded or malicious packets, sorry ! */ | ||
| 364 | ulen = ntohs(uh->len); | ||
| 365 | if (ulen <= sizeof(*uh) || ulen != skb_gro_len(skb)) { | ||
| 366 | NAPI_GRO_CB(skb)->flush = 1; | ||
| 367 | return NULL; | ||
| 368 | } | ||
| 362 | /* pull encapsulating udp header */ | 369 | /* pull encapsulating udp header */ |
| 363 | skb_gro_pull(skb, sizeof(struct udphdr)); | 370 | skb_gro_pull(skb, sizeof(struct udphdr)); |
| 364 | skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); | 371 | skb_gro_postpull_rcsum(skb, uh, sizeof(struct udphdr)); |
| @@ -377,13 +384,14 @@ static struct sk_buff *udp_gro_receive_segment(struct list_head *head, | |||
| 377 | 384 | ||
| 378 | /* Terminate the flow on len mismatch or if it grow "too much". | 385 | /* Terminate the flow on len mismatch or if it grow "too much". |
| 379 | * Under small packet flood GRO count could elsewhere grow a lot | 386 | * Under small packet flood GRO count could elsewhere grow a lot |
| 380 | * leading to execessive truesize values | 387 | * leading to excessive truesize values. |
| 388 | * On len mismatch merge the first packet shorter than gso_size, | ||
| 389 | * otherwise complete the GRO packet. | ||
| 381 | */ | 390 | */ |
| 382 | if (!skb_gro_receive(p, skb) && | 391 | if (ulen > ntohs(uh2->len) || skb_gro_receive(p, skb) || |
| 392 | ulen != ntohs(uh2->len) || | ||
| 383 | NAPI_GRO_CB(p)->count >= UDP_GRO_CNT_MAX) | 393 | NAPI_GRO_CB(p)->count >= UDP_GRO_CNT_MAX) |
| 384 | pp = p; | 394 | pp = p; |
| 385 | else if (uh->len != uh2->len) | ||
| 386 | pp = p; | ||
| 387 | 395 | ||
| 388 | return pp; | 396 | return pp; |
| 389 | } | 397 | } |
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c index d73a6d6652f6..2b144b92ae46 100644 --- a/net/ipv4/xfrm4_policy.c +++ b/net/ipv4/xfrm4_policy.c | |||
| @@ -111,7 +111,8 @@ static void | |||
| 111 | _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | 111 | _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) |
| 112 | { | 112 | { |
| 113 | const struct iphdr *iph = ip_hdr(skb); | 113 | const struct iphdr *iph = ip_hdr(skb); |
| 114 | u8 *xprth = skb_network_header(skb) + iph->ihl * 4; | 114 | int ihl = iph->ihl; |
| 115 | u8 *xprth = skb_network_header(skb) + ihl * 4; | ||
| 115 | struct flowi4 *fl4 = &fl->u.ip4; | 116 | struct flowi4 *fl4 = &fl->u.ip4; |
| 116 | int oif = 0; | 117 | int oif = 0; |
| 117 | 118 | ||
| @@ -122,6 +123,11 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 122 | fl4->flowi4_mark = skb->mark; | 123 | fl4->flowi4_mark = skb->mark; |
| 123 | fl4->flowi4_oif = reverse ? skb->skb_iif : oif; | 124 | fl4->flowi4_oif = reverse ? skb->skb_iif : oif; |
| 124 | 125 | ||
| 126 | fl4->flowi4_proto = iph->protocol; | ||
| 127 | fl4->daddr = reverse ? iph->saddr : iph->daddr; | ||
| 128 | fl4->saddr = reverse ? iph->daddr : iph->saddr; | ||
| 129 | fl4->flowi4_tos = iph->tos; | ||
| 130 | |||
| 125 | if (!ip_is_fragment(iph)) { | 131 | if (!ip_is_fragment(iph)) { |
| 126 | switch (iph->protocol) { | 132 | switch (iph->protocol) { |
| 127 | case IPPROTO_UDP: | 133 | case IPPROTO_UDP: |
| @@ -133,7 +139,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 133 | pskb_may_pull(skb, xprth + 4 - skb->data)) { | 139 | pskb_may_pull(skb, xprth + 4 - skb->data)) { |
| 134 | __be16 *ports; | 140 | __be16 *ports; |
| 135 | 141 | ||
| 136 | xprth = skb_network_header(skb) + iph->ihl * 4; | 142 | xprth = skb_network_header(skb) + ihl * 4; |
| 137 | ports = (__be16 *)xprth; | 143 | ports = (__be16 *)xprth; |
| 138 | 144 | ||
| 139 | fl4->fl4_sport = ports[!!reverse]; | 145 | fl4->fl4_sport = ports[!!reverse]; |
| @@ -146,7 +152,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 146 | pskb_may_pull(skb, xprth + 2 - skb->data)) { | 152 | pskb_may_pull(skb, xprth + 2 - skb->data)) { |
| 147 | u8 *icmp; | 153 | u8 *icmp; |
| 148 | 154 | ||
| 149 | xprth = skb_network_header(skb) + iph->ihl * 4; | 155 | xprth = skb_network_header(skb) + ihl * 4; |
| 150 | icmp = xprth; | 156 | icmp = xprth; |
| 151 | 157 | ||
| 152 | fl4->fl4_icmp_type = icmp[0]; | 158 | fl4->fl4_icmp_type = icmp[0]; |
| @@ -159,7 +165,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 159 | pskb_may_pull(skb, xprth + 4 - skb->data)) { | 165 | pskb_may_pull(skb, xprth + 4 - skb->data)) { |
| 160 | __be32 *ehdr; | 166 | __be32 *ehdr; |
| 161 | 167 | ||
| 162 | xprth = skb_network_header(skb) + iph->ihl * 4; | 168 | xprth = skb_network_header(skb) + ihl * 4; |
| 163 | ehdr = (__be32 *)xprth; | 169 | ehdr = (__be32 *)xprth; |
| 164 | 170 | ||
| 165 | fl4->fl4_ipsec_spi = ehdr[0]; | 171 | fl4->fl4_ipsec_spi = ehdr[0]; |
| @@ -171,7 +177,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 171 | pskb_may_pull(skb, xprth + 8 - skb->data)) { | 177 | pskb_may_pull(skb, xprth + 8 - skb->data)) { |
| 172 | __be32 *ah_hdr; | 178 | __be32 *ah_hdr; |
| 173 | 179 | ||
| 174 | xprth = skb_network_header(skb) + iph->ihl * 4; | 180 | xprth = skb_network_header(skb) + ihl * 4; |
| 175 | ah_hdr = (__be32 *)xprth; | 181 | ah_hdr = (__be32 *)xprth; |
| 176 | 182 | ||
| 177 | fl4->fl4_ipsec_spi = ah_hdr[1]; | 183 | fl4->fl4_ipsec_spi = ah_hdr[1]; |
| @@ -183,7 +189,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 183 | pskb_may_pull(skb, xprth + 4 - skb->data)) { | 189 | pskb_may_pull(skb, xprth + 4 - skb->data)) { |
| 184 | __be16 *ipcomp_hdr; | 190 | __be16 *ipcomp_hdr; |
| 185 | 191 | ||
| 186 | xprth = skb_network_header(skb) + iph->ihl * 4; | 192 | xprth = skb_network_header(skb) + ihl * 4; |
| 187 | ipcomp_hdr = (__be16 *)xprth; | 193 | ipcomp_hdr = (__be16 *)xprth; |
| 188 | 194 | ||
| 189 | fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); | 195 | fl4->fl4_ipsec_spi = htonl(ntohs(ipcomp_hdr[1])); |
| @@ -196,7 +202,7 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 196 | __be16 *greflags; | 202 | __be16 *greflags; |
| 197 | __be32 *gre_hdr; | 203 | __be32 *gre_hdr; |
| 198 | 204 | ||
| 199 | xprth = skb_network_header(skb) + iph->ihl * 4; | 205 | xprth = skb_network_header(skb) + ihl * 4; |
| 200 | greflags = (__be16 *)xprth; | 206 | greflags = (__be16 *)xprth; |
| 201 | gre_hdr = (__be32 *)xprth; | 207 | gre_hdr = (__be32 *)xprth; |
| 202 | 208 | ||
| @@ -213,10 +219,6 @@ _decode_session4(struct sk_buff *skb, struct flowi *fl, int reverse) | |||
| 213 | break; | 219 | break; |
| 214 | } | 220 | } |
| 215 | } | 221 | } |
| 216 | fl4->flowi4_proto = iph->protocol; | ||
| 217 | fl4->daddr = reverse ? iph->saddr : iph->daddr; | ||
| 218 | fl4->saddr = reverse ? iph->daddr : iph->saddr; | ||
| 219 | fl4->flowi4_tos = iph->tos; | ||
| 220 | } | 222 | } |
| 221 | 223 | ||
| 222 | static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, | 224 | static void xfrm4_update_pmtu(struct dst_entry *dst, struct sock *sk, |
diff --git a/net/ipv6/esp6_offload.c b/net/ipv6/esp6_offload.c index d46b4eb645c2..cb99f6fb79b7 100644 --- a/net/ipv6/esp6_offload.c +++ b/net/ipv6/esp6_offload.c | |||
| @@ -74,13 +74,13 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
| 74 | goto out; | 74 | goto out; |
| 75 | 75 | ||
| 76 | if (sp->len == XFRM_MAX_DEPTH) | 76 | if (sp->len == XFRM_MAX_DEPTH) |
| 77 | goto out; | 77 | goto out_reset; |
| 78 | 78 | ||
| 79 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, | 79 | x = xfrm_state_lookup(dev_net(skb->dev), skb->mark, |
| 80 | (xfrm_address_t *)&ipv6_hdr(skb)->daddr, | 80 | (xfrm_address_t *)&ipv6_hdr(skb)->daddr, |
| 81 | spi, IPPROTO_ESP, AF_INET6); | 81 | spi, IPPROTO_ESP, AF_INET6); |
| 82 | if (!x) | 82 | if (!x) |
| 83 | goto out; | 83 | goto out_reset; |
| 84 | 84 | ||
| 85 | sp->xvec[sp->len++] = x; | 85 | sp->xvec[sp->len++] = x; |
| 86 | sp->olen++; | 86 | sp->olen++; |
| @@ -88,7 +88,7 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
| 88 | xo = xfrm_offload(skb); | 88 | xo = xfrm_offload(skb); |
| 89 | if (!xo) { | 89 | if (!xo) { |
| 90 | xfrm_state_put(x); | 90 | xfrm_state_put(x); |
| 91 | goto out; | 91 | goto out_reset; |
| 92 | } | 92 | } |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -109,6 +109,8 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head, | |||
| 109 | xfrm_input(skb, IPPROTO_ESP, spi, -2); | 109 | xfrm_input(skb, IPPROTO_ESP, spi, -2); |
| 110 | 110 | ||
| 111 | return ERR_PTR(-EINPROGRESS); | 111 | return ERR_PTR(-EINPROGRESS); |
| 112 | out_reset: | ||
| 113 | secpath_reset(skb); | ||
| 112 | out: | 114 | out: |
| 113 | skb_push(skb, offset); | 115 | skb_push(skb, offset); |
| 114 | NAPI_GRO_CB(skb)->same_flow = 0; | 116 | NAPI_GRO_CB(skb)->same_flow = 0; |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 6613d8dbb0e5..91247a6fc67f 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
| @@ -921,9 +921,7 @@ static void fib6_drop_pcpu_from(struct fib6_info *f6i, | |||
| 921 | if (pcpu_rt) { | 921 | if (pcpu_rt) { |
| 922 | struct fib6_info *from; | 922 | struct fib6_info *from; |
| 923 | 923 | ||
| 924 | from = rcu_dereference_protected(pcpu_rt->from, | 924 | from = xchg((__force struct fib6_info **)&pcpu_rt->from, NULL); |
| 925 | lockdep_is_held(&table->tb6_lock)); | ||
| 926 | rcu_assign_pointer(pcpu_rt->from, NULL); | ||
| 927 | fib6_info_release(from); | 925 | fib6_info_release(from); |
| 928 | } | 926 | } |
| 929 | } | 927 | } |
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c index cb54a8a3c273..be5f3d7ceb96 100644 --- a/net/ipv6/ip6_flowlabel.c +++ b/net/ipv6/ip6_flowlabel.c | |||
| @@ -94,15 +94,21 @@ static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label) | |||
| 94 | return fl; | 94 | return fl; |
| 95 | } | 95 | } |
| 96 | 96 | ||
| 97 | static void fl_free_rcu(struct rcu_head *head) | ||
| 98 | { | ||
| 99 | struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu); | ||
| 100 | |||
| 101 | if (fl->share == IPV6_FL_S_PROCESS) | ||
| 102 | put_pid(fl->owner.pid); | ||
| 103 | kfree(fl->opt); | ||
| 104 | kfree(fl); | ||
| 105 | } | ||
| 106 | |||
| 97 | 107 | ||
| 98 | static void fl_free(struct ip6_flowlabel *fl) | 108 | static void fl_free(struct ip6_flowlabel *fl) |
| 99 | { | 109 | { |
| 100 | if (fl) { | 110 | if (fl) |
| 101 | if (fl->share == IPV6_FL_S_PROCESS) | 111 | call_rcu(&fl->rcu, fl_free_rcu); |
| 102 | put_pid(fl->owner.pid); | ||
| 103 | kfree(fl->opt); | ||
| 104 | kfree_rcu(fl, rcu); | ||
| 105 | } | ||
| 106 | } | 112 | } |
| 107 | 113 | ||
| 108 | static void fl_release(struct ip6_flowlabel *fl) | 114 | static void fl_release(struct ip6_flowlabel *fl) |
| @@ -633,9 +639,9 @@ recheck: | |||
| 633 | if (fl1->share == IPV6_FL_S_EXCL || | 639 | if (fl1->share == IPV6_FL_S_EXCL || |
| 634 | fl1->share != fl->share || | 640 | fl1->share != fl->share || |
| 635 | ((fl1->share == IPV6_FL_S_PROCESS) && | 641 | ((fl1->share == IPV6_FL_S_PROCESS) && |
| 636 | (fl1->owner.pid == fl->owner.pid)) || | 642 | (fl1->owner.pid != fl->owner.pid)) || |
| 637 | ((fl1->share == IPV6_FL_S_USER) && | 643 | ((fl1->share == IPV6_FL_S_USER) && |
| 638 | uid_eq(fl1->owner.uid, fl->owner.uid))) | 644 | !uid_eq(fl1->owner.uid, fl->owner.uid))) |
| 639 | goto release; | 645 | goto release; |
| 640 | 646 | ||
| 641 | err = -ENOMEM; | 647 | err = -ENOMEM; |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7178e32eb15d..0520aca3354b 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -379,11 +379,8 @@ static void ip6_dst_destroy(struct dst_entry *dst) | |||
| 379 | in6_dev_put(idev); | 379 | in6_dev_put(idev); |
| 380 | } | 380 | } |
| 381 | 381 | ||
| 382 | rcu_read_lock(); | 382 | from = xchg((__force struct fib6_info **)&rt->from, NULL); |
| 383 | from = rcu_dereference(rt->from); | ||
| 384 | rcu_assign_pointer(rt->from, NULL); | ||
| 385 | fib6_info_release(from); | 383 | fib6_info_release(from); |
| 386 | rcu_read_unlock(); | ||
| 387 | } | 384 | } |
| 388 | 385 | ||
| 389 | static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, | 386 | static void ip6_dst_ifdown(struct dst_entry *dst, struct net_device *dev, |
| @@ -1288,9 +1285,7 @@ static void rt6_remove_exception(struct rt6_exception_bucket *bucket, | |||
| 1288 | /* purge completely the exception to allow releasing the held resources: | 1285 | /* purge completely the exception to allow releasing the held resources: |
| 1289 | * some [sk] cache may keep the dst around for unlimited time | 1286 | * some [sk] cache may keep the dst around for unlimited time |
| 1290 | */ | 1287 | */ |
| 1291 | from = rcu_dereference_protected(rt6_ex->rt6i->from, | 1288 | from = xchg((__force struct fib6_info **)&rt6_ex->rt6i->from, NULL); |
| 1292 | lockdep_is_held(&rt6_exception_lock)); | ||
| 1293 | rcu_assign_pointer(rt6_ex->rt6i->from, NULL); | ||
| 1294 | fib6_info_release(from); | 1289 | fib6_info_release(from); |
| 1295 | dst_dev_put(&rt6_ex->rt6i->dst); | 1290 | dst_dev_put(&rt6_ex->rt6i->dst); |
| 1296 | 1291 | ||
| @@ -3397,11 +3392,8 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3397 | 3392 | ||
| 3398 | rcu_read_lock(); | 3393 | rcu_read_lock(); |
| 3399 | from = rcu_dereference(rt->from); | 3394 | from = rcu_dereference(rt->from); |
| 3400 | /* This fib6_info_hold() is safe here because we hold reference to rt | 3395 | if (!from) |
| 3401 | * and rt already holds reference to fib6_info. | 3396 | goto out; |
| 3402 | */ | ||
| 3403 | fib6_info_hold(from); | ||
| 3404 | rcu_read_unlock(); | ||
| 3405 | 3397 | ||
| 3406 | nrt = ip6_rt_cache_alloc(from, &msg->dest, NULL); | 3398 | nrt = ip6_rt_cache_alloc(from, &msg->dest, NULL); |
| 3407 | if (!nrt) | 3399 | if (!nrt) |
| @@ -3413,10 +3405,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3413 | 3405 | ||
| 3414 | nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; | 3406 | nrt->rt6i_gateway = *(struct in6_addr *)neigh->primary_key; |
| 3415 | 3407 | ||
| 3416 | /* No need to remove rt from the exception table if rt is | 3408 | /* rt6_insert_exception() will take care of duplicated exceptions */ |
| 3417 | * a cached route because rt6_insert_exception() will | ||
| 3418 | * takes care of it | ||
| 3419 | */ | ||
| 3420 | if (rt6_insert_exception(nrt, from)) { | 3409 | if (rt6_insert_exception(nrt, from)) { |
| 3421 | dst_release_immediate(&nrt->dst); | 3410 | dst_release_immediate(&nrt->dst); |
| 3422 | goto out; | 3411 | goto out; |
| @@ -3429,7 +3418,7 @@ static void rt6_do_redirect(struct dst_entry *dst, struct sock *sk, struct sk_bu | |||
| 3429 | call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); | 3418 | call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); |
| 3430 | 3419 | ||
| 3431 | out: | 3420 | out: |
| 3432 | fib6_info_release(from); | 3421 | rcu_read_unlock(); |
| 3433 | neigh_release(neigh); | 3422 | neigh_release(neigh); |
| 3434 | } | 3423 | } |
| 3435 | 3424 | ||
| @@ -3668,23 +3657,34 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, void __user *arg) | |||
| 3668 | 3657 | ||
| 3669 | static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) | 3658 | static int ip6_pkt_drop(struct sk_buff *skb, u8 code, int ipstats_mib_noroutes) |
| 3670 | { | 3659 | { |
| 3671 | int type; | ||
| 3672 | struct dst_entry *dst = skb_dst(skb); | 3660 | struct dst_entry *dst = skb_dst(skb); |
| 3661 | struct net *net = dev_net(dst->dev); | ||
| 3662 | struct inet6_dev *idev; | ||
| 3663 | int type; | ||
| 3664 | |||
| 3665 | if (netif_is_l3_master(skb->dev) && | ||
| 3666 | dst->dev == net->loopback_dev) | ||
| 3667 | idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); | ||
| 3668 | else | ||
| 3669 | idev = ip6_dst_idev(dst); | ||
| 3670 | |||
| 3673 | switch (ipstats_mib_noroutes) { | 3671 | switch (ipstats_mib_noroutes) { |
| 3674 | case IPSTATS_MIB_INNOROUTES: | 3672 | case IPSTATS_MIB_INNOROUTES: |
| 3675 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); | 3673 | type = ipv6_addr_type(&ipv6_hdr(skb)->daddr); |
| 3676 | if (type == IPV6_ADDR_ANY) { | 3674 | if (type == IPV6_ADDR_ANY) { |
| 3677 | IP6_INC_STATS(dev_net(dst->dev), | 3675 | IP6_INC_STATS(net, idev, IPSTATS_MIB_INADDRERRORS); |
| 3678 | __in6_dev_get_safely(skb->dev), | ||
| 3679 | IPSTATS_MIB_INADDRERRORS); | ||
| 3680 | break; | 3676 | break; |
| 3681 | } | 3677 | } |
| 3682 | /* FALLTHROUGH */ | 3678 | /* FALLTHROUGH */ |
| 3683 | case IPSTATS_MIB_OUTNOROUTES: | 3679 | case IPSTATS_MIB_OUTNOROUTES: |
| 3684 | IP6_INC_STATS(dev_net(dst->dev), ip6_dst_idev(dst), | 3680 | IP6_INC_STATS(net, idev, ipstats_mib_noroutes); |
| 3685 | ipstats_mib_noroutes); | ||
| 3686 | break; | 3681 | break; |
| 3687 | } | 3682 | } |
| 3683 | |||
| 3684 | /* Start over by dropping the dst for l3mdev case */ | ||
| 3685 | if (netif_is_l3_master(skb->dev)) | ||
| 3686 | skb_dst_drop(skb); | ||
| 3687 | |||
| 3688 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0); | 3688 | icmpv6_send(skb, ICMPV6_DEST_UNREACH, code, 0); |
| 3689 | kfree_skb(skb); | 3689 | kfree_skb(skb); |
| 3690 | return 0; | 3690 | return 0; |
| @@ -5017,16 +5017,20 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
| 5017 | 5017 | ||
| 5018 | rcu_read_lock(); | 5018 | rcu_read_lock(); |
| 5019 | from = rcu_dereference(rt->from); | 5019 | from = rcu_dereference(rt->from); |
| 5020 | 5020 | if (from) { | |
| 5021 | if (fibmatch) | 5021 | if (fibmatch) |
| 5022 | err = rt6_fill_node(net, skb, from, NULL, NULL, NULL, iif, | 5022 | err = rt6_fill_node(net, skb, from, NULL, NULL, NULL, |
| 5023 | RTM_NEWROUTE, NETLINK_CB(in_skb).portid, | 5023 | iif, RTM_NEWROUTE, |
| 5024 | nlh->nlmsg_seq, 0); | 5024 | NETLINK_CB(in_skb).portid, |
| 5025 | else | 5025 | nlh->nlmsg_seq, 0); |
| 5026 | err = rt6_fill_node(net, skb, from, dst, &fl6.daddr, | 5026 | else |
| 5027 | &fl6.saddr, iif, RTM_NEWROUTE, | 5027 | err = rt6_fill_node(net, skb, from, dst, &fl6.daddr, |
| 5028 | NETLINK_CB(in_skb).portid, nlh->nlmsg_seq, | 5028 | &fl6.saddr, iif, RTM_NEWROUTE, |
| 5029 | 0); | 5029 | NETLINK_CB(in_skb).portid, |
| 5030 | nlh->nlmsg_seq, 0); | ||
| 5031 | } else { | ||
| 5032 | err = -ENETUNREACH; | ||
| 5033 | } | ||
| 5030 | rcu_read_unlock(); | 5034 | rcu_read_unlock(); |
| 5031 | 5035 | ||
| 5032 | if (err < 0) { | 5036 | if (err < 0) { |
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c index bc65db782bfb..d9e5f6808811 100644 --- a/net/ipv6/xfrm6_tunnel.c +++ b/net/ipv6/xfrm6_tunnel.c | |||
| @@ -345,7 +345,7 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net) | |||
| 345 | unsigned int i; | 345 | unsigned int i; |
| 346 | 346 | ||
| 347 | xfrm_flush_gc(); | 347 | xfrm_flush_gc(); |
| 348 | xfrm_state_flush(net, IPSEC_PROTO_ANY, false, true); | 348 | xfrm_state_flush(net, 0, false, true); |
| 349 | 349 | ||
| 350 | for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) | 350 | for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++) |
| 351 | WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); | 351 | WARN_ON_ONCE(!hlist_empty(&xfrm6_tn->spi_byaddr[i])); |
| @@ -402,6 +402,10 @@ static void __exit xfrm6_tunnel_fini(void) | |||
| 402 | xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); | 402 | xfrm6_tunnel_deregister(&xfrm6_tunnel_handler, AF_INET6); |
| 403 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); | 403 | xfrm_unregister_type(&xfrm6_tunnel_type, AF_INET6); |
| 404 | unregister_pernet_subsys(&xfrm6_tunnel_net_ops); | 404 | unregister_pernet_subsys(&xfrm6_tunnel_net_ops); |
| 405 | /* Someone maybe has gotten the xfrm6_tunnel_spi. | ||
| 406 | * So need to wait it. | ||
| 407 | */ | ||
| 408 | rcu_barrier(); | ||
| 405 | kmem_cache_destroy(xfrm6_tunnel_spi_kmem); | 409 | kmem_cache_destroy(xfrm6_tunnel_spi_kmem); |
| 406 | } | 410 | } |
| 407 | 411 | ||
diff --git a/net/key/af_key.c b/net/key/af_key.c index 5651c29cb5bd..4af1e1d60b9f 100644 --- a/net/key/af_key.c +++ b/net/key/af_key.c | |||
| @@ -1951,8 +1951,10 @@ parse_ipsecrequest(struct xfrm_policy *xp, struct sadb_x_ipsecrequest *rq) | |||
| 1951 | 1951 | ||
| 1952 | if (rq->sadb_x_ipsecrequest_mode == 0) | 1952 | if (rq->sadb_x_ipsecrequest_mode == 0) |
| 1953 | return -EINVAL; | 1953 | return -EINVAL; |
| 1954 | if (!xfrm_id_proto_valid(rq->sadb_x_ipsecrequest_proto)) | ||
| 1955 | return -EINVAL; | ||
| 1954 | 1956 | ||
| 1955 | t->id.proto = rq->sadb_x_ipsecrequest_proto; /* XXX check proto */ | 1957 | t->id.proto = rq->sadb_x_ipsecrequest_proto; |
| 1956 | if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0) | 1958 | if ((mode = pfkey_mode_to_xfrm(rq->sadb_x_ipsecrequest_mode)) < 0) |
| 1957 | return -EINVAL; | 1959 | return -EINVAL; |
| 1958 | t->mode = mode; | 1960 | t->mode = mode; |
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c index fed6becc5daf..52b5a2797c0c 100644 --- a/net/l2tp/l2tp_core.c +++ b/net/l2tp/l2tp_core.c | |||
| @@ -169,8 +169,8 @@ struct l2tp_tunnel *l2tp_tunnel_get(const struct net *net, u32 tunnel_id) | |||
| 169 | 169 | ||
| 170 | rcu_read_lock_bh(); | 170 | rcu_read_lock_bh(); |
| 171 | list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { | 171 | list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { |
| 172 | if (tunnel->tunnel_id == tunnel_id) { | 172 | if (tunnel->tunnel_id == tunnel_id && |
| 173 | l2tp_tunnel_inc_refcount(tunnel); | 173 | refcount_inc_not_zero(&tunnel->ref_count)) { |
| 174 | rcu_read_unlock_bh(); | 174 | rcu_read_unlock_bh(); |
| 175 | 175 | ||
| 176 | return tunnel; | 176 | return tunnel; |
| @@ -190,8 +190,8 @@ struct l2tp_tunnel *l2tp_tunnel_get_nth(const struct net *net, int nth) | |||
| 190 | 190 | ||
| 191 | rcu_read_lock_bh(); | 191 | rcu_read_lock_bh(); |
| 192 | list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { | 192 | list_for_each_entry_rcu(tunnel, &pn->l2tp_tunnel_list, list) { |
| 193 | if (++count > nth) { | 193 | if (++count > nth && |
| 194 | l2tp_tunnel_inc_refcount(tunnel); | 194 | refcount_inc_not_zero(&tunnel->ref_count)) { |
| 195 | rcu_read_unlock_bh(); | 195 | rcu_read_unlock_bh(); |
| 196 | return tunnel; | 196 | return tunnel; |
| 197 | } | 197 | } |
| @@ -909,7 +909,7 @@ int l2tp_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
| 909 | { | 909 | { |
| 910 | struct l2tp_tunnel *tunnel; | 910 | struct l2tp_tunnel *tunnel; |
| 911 | 911 | ||
| 912 | tunnel = l2tp_tunnel(sk); | 912 | tunnel = rcu_dereference_sk_user_data(sk); |
| 913 | if (tunnel == NULL) | 913 | if (tunnel == NULL) |
| 914 | goto pass_up; | 914 | goto pass_up; |
| 915 | 915 | ||
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c index cff0fb3578c9..deb3faf08337 100644 --- a/net/mac80211/debugfs_netdev.c +++ b/net/mac80211/debugfs_netdev.c | |||
| @@ -841,7 +841,7 @@ void ieee80211_debugfs_rename_netdev(struct ieee80211_sub_if_data *sdata) | |||
| 841 | 841 | ||
| 842 | dir = sdata->vif.debugfs_dir; | 842 | dir = sdata->vif.debugfs_dir; |
| 843 | 843 | ||
| 844 | if (!dir) | 844 | if (IS_ERR_OR_NULL(dir)) |
| 845 | return; | 845 | return; |
| 846 | 846 | ||
| 847 | sprintf(buf, "netdev:%s", sdata->name); | 847 | sprintf(buf, "netdev:%s", sdata->name); |
diff --git a/net/mac80211/ht.c b/net/mac80211/ht.c index e03c46ac8e4d..c62101857b9b 100644 --- a/net/mac80211/ht.c +++ b/net/mac80211/ht.c | |||
| @@ -112,8 +112,9 @@ void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, | |||
| 112 | IEEE80211_HT_CAP_TX_STBC); | 112 | IEEE80211_HT_CAP_TX_STBC); |
| 113 | 113 | ||
| 114 | /* Allow user to configure RX STBC bits */ | 114 | /* Allow user to configure RX STBC bits */ |
| 115 | if (ht_capa_mask->cap_info & IEEE80211_HT_CAP_RX_STBC) | 115 | if (ht_capa_mask->cap_info & cpu_to_le16(IEEE80211_HT_CAP_RX_STBC)) |
| 116 | ht_cap->cap |= ht_capa->cap_info & IEEE80211_HT_CAP_RX_STBC; | 116 | ht_cap->cap |= le16_to_cpu(ht_capa->cap_info) & |
| 117 | IEEE80211_HT_CAP_RX_STBC; | ||
| 117 | 118 | ||
| 118 | /* Allow user to decrease AMPDU factor */ | 119 | /* Allow user to decrease AMPDU factor */ |
| 119 | if (ht_capa_mask->ampdu_params_info & | 120 | if (ht_capa_mask->ampdu_params_info & |
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c index 4a6ff1482a9f..02d2e6f11e93 100644 --- a/net/mac80211/iface.c +++ b/net/mac80211/iface.c | |||
| @@ -1908,6 +1908,9 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata) | |||
| 1908 | list_del_rcu(&sdata->list); | 1908 | list_del_rcu(&sdata->list); |
| 1909 | mutex_unlock(&sdata->local->iflist_mtx); | 1909 | mutex_unlock(&sdata->local->iflist_mtx); |
| 1910 | 1910 | ||
| 1911 | if (sdata->vif.txq) | ||
| 1912 | ieee80211_txq_purge(sdata->local, to_txq_info(sdata->vif.txq)); | ||
| 1913 | |||
| 1911 | synchronize_rcu(); | 1914 | synchronize_rcu(); |
| 1912 | 1915 | ||
| 1913 | if (sdata->dev) { | 1916 | if (sdata->dev) { |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index f0ec068e1d02..cb69d35c8e6a 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
| @@ -362,8 +362,8 @@ int genl_register_family(struct genl_family *family) | |||
| 362 | } else | 362 | } else |
| 363 | family->attrbuf = NULL; | 363 | family->attrbuf = NULL; |
| 364 | 364 | ||
| 365 | family->id = idr_alloc(&genl_fam_idr, family, | 365 | family->id = idr_alloc_cyclic(&genl_fam_idr, family, |
| 366 | start, end + 1, GFP_KERNEL); | 366 | start, end + 1, GFP_KERNEL); |
| 367 | if (family->id < 0) { | 367 | if (family->id < 0) { |
| 368 | err = family->id; | 368 | err = family->id; |
| 369 | goto errout_free; | 369 | goto errout_free; |
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 9419c5cf4de5..9b81813dd16a 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
| @@ -2602,8 +2602,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2602 | void *ph; | 2602 | void *ph; |
| 2603 | DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); | 2603 | DECLARE_SOCKADDR(struct sockaddr_ll *, saddr, msg->msg_name); |
| 2604 | bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); | 2604 | bool need_wait = !(msg->msg_flags & MSG_DONTWAIT); |
| 2605 | unsigned char *addr = NULL; | ||
| 2605 | int tp_len, size_max; | 2606 | int tp_len, size_max; |
| 2606 | unsigned char *addr; | ||
| 2607 | void *data; | 2607 | void *data; |
| 2608 | int len_sum = 0; | 2608 | int len_sum = 0; |
| 2609 | int status = TP_STATUS_AVAILABLE; | 2609 | int status = TP_STATUS_AVAILABLE; |
| @@ -2614,7 +2614,6 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2614 | if (likely(saddr == NULL)) { | 2614 | if (likely(saddr == NULL)) { |
| 2615 | dev = packet_cached_dev_get(po); | 2615 | dev = packet_cached_dev_get(po); |
| 2616 | proto = po->num; | 2616 | proto = po->num; |
| 2617 | addr = NULL; | ||
| 2618 | } else { | 2617 | } else { |
| 2619 | err = -EINVAL; | 2618 | err = -EINVAL; |
| 2620 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) | 2619 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) |
| @@ -2624,10 +2623,13 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
| 2624 | sll_addr))) | 2623 | sll_addr))) |
| 2625 | goto out; | 2624 | goto out; |
| 2626 | proto = saddr->sll_protocol; | 2625 | proto = saddr->sll_protocol; |
| 2627 | addr = saddr->sll_halen ? saddr->sll_addr : NULL; | ||
| 2628 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | 2626 | dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); |
| 2629 | if (addr && dev && saddr->sll_halen < dev->addr_len) | 2627 | if (po->sk.sk_socket->type == SOCK_DGRAM) { |
| 2630 | goto out_put; | 2628 | if (dev && msg->msg_namelen < dev->addr_len + |
| 2629 | offsetof(struct sockaddr_ll, sll_addr)) | ||
| 2630 | goto out_put; | ||
| 2631 | addr = saddr->sll_addr; | ||
| 2632 | } | ||
| 2631 | } | 2633 | } |
| 2632 | 2634 | ||
| 2633 | err = -ENXIO; | 2635 | err = -ENXIO; |
| @@ -2799,7 +2801,7 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
| 2799 | struct sk_buff *skb; | 2801 | struct sk_buff *skb; |
| 2800 | struct net_device *dev; | 2802 | struct net_device *dev; |
| 2801 | __be16 proto; | 2803 | __be16 proto; |
| 2802 | unsigned char *addr; | 2804 | unsigned char *addr = NULL; |
| 2803 | int err, reserve = 0; | 2805 | int err, reserve = 0; |
| 2804 | struct sockcm_cookie sockc; | 2806 | struct sockcm_cookie sockc; |
| 2805 | struct virtio_net_hdr vnet_hdr = { 0 }; | 2807 | struct virtio_net_hdr vnet_hdr = { 0 }; |
| @@ -2816,7 +2818,6 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
| 2816 | if (likely(saddr == NULL)) { | 2818 | if (likely(saddr == NULL)) { |
| 2817 | dev = packet_cached_dev_get(po); | 2819 | dev = packet_cached_dev_get(po); |
| 2818 | proto = po->num; | 2820 | proto = po->num; |
| 2819 | addr = NULL; | ||
| 2820 | } else { | 2821 | } else { |
| 2821 | err = -EINVAL; | 2822 | err = -EINVAL; |
| 2822 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) | 2823 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) |
| @@ -2824,10 +2825,13 @@ static int packet_snd(struct socket *sock, struct msghdr *msg, size_t len) | |||
| 2824 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) | 2825 | if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) |
| 2825 | goto out; | 2826 | goto out; |
| 2826 | proto = saddr->sll_protocol; | 2827 | proto = saddr->sll_protocol; |
| 2827 | addr = saddr->sll_halen ? saddr->sll_addr : NULL; | ||
| 2828 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); | 2828 | dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); |
| 2829 | if (addr && dev && saddr->sll_halen < dev->addr_len) | 2829 | if (sock->type == SOCK_DGRAM) { |
| 2830 | goto out_unlock; | 2830 | if (dev && msg->msg_namelen < dev->addr_len + |
| 2831 | offsetof(struct sockaddr_ll, sll_addr)) | ||
| 2832 | goto out_unlock; | ||
| 2833 | addr = saddr->sll_addr; | ||
| 2834 | } | ||
| 2831 | } | 2835 | } |
| 2832 | 2836 | ||
| 2833 | err = -ENXIO; | 2837 | err = -ENXIO; |
| @@ -3344,20 +3348,29 @@ static int packet_recvmsg(struct socket *sock, struct msghdr *msg, size_t len, | |||
| 3344 | sock_recv_ts_and_drops(msg, sk, skb); | 3348 | sock_recv_ts_and_drops(msg, sk, skb); |
| 3345 | 3349 | ||
| 3346 | if (msg->msg_name) { | 3350 | if (msg->msg_name) { |
| 3351 | int copy_len; | ||
| 3352 | |||
| 3347 | /* If the address length field is there to be filled | 3353 | /* If the address length field is there to be filled |
| 3348 | * in, we fill it in now. | 3354 | * in, we fill it in now. |
| 3349 | */ | 3355 | */ |
| 3350 | if (sock->type == SOCK_PACKET) { | 3356 | if (sock->type == SOCK_PACKET) { |
| 3351 | __sockaddr_check_size(sizeof(struct sockaddr_pkt)); | 3357 | __sockaddr_check_size(sizeof(struct sockaddr_pkt)); |
| 3352 | msg->msg_namelen = sizeof(struct sockaddr_pkt); | 3358 | msg->msg_namelen = sizeof(struct sockaddr_pkt); |
| 3359 | copy_len = msg->msg_namelen; | ||
| 3353 | } else { | 3360 | } else { |
| 3354 | struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; | 3361 | struct sockaddr_ll *sll = &PACKET_SKB_CB(skb)->sa.ll; |
| 3355 | 3362 | ||
| 3356 | msg->msg_namelen = sll->sll_halen + | 3363 | msg->msg_namelen = sll->sll_halen + |
| 3357 | offsetof(struct sockaddr_ll, sll_addr); | 3364 | offsetof(struct sockaddr_ll, sll_addr); |
| 3365 | copy_len = msg->msg_namelen; | ||
| 3366 | if (msg->msg_namelen < sizeof(struct sockaddr_ll)) { | ||
| 3367 | memset(msg->msg_name + | ||
| 3368 | offsetof(struct sockaddr_ll, sll_addr), | ||
| 3369 | 0, sizeof(sll->sll_addr)); | ||
| 3370 | msg->msg_namelen = sizeof(struct sockaddr_ll); | ||
| 3371 | } | ||
| 3358 | } | 3372 | } |
| 3359 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, | 3373 | memcpy(msg->msg_name, &PACKET_SKB_CB(skb)->sa, copy_len); |
| 3360 | msg->msg_namelen); | ||
| 3361 | } | 3374 | } |
| 3362 | 3375 | ||
| 3363 | if (pkt_sk(sk)->auxdata) { | 3376 | if (pkt_sk(sk)->auxdata) { |
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c index 70559854837e..8946c89d7392 100644 --- a/net/rds/ib_recv.c +++ b/net/rds/ib_recv.c | |||
| @@ -772,7 +772,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, | |||
| 772 | unsigned long frag_off; | 772 | unsigned long frag_off; |
| 773 | unsigned long to_copy; | 773 | unsigned long to_copy; |
| 774 | unsigned long copied; | 774 | unsigned long copied; |
| 775 | uint64_t uncongested = 0; | 775 | __le64 uncongested = 0; |
| 776 | void *addr; | 776 | void *addr; |
| 777 | 777 | ||
| 778 | /* catch completely corrupt packets */ | 778 | /* catch completely corrupt packets */ |
| @@ -789,7 +789,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, | |||
| 789 | copied = 0; | 789 | copied = 0; |
| 790 | 790 | ||
| 791 | while (copied < RDS_CONG_MAP_BYTES) { | 791 | while (copied < RDS_CONG_MAP_BYTES) { |
| 792 | uint64_t *src, *dst; | 792 | __le64 *src, *dst; |
| 793 | unsigned int k; | 793 | unsigned int k; |
| 794 | 794 | ||
| 795 | to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off); | 795 | to_copy = min(RDS_FRAG_SIZE - frag_off, PAGE_SIZE - map_off); |
| @@ -824,9 +824,7 @@ static void rds_ib_cong_recv(struct rds_connection *conn, | |||
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | /* the congestion map is in little endian order */ | 826 | /* the congestion map is in little endian order */ |
| 827 | uncongested = le64_to_cpu(uncongested); | 827 | rds_cong_map_updated(map, le64_to_cpu(uncongested)); |
| 828 | |||
| 829 | rds_cong_map_updated(map, uncongested); | ||
| 830 | } | 828 | } |
| 831 | 829 | ||
| 832 | static void rds_ib_process_recv(struct rds_connection *conn, | 830 | static void rds_ib_process_recv(struct rds_connection *conn, |
diff --git a/net/rxrpc/call_object.c b/net/rxrpc/call_object.c index 8aa2937b069f..fe96881a334d 100644 --- a/net/rxrpc/call_object.c +++ b/net/rxrpc/call_object.c | |||
| @@ -604,30 +604,30 @@ void rxrpc_destroy_all_calls(struct rxrpc_net *rxnet) | |||
| 604 | 604 | ||
| 605 | _enter(""); | 605 | _enter(""); |
| 606 | 606 | ||
| 607 | if (list_empty(&rxnet->calls)) | 607 | if (!list_empty(&rxnet->calls)) { |
| 608 | return; | 608 | write_lock(&rxnet->call_lock); |
| 609 | 609 | ||
| 610 | write_lock(&rxnet->call_lock); | 610 | while (!list_empty(&rxnet->calls)) { |
| 611 | call = list_entry(rxnet->calls.next, | ||
| 612 | struct rxrpc_call, link); | ||
| 613 | _debug("Zapping call %p", call); | ||
| 611 | 614 | ||
| 612 | while (!list_empty(&rxnet->calls)) { | 615 | rxrpc_see_call(call); |
| 613 | call = list_entry(rxnet->calls.next, struct rxrpc_call, link); | 616 | list_del_init(&call->link); |
| 614 | _debug("Zapping call %p", call); | ||
| 615 | 617 | ||
| 616 | rxrpc_see_call(call); | 618 | pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", |
| 617 | list_del_init(&call->link); | 619 | call, atomic_read(&call->usage), |
| 620 | rxrpc_call_states[call->state], | ||
| 621 | call->flags, call->events); | ||
| 618 | 622 | ||
| 619 | pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n", | 623 | write_unlock(&rxnet->call_lock); |
| 620 | call, atomic_read(&call->usage), | 624 | cond_resched(); |
| 621 | rxrpc_call_states[call->state], | 625 | write_lock(&rxnet->call_lock); |
| 622 | call->flags, call->events); | 626 | } |
| 623 | 627 | ||
| 624 | write_unlock(&rxnet->call_lock); | 628 | write_unlock(&rxnet->call_lock); |
| 625 | cond_resched(); | ||
| 626 | write_lock(&rxnet->call_lock); | ||
| 627 | } | 629 | } |
| 628 | 630 | ||
| 629 | write_unlock(&rxnet->call_lock); | ||
| 630 | |||
| 631 | atomic_dec(&rxnet->nr_calls); | 631 | atomic_dec(&rxnet->nr_calls); |
| 632 | wait_var_event(&rxnet->nr_calls, !atomic_read(&rxnet->nr_calls)); | 632 | wait_var_event(&rxnet->nr_calls, !atomic_read(&rxnet->nr_calls)); |
| 633 | } | 633 | } |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 1d143bc3f73d..4aa03588f87b 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
| @@ -1112,32 +1112,6 @@ static void sctp_cmd_send_msg(struct sctp_association *asoc, | |||
| 1112 | } | 1112 | } |
| 1113 | 1113 | ||
| 1114 | 1114 | ||
| 1115 | /* Sent the next ASCONF packet currently stored in the association. | ||
| 1116 | * This happens after the ASCONF_ACK was succeffully processed. | ||
| 1117 | */ | ||
| 1118 | static void sctp_cmd_send_asconf(struct sctp_association *asoc) | ||
| 1119 | { | ||
| 1120 | struct net *net = sock_net(asoc->base.sk); | ||
| 1121 | |||
| 1122 | /* Send the next asconf chunk from the addip chunk | ||
| 1123 | * queue. | ||
| 1124 | */ | ||
| 1125 | if (!list_empty(&asoc->addip_chunk_list)) { | ||
| 1126 | struct list_head *entry = asoc->addip_chunk_list.next; | ||
| 1127 | struct sctp_chunk *asconf = list_entry(entry, | ||
| 1128 | struct sctp_chunk, list); | ||
| 1129 | list_del_init(entry); | ||
| 1130 | |||
| 1131 | /* Hold the chunk until an ASCONF_ACK is received. */ | ||
| 1132 | sctp_chunk_hold(asconf); | ||
| 1133 | if (sctp_primitive_ASCONF(net, asoc, asconf)) | ||
| 1134 | sctp_chunk_free(asconf); | ||
| 1135 | else | ||
| 1136 | asoc->addip_last_asconf = asconf; | ||
| 1137 | } | ||
| 1138 | } | ||
| 1139 | |||
| 1140 | |||
| 1141 | /* These three macros allow us to pull the debugging code out of the | 1115 | /* These three macros allow us to pull the debugging code out of the |
| 1142 | * main flow of sctp_do_sm() to keep attention focused on the real | 1116 | * main flow of sctp_do_sm() to keep attention focused on the real |
| 1143 | * functionality there. | 1117 | * functionality there. |
| @@ -1783,9 +1757,6 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type, | |||
| 1783 | } | 1757 | } |
| 1784 | sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); | 1758 | sctp_cmd_send_msg(asoc, cmd->obj.msg, gfp); |
| 1785 | break; | 1759 | break; |
| 1786 | case SCTP_CMD_SEND_NEXT_ASCONF: | ||
| 1787 | sctp_cmd_send_asconf(asoc); | ||
| 1788 | break; | ||
| 1789 | case SCTP_CMD_PURGE_ASCONF_QUEUE: | 1760 | case SCTP_CMD_PURGE_ASCONF_QUEUE: |
| 1790 | sctp_asconf_queue_teardown(asoc); | 1761 | sctp_asconf_queue_teardown(asoc); |
| 1791 | break; | 1762 | break; |
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c index c9ae3404b1bb..713a669d2058 100644 --- a/net/sctp/sm_statefuns.c +++ b/net/sctp/sm_statefuns.c | |||
| @@ -3824,6 +3824,29 @@ enum sctp_disposition sctp_sf_do_asconf(struct net *net, | |||
| 3824 | return SCTP_DISPOSITION_CONSUME; | 3824 | return SCTP_DISPOSITION_CONSUME; |
| 3825 | } | 3825 | } |
| 3826 | 3826 | ||
| 3827 | static enum sctp_disposition sctp_send_next_asconf( | ||
| 3828 | struct net *net, | ||
| 3829 | const struct sctp_endpoint *ep, | ||
| 3830 | struct sctp_association *asoc, | ||
| 3831 | const union sctp_subtype type, | ||
| 3832 | struct sctp_cmd_seq *commands) | ||
| 3833 | { | ||
| 3834 | struct sctp_chunk *asconf; | ||
| 3835 | struct list_head *entry; | ||
| 3836 | |||
| 3837 | if (list_empty(&asoc->addip_chunk_list)) | ||
| 3838 | return SCTP_DISPOSITION_CONSUME; | ||
| 3839 | |||
| 3840 | entry = asoc->addip_chunk_list.next; | ||
| 3841 | asconf = list_entry(entry, struct sctp_chunk, list); | ||
| 3842 | |||
| 3843 | list_del_init(entry); | ||
| 3844 | sctp_chunk_hold(asconf); | ||
| 3845 | asoc->addip_last_asconf = asconf; | ||
| 3846 | |||
| 3847 | return sctp_sf_do_prm_asconf(net, ep, asoc, type, asconf, commands); | ||
| 3848 | } | ||
| 3849 | |||
| 3827 | /* | 3850 | /* |
| 3828 | * ADDIP Section 4.3 General rules for address manipulation | 3851 | * ADDIP Section 4.3 General rules for address manipulation |
| 3829 | * When building TLV parameters for the ASCONF Chunk that will add or | 3852 | * When building TLV parameters for the ASCONF Chunk that will add or |
| @@ -3915,14 +3938,10 @@ enum sctp_disposition sctp_sf_do_asconf_ack(struct net *net, | |||
| 3915 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); | 3938 | SCTP_TO(SCTP_EVENT_TIMEOUT_T4_RTO)); |
| 3916 | 3939 | ||
| 3917 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, | 3940 | if (!sctp_process_asconf_ack((struct sctp_association *)asoc, |
| 3918 | asconf_ack)) { | 3941 | asconf_ack)) |
| 3919 | /* Successfully processed ASCONF_ACK. We can | 3942 | return sctp_send_next_asconf(net, ep, |
| 3920 | * release the next asconf if we have one. | 3943 | (struct sctp_association *)asoc, |
| 3921 | */ | 3944 | type, commands); |
| 3922 | sctp_add_cmd_sf(commands, SCTP_CMD_SEND_NEXT_ASCONF, | ||
| 3923 | SCTP_NULL()); | ||
| 3924 | return SCTP_DISPOSITION_CONSUME; | ||
| 3925 | } | ||
| 3926 | 3945 | ||
| 3927 | abort = sctp_make_abort(asoc, asconf_ack, | 3946 | abort = sctp_make_abort(asoc, asconf_ack, |
| 3928 | sizeof(struct sctp_errhdr)); | 3947 | sizeof(struct sctp_errhdr)); |
diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index cc0256939eb6..14dedb24fa7b 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c | |||
| @@ -597,7 +597,7 @@ void handle_device_resync(struct sock *sk, u32 seq, u64 rcd_sn) | |||
| 597 | static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) | 597 | static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) |
| 598 | { | 598 | { |
| 599 | struct strp_msg *rxm = strp_msg(skb); | 599 | struct strp_msg *rxm = strp_msg(skb); |
| 600 | int err = 0, offset = rxm->offset, copy, nsg; | 600 | int err = 0, offset = rxm->offset, copy, nsg, data_len, pos; |
| 601 | struct sk_buff *skb_iter, *unused; | 601 | struct sk_buff *skb_iter, *unused; |
| 602 | struct scatterlist sg[1]; | 602 | struct scatterlist sg[1]; |
| 603 | char *orig_buf, *buf; | 603 | char *orig_buf, *buf; |
| @@ -628,25 +628,42 @@ static int tls_device_reencrypt(struct sock *sk, struct sk_buff *skb) | |||
| 628 | else | 628 | else |
| 629 | err = 0; | 629 | err = 0; |
| 630 | 630 | ||
| 631 | copy = min_t(int, skb_pagelen(skb) - offset, | 631 | data_len = rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE; |
| 632 | rxm->full_len - TLS_CIPHER_AES_GCM_128_TAG_SIZE); | ||
| 633 | 632 | ||
| 634 | if (skb->decrypted) | 633 | if (skb_pagelen(skb) > offset) { |
| 635 | skb_store_bits(skb, offset, buf, copy); | 634 | copy = min_t(int, skb_pagelen(skb) - offset, data_len); |
| 636 | 635 | ||
| 637 | offset += copy; | 636 | if (skb->decrypted) |
| 638 | buf += copy; | 637 | skb_store_bits(skb, offset, buf, copy); |
| 639 | 638 | ||
| 639 | offset += copy; | ||
| 640 | buf += copy; | ||
| 641 | } | ||
| 642 | |||
| 643 | pos = skb_pagelen(skb); | ||
| 640 | skb_walk_frags(skb, skb_iter) { | 644 | skb_walk_frags(skb, skb_iter) { |
| 641 | copy = min_t(int, skb_iter->len, | 645 | int frag_pos; |
| 642 | rxm->full_len - offset + rxm->offset - | 646 | |
| 643 | TLS_CIPHER_AES_GCM_128_TAG_SIZE); | 647 | /* Practically all frags must belong to msg if reencrypt |
| 648 | * is needed with current strparser and coalescing logic, | ||
| 649 | * but strparser may "get optimized", so let's be safe. | ||
| 650 | */ | ||
| 651 | if (pos + skb_iter->len <= offset) | ||
| 652 | goto done_with_frag; | ||
| 653 | if (pos >= data_len + rxm->offset) | ||
| 654 | break; | ||
| 655 | |||
| 656 | frag_pos = offset - pos; | ||
| 657 | copy = min_t(int, skb_iter->len - frag_pos, | ||
| 658 | data_len + rxm->offset - offset); | ||
| 644 | 659 | ||
| 645 | if (skb_iter->decrypted) | 660 | if (skb_iter->decrypted) |
| 646 | skb_store_bits(skb_iter, offset, buf, copy); | 661 | skb_store_bits(skb_iter, frag_pos, buf, copy); |
| 647 | 662 | ||
| 648 | offset += copy; | 663 | offset += copy; |
| 649 | buf += copy; | 664 | buf += copy; |
| 665 | done_with_frag: | ||
| 666 | pos += skb_iter->len; | ||
| 650 | } | 667 | } |
| 651 | 668 | ||
| 652 | free_buf: | 669 | free_buf: |
diff --git a/net/tls/tls_device_fallback.c b/net/tls/tls_device_fallback.c index a3ebd4b02714..c3a5fe624b4e 100644 --- a/net/tls/tls_device_fallback.c +++ b/net/tls/tls_device_fallback.c | |||
| @@ -201,13 +201,14 @@ static void complete_skb(struct sk_buff *nskb, struct sk_buff *skb, int headln) | |||
| 201 | 201 | ||
| 202 | skb_put(nskb, skb->len); | 202 | skb_put(nskb, skb->len); |
| 203 | memcpy(nskb->data, skb->data, headln); | 203 | memcpy(nskb->data, skb->data, headln); |
| 204 | update_chksum(nskb, headln); | ||
| 205 | 204 | ||
| 206 | nskb->destructor = skb->destructor; | 205 | nskb->destructor = skb->destructor; |
| 207 | nskb->sk = sk; | 206 | nskb->sk = sk; |
| 208 | skb->destructor = NULL; | 207 | skb->destructor = NULL; |
| 209 | skb->sk = NULL; | 208 | skb->sk = NULL; |
| 210 | 209 | ||
| 210 | update_chksum(nskb, headln); | ||
| 211 | |||
| 211 | delta = nskb->truesize - skb->truesize; | 212 | delta = nskb->truesize - skb->truesize; |
| 212 | if (likely(delta < 0)) | 213 | if (likely(delta < 0)) |
| 213 | WARN_ON_ONCE(refcount_sub_and_test(-delta, &sk->sk_wmem_alloc)); | 214 | WARN_ON_ONCE(refcount_sub_and_test(-delta, &sk->sk_wmem_alloc)); |
diff --git a/net/wireless/reg.c b/net/wireless/reg.c index 0ba778f371cb..a6fd5ce199da 100644 --- a/net/wireless/reg.c +++ b/net/wireless/reg.c | |||
| @@ -3778,10 +3778,9 @@ void wiphy_regulatory_register(struct wiphy *wiphy) | |||
| 3778 | /* | 3778 | /* |
| 3779 | * The last request may have been received before this | 3779 | * The last request may have been received before this |
| 3780 | * registration call. Call the driver notifier if | 3780 | * registration call. Call the driver notifier if |
| 3781 | * initiator is USER and user type is CELL_BASE. | 3781 | * initiator is USER. |
| 3782 | */ | 3782 | */ |
| 3783 | if (lr->initiator == NL80211_REGDOM_SET_BY_USER && | 3783 | if (lr->initiator == NL80211_REGDOM_SET_BY_USER) |
| 3784 | lr->user_reg_hint_type == NL80211_USER_REG_HINT_CELL_BASE) | ||
| 3785 | reg_call_notifier(wiphy, lr); | 3784 | reg_call_notifier(wiphy, lr); |
| 3786 | } | 3785 | } |
| 3787 | 3786 | ||
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c index dbb3c1945b5c..85fec98676d3 100644 --- a/net/xfrm/xfrm_interface.c +++ b/net/xfrm/xfrm_interface.c | |||
| @@ -70,17 +70,28 @@ static struct xfrm_if *xfrmi_lookup(struct net *net, struct xfrm_state *x) | |||
| 70 | return NULL; | 70 | return NULL; |
| 71 | } | 71 | } |
| 72 | 72 | ||
| 73 | static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb) | 73 | static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb, |
| 74 | unsigned short family) | ||
| 74 | { | 75 | { |
| 75 | struct xfrmi_net *xfrmn; | 76 | struct xfrmi_net *xfrmn; |
| 76 | int ifindex; | ||
| 77 | struct xfrm_if *xi; | 77 | struct xfrm_if *xi; |
| 78 | int ifindex = 0; | ||
| 78 | 79 | ||
| 79 | if (!secpath_exists(skb) || !skb->dev) | 80 | if (!secpath_exists(skb) || !skb->dev) |
| 80 | return NULL; | 81 | return NULL; |
| 81 | 82 | ||
| 83 | switch (family) { | ||
| 84 | case AF_INET6: | ||
| 85 | ifindex = inet6_sdif(skb); | ||
| 86 | break; | ||
| 87 | case AF_INET: | ||
| 88 | ifindex = inet_sdif(skb); | ||
| 89 | break; | ||
| 90 | } | ||
| 91 | if (!ifindex) | ||
| 92 | ifindex = skb->dev->ifindex; | ||
| 93 | |||
| 82 | xfrmn = net_generic(xs_net(xfrm_input_state(skb)), xfrmi_net_id); | 94 | xfrmn = net_generic(xs_net(xfrm_input_state(skb)), xfrmi_net_id); |
| 83 | ifindex = skb->dev->ifindex; | ||
| 84 | 95 | ||
| 85 | for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) { | 96 | for_each_xfrmi_rcu(xfrmn->xfrmi[0], xi) { |
| 86 | if (ifindex == xi->dev->ifindex && | 97 | if (ifindex == xi->dev->ifindex && |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 8d1a898d0ba5..a6b58df7a70f 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
| @@ -3313,7 +3313,7 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, | |||
| 3313 | ifcb = xfrm_if_get_cb(); | 3313 | ifcb = xfrm_if_get_cb(); |
| 3314 | 3314 | ||
| 3315 | if (ifcb) { | 3315 | if (ifcb) { |
| 3316 | xi = ifcb->decode_session(skb); | 3316 | xi = ifcb->decode_session(skb, family); |
| 3317 | if (xi) { | 3317 | if (xi) { |
| 3318 | if_id = xi->p.if_id; | 3318 | if_id = xi->p.if_id; |
| 3319 | net = xi->net; | 3319 | net = xi->net; |
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index 1bb971f46fc6..178baaa037e5 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c | |||
| @@ -2384,7 +2384,7 @@ void xfrm_state_fini(struct net *net) | |||
| 2384 | 2384 | ||
| 2385 | flush_work(&net->xfrm.state_hash_work); | 2385 | flush_work(&net->xfrm.state_hash_work); |
| 2386 | flush_work(&xfrm_state_gc_work); | 2386 | flush_work(&xfrm_state_gc_work); |
| 2387 | xfrm_state_flush(net, IPSEC_PROTO_ANY, false, true); | 2387 | xfrm_state_flush(net, 0, false, true); |
| 2388 | 2388 | ||
| 2389 | WARN_ON(!list_empty(&net->xfrm.state_all)); | 2389 | WARN_ON(!list_empty(&net->xfrm.state_all)); |
| 2390 | 2390 | ||
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index a131f9ff979e..6916931b1de1 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
| @@ -1424,7 +1424,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p) | |||
| 1424 | ret = verify_policy_dir(p->dir); | 1424 | ret = verify_policy_dir(p->dir); |
| 1425 | if (ret) | 1425 | if (ret) |
| 1426 | return ret; | 1426 | return ret; |
| 1427 | if (p->index && ((p->index & XFRM_POLICY_MAX) != p->dir)) | 1427 | if (p->index && (xfrm_policy_id2dir(p->index) != p->dir)) |
| 1428 | return -EINVAL; | 1428 | return -EINVAL; |
| 1429 | 1429 | ||
| 1430 | return 0; | 1430 | return 0; |
| @@ -1513,20 +1513,8 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family) | |||
| 1513 | return -EINVAL; | 1513 | return -EINVAL; |
| 1514 | } | 1514 | } |
| 1515 | 1515 | ||
| 1516 | switch (ut[i].id.proto) { | 1516 | if (!xfrm_id_proto_valid(ut[i].id.proto)) |
| 1517 | case IPPROTO_AH: | ||
| 1518 | case IPPROTO_ESP: | ||
| 1519 | case IPPROTO_COMP: | ||
| 1520 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 1521 | case IPPROTO_ROUTING: | ||
| 1522 | case IPPROTO_DSTOPTS: | ||
| 1523 | #endif | ||
| 1524 | case IPSEC_PROTO_ANY: | ||
| 1525 | break; | ||
| 1526 | default: | ||
| 1527 | return -EINVAL; | 1517 | return -EINVAL; |
| 1528 | } | ||
| 1529 | |||
| 1530 | } | 1518 | } |
| 1531 | 1519 | ||
| 1532 | return 0; | 1520 | return 0; |
diff --git a/tools/bpf/bpftool/map.c b/tools/bpf/bpftool/map.c index e0c650d91784..994a7e0d16fb 100644 --- a/tools/bpf/bpftool/map.c +++ b/tools/bpf/bpftool/map.c | |||
| @@ -1151,6 +1151,9 @@ static int do_create(int argc, char **argv) | |||
| 1151 | return -1; | 1151 | return -1; |
| 1152 | } | 1152 | } |
| 1153 | NEXT_ARG(); | 1153 | NEXT_ARG(); |
| 1154 | } else { | ||
| 1155 | p_err("unknown arg %s", *argv); | ||
| 1156 | return -1; | ||
| 1154 | } | 1157 | } |
| 1155 | } | 1158 | } |
| 1156 | 1159 | ||
diff --git a/tools/lib/bpf/.gitignore b/tools/lib/bpf/.gitignore index 4db74758c674..fecb78afea3f 100644 --- a/tools/lib/bpf/.gitignore +++ b/tools/lib/bpf/.gitignore | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | libbpf_version.h | 1 | libbpf_version.h |
| 2 | FEATURE-DUMP.libbpf | 2 | FEATURE-DUMP.libbpf |
| 3 | test_libbpf | 3 | test_libbpf |
| 4 | libbpf.so.* | ||
diff --git a/tools/testing/selftests/bpf/verifier/calls.c b/tools/testing/selftests/bpf/verifier/calls.c index fb11240b758b..9093a8f64dc6 100644 --- a/tools/testing/selftests/bpf/verifier/calls.c +++ b/tools/testing/selftests/bpf/verifier/calls.c | |||
| @@ -375,6 +375,31 @@ | |||
| 375 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, | 375 | .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS, |
| 376 | }, | 376 | }, |
| 377 | { | 377 | { |
| 378 | "calls: ptr null check in subprog", | ||
| 379 | .insns = { | ||
| 380 | BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0), | ||
| 381 | BPF_MOV64_REG(BPF_REG_2, BPF_REG_10), | ||
| 382 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8), | ||
| 383 | BPF_LD_MAP_FD(BPF_REG_1, 0), | ||
| 384 | BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem), | ||
| 385 | BPF_MOV64_REG(BPF_REG_1, BPF_REG_0), | ||
| 386 | BPF_MOV64_REG(BPF_REG_6, BPF_REG_0), | ||
| 387 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 3), | ||
| 388 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), | ||
| 389 | BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), | ||
| 390 | BPF_EXIT_INSN(), | ||
| 391 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 392 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_1, 0, 1), | ||
| 393 | BPF_MOV64_IMM(BPF_REG_0, 1), | ||
| 394 | BPF_EXIT_INSN(), | ||
| 395 | }, | ||
| 396 | .errstr_unpriv = "function calls to other bpf functions are allowed for root only", | ||
| 397 | .fixup_map_hash_48b = { 3 }, | ||
| 398 | .result_unpriv = REJECT, | ||
| 399 | .result = ACCEPT, | ||
| 400 | .retval = 0, | ||
| 401 | }, | ||
| 402 | { | ||
| 378 | "calls: two calls with args", | 403 | "calls: two calls with args", |
| 379 | .insns = { | 404 | .insns = { |
| 380 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), | 405 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 1), |
diff --git a/tools/testing/selftests/bpf/verifier/direct_packet_access.c b/tools/testing/selftests/bpf/verifier/direct_packet_access.c index e3fc22e672c2..d5c596fdc4b9 100644 --- a/tools/testing/selftests/bpf/verifier/direct_packet_access.c +++ b/tools/testing/selftests/bpf/verifier/direct_packet_access.c | |||
| @@ -631,3 +631,25 @@ | |||
| 631 | .errstr = "invalid access to packet", | 631 | .errstr = "invalid access to packet", |
| 632 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | 632 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, |
| 633 | }, | 633 | }, |
| 634 | { | ||
| 635 | "direct packet access: test29 (reg > pkt_end in subprog)", | ||
| 636 | .insns = { | ||
| 637 | BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_1, | ||
| 638 | offsetof(struct __sk_buff, data)), | ||
| 639 | BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, | ||
| 640 | offsetof(struct __sk_buff, data_end)), | ||
| 641 | BPF_MOV64_REG(BPF_REG_3, BPF_REG_6), | ||
| 642 | BPF_ALU64_IMM(BPF_ADD, BPF_REG_3, 8), | ||
| 643 | BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 4), | ||
| 644 | BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1), | ||
| 645 | BPF_LDX_MEM(BPF_B, BPF_REG_0, BPF_REG_6, 0), | ||
| 646 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 647 | BPF_EXIT_INSN(), | ||
| 648 | BPF_MOV64_IMM(BPF_REG_0, 0), | ||
| 649 | BPF_JMP_REG(BPF_JGT, BPF_REG_3, BPF_REG_2, 1), | ||
| 650 | BPF_MOV64_IMM(BPF_REG_0, 1), | ||
| 651 | BPF_EXIT_INSN(), | ||
| 652 | }, | ||
| 653 | .result = ACCEPT, | ||
| 654 | .prog_type = BPF_PROG_TYPE_SCHED_CLS, | ||
| 655 | }, | ||
diff --git a/tools/testing/selftests/net/fib_rule_tests.sh b/tools/testing/selftests/net/fib_rule_tests.sh index d4cfb6a7a086..4b7e107865bf 100755 --- a/tools/testing/selftests/net/fib_rule_tests.sh +++ b/tools/testing/selftests/net/fib_rule_tests.sh | |||
| @@ -27,6 +27,7 @@ log_test() | |||
| 27 | nsuccess=$((nsuccess+1)) | 27 | nsuccess=$((nsuccess+1)) |
| 28 | printf "\n TEST: %-50s [ OK ]\n" "${msg}" | 28 | printf "\n TEST: %-50s [ OK ]\n" "${msg}" |
| 29 | else | 29 | else |
| 30 | ret=1 | ||
| 30 | nfail=$((nfail+1)) | 31 | nfail=$((nfail+1)) |
| 31 | printf "\n TEST: %-50s [FAIL]\n" "${msg}" | 32 | printf "\n TEST: %-50s [FAIL]\n" "${msg}" |
| 32 | if [ "${PAUSE_ON_FAIL}" = "yes" ]; then | 33 | if [ "${PAUSE_ON_FAIL}" = "yes" ]; then |
| @@ -147,8 +148,8 @@ fib_rule6_test() | |||
| 147 | 148 | ||
| 148 | fib_check_iproute_support "ipproto" "ipproto" | 149 | fib_check_iproute_support "ipproto" "ipproto" |
| 149 | if [ $? -eq 0 ]; then | 150 | if [ $? -eq 0 ]; then |
| 150 | match="ipproto icmp" | 151 | match="ipproto ipv6-icmp" |
| 151 | fib_rule6_test_match_n_redirect "$match" "$match" "ipproto icmp match" | 152 | fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match" |
| 152 | fi | 153 | fi |
| 153 | } | 154 | } |
| 154 | 155 | ||
| @@ -245,4 +246,9 @@ setup | |||
| 245 | run_fibrule_tests | 246 | run_fibrule_tests |
| 246 | cleanup | 247 | cleanup |
| 247 | 248 | ||
| 249 | if [ "$TESTS" != "none" ]; then | ||
| 250 | printf "\nTests passed: %3d\n" ${nsuccess} | ||
| 251 | printf "Tests failed: %3d\n" ${nfail} | ||
| 252 | fi | ||
| 253 | |||
| 248 | exit $ret | 254 | exit $ret |
