diff options
51 files changed, 408 insertions, 106 deletions
diff --git a/arch/mips/net/ebpf_jit.c b/arch/mips/net/ebpf_jit.c index 76e9bf88d3b9..0effd3cba9a7 100644 --- a/arch/mips/net/ebpf_jit.c +++ b/arch/mips/net/ebpf_jit.c | |||
| @@ -1819,7 +1819,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_prog *prog) | |||
| 1819 | 1819 | ||
| 1820 | /* Update the icache */ | 1820 | /* Update the icache */ |
| 1821 | flush_icache_range((unsigned long)ctx.target, | 1821 | flush_icache_range((unsigned long)ctx.target, |
| 1822 | (unsigned long)(ctx.target + ctx.idx * sizeof(u32))); | 1822 | (unsigned long)&ctx.target[ctx.idx]); |
| 1823 | 1823 | ||
| 1824 | if (bpf_jit_enable > 1) | 1824 | if (bpf_jit_enable > 1) |
| 1825 | /* Dump JIT code */ | 1825 | /* Dump JIT code */ |
diff --git a/drivers/net/dsa/lantiq_gswip.c b/drivers/net/dsa/lantiq_gswip.c index 693a67f45bef..ddc1f9ca8ebc 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c | |||
| @@ -1162,6 +1162,12 @@ static struct platform_driver gswip_driver = { | |||
| 1162 | 1162 | ||
| 1163 | module_platform_driver(gswip_driver); | 1163 | module_platform_driver(gswip_driver); |
| 1164 | 1164 | ||
| 1165 | MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin"); | ||
| 1166 | MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin"); | ||
| 1167 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin"); | ||
| 1168 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin"); | ||
| 1169 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin"); | ||
| 1170 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin"); | ||
| 1165 | MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); | 1171 | MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); |
| 1166 | MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); | 1172 | MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); |
| 1167 | MODULE_LICENSE("GPL v2"); | 1173 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index 12fd7ce3f1ff..7e3c00bd9532 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
| @@ -896,7 +896,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip, | |||
| 896 | default: | 896 | default: |
| 897 | return U64_MAX; | 897 | return U64_MAX; |
| 898 | } | 898 | } |
| 899 | value = (((u64)high) << 16) | low; | 899 | value = (((u64)high) << 32) | low; |
| 900 | return value; | 900 | return value; |
| 901 | } | 901 | } |
| 902 | 902 | ||
| @@ -3093,7 +3093,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = { | |||
| 3093 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, | 3093 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
| 3094 | .port_link_state = mv88e6352_port_link_state, | 3094 | .port_link_state = mv88e6352_port_link_state, |
| 3095 | .port_get_cmode = mv88e6185_port_get_cmode, | 3095 | .port_get_cmode = mv88e6185_port_get_cmode, |
| 3096 | .stats_snapshot = mv88e6320_g1_stats_snapshot, | 3096 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
| 3097 | .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | 3097 | .stats_set_histogram = mv88e6095_g1_stats_set_histogram, |
| 3098 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, | 3098 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
| 3099 | .stats_get_strings = mv88e6095_stats_get_strings, | 3099 | .stats_get_strings = mv88e6095_stats_get_strings, |
| @@ -4595,6 +4595,14 @@ static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, | |||
| 4595 | return 0; | 4595 | return 0; |
| 4596 | } | 4596 | } |
| 4597 | 4597 | ||
| 4598 | static void mv88e6xxx_ports_cmode_init(struct mv88e6xxx_chip *chip) | ||
| 4599 | { | ||
| 4600 | int i; | ||
| 4601 | |||
| 4602 | for (i = 0; i < mv88e6xxx_num_ports(chip); i++) | ||
| 4603 | chip->ports[i].cmode = MV88E6XXX_PORT_STS_CMODE_INVALID; | ||
| 4604 | } | ||
| 4605 | |||
| 4598 | static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, | 4606 | static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, |
| 4599 | int port) | 4607 | int port) |
| 4600 | { | 4608 | { |
| @@ -4631,6 +4639,8 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev, | |||
| 4631 | if (err) | 4639 | if (err) |
| 4632 | goto free; | 4640 | goto free; |
| 4633 | 4641 | ||
| 4642 | mv88e6xxx_ports_cmode_init(chip); | ||
| 4643 | |||
| 4634 | mutex_lock(&chip->reg_lock); | 4644 | mutex_lock(&chip->reg_lock); |
| 4635 | err = mv88e6xxx_switch_reset(chip); | 4645 | err = mv88e6xxx_switch_reset(chip); |
| 4636 | mutex_unlock(&chip->reg_lock); | 4646 | mutex_unlock(&chip->reg_lock); |
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index ebd26b6a93e6..79ab51e69aee 100644 --- a/drivers/net/dsa/mv88e6xxx/port.c +++ b/drivers/net/dsa/mv88e6xxx/port.c | |||
| @@ -398,6 +398,10 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | |||
| 398 | cmode = 0; | 398 | cmode = 0; |
| 399 | } | 399 | } |
| 400 | 400 | ||
| 401 | /* cmode doesn't change, nothing to do for us */ | ||
| 402 | if (cmode == chip->ports[port].cmode) | ||
| 403 | return 0; | ||
| 404 | |||
| 401 | lane = mv88e6390x_serdes_get_lane(chip, port); | 405 | lane = mv88e6390x_serdes_get_lane(chip, port); |
| 402 | if (lane < 0) | 406 | if (lane < 0) |
| 403 | return lane; | 407 | return lane; |
| @@ -408,7 +412,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | |||
| 408 | return err; | 412 | return err; |
| 409 | } | 413 | } |
| 410 | 414 | ||
| 411 | err = mv88e6390_serdes_power(chip, port, false); | 415 | err = mv88e6390x_serdes_power(chip, port, false); |
| 412 | if (err) | 416 | if (err) |
| 413 | return err; | 417 | return err; |
| 414 | 418 | ||
| @@ -424,7 +428,7 @@ int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port, | |||
| 424 | if (err) | 428 | if (err) |
| 425 | return err; | 429 | return err; |
| 426 | 430 | ||
| 427 | err = mv88e6390_serdes_power(chip, port, true); | 431 | err = mv88e6390x_serdes_power(chip, port, true); |
| 428 | if (err) | 432 | if (err) |
| 429 | return err; | 433 | return err; |
| 430 | 434 | ||
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h index e583641de758..4aadf321edb7 100644 --- a/drivers/net/dsa/mv88e6xxx/port.h +++ b/drivers/net/dsa/mv88e6xxx/port.h | |||
| @@ -52,6 +52,7 @@ | |||
| 52 | #define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005 | 52 | #define MV88E6185_PORT_STS_CMODE_1000BASE_X 0x0005 |
| 53 | #define MV88E6185_PORT_STS_CMODE_PHY 0x0006 | 53 | #define MV88E6185_PORT_STS_CMODE_PHY 0x0006 |
| 54 | #define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007 | 54 | #define MV88E6185_PORT_STS_CMODE_DISABLED 0x0007 |
| 55 | #define MV88E6XXX_PORT_STS_CMODE_INVALID 0xff | ||
| 55 | 56 | ||
| 56 | /* Offset 0x01: MAC (or PCS or Physical) Control Register */ | 57 | /* Offset 0x01: MAC (or PCS or Physical) Control Register */ |
| 57 | #define MV88E6XXX_PORT_MAC_CTL 0x01 | 58 | #define MV88E6XXX_PORT_MAC_CTL 0x01 |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c index b58ca7cb8e9d..fbba300c1d01 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c | |||
| @@ -275,6 +275,9 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self, | |||
| 275 | 275 | ||
| 276 | static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) | 276 | static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) |
| 277 | { | 277 | { |
| 278 | /* Tx TC/Queue number config */ | ||
| 279 | hw_atl_rpb_tps_tx_tc_mode_set(self, 1U); | ||
| 280 | |||
| 278 | hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); | 281 | hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); |
| 279 | hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); | 282 | hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); |
| 280 | hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); | 283 | hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c index 939f77e2e117..8ac7a67b15c1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c | |||
| @@ -1274,6 +1274,15 @@ void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en) | |||
| 1274 | HW_ATL_TPB_TX_BUF_EN_SHIFT, tx_buff_en); | 1274 | HW_ATL_TPB_TX_BUF_EN_SHIFT, tx_buff_en); |
| 1275 | } | 1275 | } |
| 1276 | 1276 | ||
| 1277 | void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw, | ||
| 1278 | u32 tx_traf_class_mode) | ||
| 1279 | { | ||
| 1280 | aq_hw_write_reg_bit(aq_hw, HW_ATL_TPB_TX_TC_MODE_ADDR, | ||
| 1281 | HW_ATL_TPB_TX_TC_MODE_MSK, | ||
| 1282 | HW_ATL_TPB_TX_TC_MODE_SHIFT, | ||
| 1283 | tx_traf_class_mode); | ||
| 1284 | } | ||
| 1285 | |||
| 1277 | void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, | 1286 | void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, |
| 1278 | u32 tx_buff_hi_threshold_per_tc, | 1287 | u32 tx_buff_hi_threshold_per_tc, |
| 1279 | u32 buffer) | 1288 | u32 buffer) |
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h index 03c570d115fe..f529540bfd7e 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h | |||
| @@ -605,6 +605,10 @@ void hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(struct aq_hw_s *aq_hw, | |||
| 605 | 605 | ||
| 606 | /* tpb */ | 606 | /* tpb */ |
| 607 | 607 | ||
| 608 | /* set TX Traffic Class Mode */ | ||
| 609 | void hw_atl_rpb_tps_tx_tc_mode_set(struct aq_hw_s *aq_hw, | ||
| 610 | u32 tx_traf_class_mode); | ||
| 611 | |||
| 608 | /* set tx buffer enable */ | 612 | /* set tx buffer enable */ |
| 609 | void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en); | 613 | void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en); |
| 610 | 614 | ||
diff --git a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h index 8470d92db812..e91ffce005f1 100644 --- a/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h +++ b/drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h | |||
| @@ -1948,6 +1948,19 @@ | |||
| 1948 | /* default value of bitfield tx_buf_en */ | 1948 | /* default value of bitfield tx_buf_en */ |
| 1949 | #define HW_ATL_TPB_TX_BUF_EN_DEFAULT 0x0 | 1949 | #define HW_ATL_TPB_TX_BUF_EN_DEFAULT 0x0 |
| 1950 | 1950 | ||
| 1951 | /* register address for bitfield tx_tc_mode */ | ||
| 1952 | #define HW_ATL_TPB_TX_TC_MODE_ADDR 0x00007900 | ||
| 1953 | /* bitmask for bitfield tx_tc_mode */ | ||
| 1954 | #define HW_ATL_TPB_TX_TC_MODE_MSK 0x00000100 | ||
| 1955 | /* inverted bitmask for bitfield tx_tc_mode */ | ||
| 1956 | #define HW_ATL_TPB_TX_TC_MODE_MSKN 0xFFFFFEFF | ||
| 1957 | /* lower bit position of bitfield tx_tc_mode */ | ||
| 1958 | #define HW_ATL_TPB_TX_TC_MODE_SHIFT 8 | ||
| 1959 | /* width of bitfield tx_tc_mode */ | ||
| 1960 | #define HW_ATL_TPB_TX_TC_MODE_WIDTH 1 | ||
| 1961 | /* default value of bitfield tx_tc_mode */ | ||
| 1962 | #define HW_ATL_TPB_TX_TC_MODE_DEFAULT 0x0 | ||
| 1963 | |||
| 1951 | /* tx tx{b}_hi_thresh[c:0] bitfield definitions | 1964 | /* tx tx{b}_hi_thresh[c:0] bitfield definitions |
| 1952 | * preprocessor definitions for the bitfield "tx{b}_hi_thresh[c:0]". | 1965 | * preprocessor definitions for the bitfield "tx{b}_hi_thresh[c:0]". |
| 1953 | * parameter: buffer {b} | stride size 0x10 | range [0, 7] | 1966 | * parameter: buffer {b} | stride size 0x10 | range [0, 7] |
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index d95730c6e0f2..803f7990d32b 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
| @@ -500,6 +500,12 @@ normal_tx: | |||
| 500 | } | 500 | } |
| 501 | 501 | ||
| 502 | length >>= 9; | 502 | length >>= 9; |
| 503 | if (unlikely(length >= ARRAY_SIZE(bnxt_lhint_arr))) { | ||
| 504 | dev_warn_ratelimited(&pdev->dev, "Dropped oversize %d bytes TX packet.\n", | ||
| 505 | skb->len); | ||
| 506 | i = 0; | ||
| 507 | goto tx_dma_error; | ||
| 508 | } | ||
| 503 | flags |= bnxt_lhint_arr[length]; | 509 | flags |= bnxt_lhint_arr[length]; |
| 504 | txbd->tx_bd_len_flags_type = cpu_to_le32(flags); | 510 | txbd->tx_bd_len_flags_type = cpu_to_le32(flags); |
| 505 | 511 | ||
diff --git a/drivers/net/ethernet/microchip/enc28j60.c b/drivers/net/ethernet/microchip/enc28j60.c index f6ecfa778660..8f72587b5a2c 100644 --- a/drivers/net/ethernet/microchip/enc28j60.c +++ b/drivers/net/ethernet/microchip/enc28j60.c | |||
| @@ -1681,5 +1681,5 @@ MODULE_DESCRIPTION(DRV_NAME " ethernet driver"); | |||
| 1681 | MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>"); | 1681 | MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>"); |
| 1682 | MODULE_LICENSE("GPL"); | 1682 | MODULE_LICENSE("GPL"); |
| 1683 | module_param_named(debug, debug.msg_enable, int, 0); | 1683 | module_param_named(debug, debug.msg_enable, int, 0); |
| 1684 | MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., ffff=all)"); | 1684 | MODULE_PARM_DESC(debug, "Debug verbosity level in amount of bits set (0=none, ..., 31=all)"); |
| 1685 | MODULE_ALIAS("spi:" DRV_NAME); | 1685 | MODULE_ALIAS("spi:" DRV_NAME); |
diff --git a/drivers/net/ethernet/microchip/lan743x_main.c b/drivers/net/ethernet/microchip/lan743x_main.c index 310807ef328b..4d1b4a24907f 100644 --- a/drivers/net/ethernet/microchip/lan743x_main.c +++ b/drivers/net/ethernet/microchip/lan743x_main.c | |||
| @@ -1400,7 +1400,8 @@ static int lan743x_tx_frame_start(struct lan743x_tx *tx, | |||
| 1400 | } | 1400 | } |
| 1401 | 1401 | ||
| 1402 | static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, | 1402 | static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, |
| 1403 | unsigned int frame_length) | 1403 | unsigned int frame_length, |
| 1404 | int nr_frags) | ||
| 1404 | { | 1405 | { |
| 1405 | /* called only from within lan743x_tx_xmit_frame. | 1406 | /* called only from within lan743x_tx_xmit_frame. |
| 1406 | * assuming tx->ring_lock has already been acquired. | 1407 | * assuming tx->ring_lock has already been acquired. |
| @@ -1410,6 +1411,10 @@ static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, | |||
| 1410 | 1411 | ||
| 1411 | /* wrap up previous descriptor */ | 1412 | /* wrap up previous descriptor */ |
| 1412 | tx->frame_data0 |= TX_DESC_DATA0_EXT_; | 1413 | tx->frame_data0 |= TX_DESC_DATA0_EXT_; |
| 1414 | if (nr_frags <= 0) { | ||
| 1415 | tx->frame_data0 |= TX_DESC_DATA0_LS_; | ||
| 1416 | tx->frame_data0 |= TX_DESC_DATA0_IOC_; | ||
| 1417 | } | ||
| 1413 | tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; | 1418 | tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; |
| 1414 | tx_descriptor->data0 = tx->frame_data0; | 1419 | tx_descriptor->data0 = tx->frame_data0; |
| 1415 | 1420 | ||
| @@ -1514,8 +1519,11 @@ static void lan743x_tx_frame_end(struct lan743x_tx *tx, | |||
| 1514 | u32 tx_tail_flags = 0; | 1519 | u32 tx_tail_flags = 0; |
| 1515 | 1520 | ||
| 1516 | /* wrap up previous descriptor */ | 1521 | /* wrap up previous descriptor */ |
| 1517 | tx->frame_data0 |= TX_DESC_DATA0_LS_; | 1522 | if ((tx->frame_data0 & TX_DESC_DATA0_DTYPE_MASK_) == |
| 1518 | tx->frame_data0 |= TX_DESC_DATA0_IOC_; | 1523 | TX_DESC_DATA0_DTYPE_DATA_) { |
| 1524 | tx->frame_data0 |= TX_DESC_DATA0_LS_; | ||
| 1525 | tx->frame_data0 |= TX_DESC_DATA0_IOC_; | ||
| 1526 | } | ||
| 1519 | 1527 | ||
| 1520 | tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; | 1528 | tx_descriptor = &tx->ring_cpu_ptr[tx->frame_tail]; |
| 1521 | buffer_info = &tx->buffer_info[tx->frame_tail]; | 1529 | buffer_info = &tx->buffer_info[tx->frame_tail]; |
| @@ -1600,7 +1608,7 @@ static netdev_tx_t lan743x_tx_xmit_frame(struct lan743x_tx *tx, | |||
| 1600 | } | 1608 | } |
| 1601 | 1609 | ||
| 1602 | if (gso) | 1610 | if (gso) |
| 1603 | lan743x_tx_frame_add_lso(tx, frame_length); | 1611 | lan743x_tx_frame_add_lso(tx, frame_length, nr_frags); |
| 1604 | 1612 | ||
| 1605 | if (nr_frags <= 0) | 1613 | if (nr_frags <= 0) |
| 1606 | goto finish; | 1614 | goto finish; |
diff --git a/drivers/net/geneve.c b/drivers/net/geneve.c index 3377ac66a347..5583d993480d 100644 --- a/drivers/net/geneve.c +++ b/drivers/net/geneve.c | |||
| @@ -692,15 +692,20 @@ out: | |||
| 692 | static int geneve_open(struct net_device *dev) | 692 | static int geneve_open(struct net_device *dev) |
| 693 | { | 693 | { |
| 694 | struct geneve_dev *geneve = netdev_priv(dev); | 694 | struct geneve_dev *geneve = netdev_priv(dev); |
| 695 | bool ipv6 = !!(geneve->info.mode & IP_TUNNEL_INFO_IPV6); | ||
| 696 | bool metadata = geneve->collect_md; | 695 | bool metadata = geneve->collect_md; |
| 696 | bool ipv4, ipv6; | ||
| 697 | int ret = 0; | 697 | int ret = 0; |
| 698 | 698 | ||
| 699 | ipv6 = geneve->info.mode & IP_TUNNEL_INFO_IPV6 || metadata; | ||
| 700 | ipv4 = !ipv6 || metadata; | ||
| 699 | #if IS_ENABLED(CONFIG_IPV6) | 701 | #if IS_ENABLED(CONFIG_IPV6) |
| 700 | if (ipv6 || metadata) | 702 | if (ipv6) { |
| 701 | ret = geneve_sock_add(geneve, true); | 703 | ret = geneve_sock_add(geneve, true); |
| 704 | if (ret < 0 && ret != -EAFNOSUPPORT) | ||
| 705 | ipv4 = false; | ||
| 706 | } | ||
| 702 | #endif | 707 | #endif |
| 703 | if (!ret && (!ipv6 || metadata)) | 708 | if (ipv4) |
| 704 | ret = geneve_sock_add(geneve, false); | 709 | ret = geneve_sock_add(geneve, false); |
| 705 | if (ret < 0) | 710 | if (ret < 0) |
| 706 | geneve_sock_release(geneve); | 711 | geneve_sock_release(geneve); |
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 256adbd044f5..cf4897043e83 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
| @@ -744,6 +744,14 @@ void netvsc_linkstatus_callback(struct net_device *net, | |||
| 744 | schedule_delayed_work(&ndev_ctx->dwork, 0); | 744 | schedule_delayed_work(&ndev_ctx->dwork, 0); |
| 745 | } | 745 | } |
| 746 | 746 | ||
| 747 | static void netvsc_comp_ipcsum(struct sk_buff *skb) | ||
| 748 | { | ||
| 749 | struct iphdr *iph = (struct iphdr *)skb->data; | ||
| 750 | |||
| 751 | iph->check = 0; | ||
| 752 | iph->check = ip_fast_csum(iph, iph->ihl); | ||
| 753 | } | ||
| 754 | |||
| 747 | static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, | 755 | static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, |
| 748 | struct netvsc_channel *nvchan) | 756 | struct netvsc_channel *nvchan) |
| 749 | { | 757 | { |
| @@ -770,9 +778,17 @@ static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, | |||
| 770 | /* skb is already created with CHECKSUM_NONE */ | 778 | /* skb is already created with CHECKSUM_NONE */ |
| 771 | skb_checksum_none_assert(skb); | 779 | skb_checksum_none_assert(skb); |
| 772 | 780 | ||
| 773 | /* | 781 | /* Incoming packets may have IP header checksum verified by the host. |
| 774 | * In Linux, the IP checksum is always checked. | 782 | * They may not have IP header checksum computed after coalescing. |
| 775 | * Do L4 checksum offload if enabled and present. | 783 | * We compute it here if the flags are set, because on Linux, the IP |
| 784 | * checksum is always checked. | ||
| 785 | */ | ||
| 786 | if (csum_info && csum_info->receive.ip_checksum_value_invalid && | ||
| 787 | csum_info->receive.ip_checksum_succeeded && | ||
| 788 | skb->protocol == htons(ETH_P_IP)) | ||
| 789 | netvsc_comp_ipcsum(skb); | ||
| 790 | |||
| 791 | /* Do L4 checksum offload if enabled and present. | ||
| 776 | */ | 792 | */ |
| 777 | if (csum_info && (net->features & NETIF_F_RXCSUM)) { | 793 | if (csum_info && (net->features & NETIF_F_RXCSUM)) { |
| 778 | if (csum_info->receive.tcp_checksum_succeeded || | 794 | if (csum_info->receive.tcp_checksum_succeeded || |
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c index da6a67d47ce9..56fa3606cb9c 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c | |||
| @@ -19,6 +19,7 @@ | |||
| 19 | #include <linux/module.h> | 19 | #include <linux/module.h> |
| 20 | #include <linux/of.h> | 20 | #include <linux/of.h> |
| 21 | #include <linux/phy.h> | 21 | #include <linux/phy.h> |
| 22 | #include <linux/delay.h> | ||
| 22 | 23 | ||
| 23 | #include <dt-bindings/net/ti-dp83867.h> | 24 | #include <dt-bindings/net/ti-dp83867.h> |
| 24 | 25 | ||
| @@ -325,6 +326,8 @@ static int dp83867_phy_reset(struct phy_device *phydev) | |||
| 325 | if (err < 0) | 326 | if (err < 0) |
| 326 | return err; | 327 | return err; |
| 327 | 328 | ||
| 329 | usleep_range(10, 20); | ||
| 330 | |||
| 328 | return dp83867_config_init(phydev); | 331 | return dp83867_config_init(phydev); |
| 329 | } | 332 | } |
| 330 | 333 | ||
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index b1f959935f50..b7df0295a3ca 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
| @@ -344,6 +344,17 @@ static int ksz8041_config_aneg(struct phy_device *phydev) | |||
| 344 | return genphy_config_aneg(phydev); | 344 | return genphy_config_aneg(phydev); |
| 345 | } | 345 | } |
| 346 | 346 | ||
| 347 | static int ksz8061_config_init(struct phy_device *phydev) | ||
| 348 | { | ||
| 349 | int ret; | ||
| 350 | |||
| 351 | ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A); | ||
| 352 | if (ret) | ||
| 353 | return ret; | ||
| 354 | |||
| 355 | return kszphy_config_init(phydev); | ||
| 356 | } | ||
| 357 | |||
| 347 | static int ksz9021_load_values_from_of(struct phy_device *phydev, | 358 | static int ksz9021_load_values_from_of(struct phy_device *phydev, |
| 348 | const struct device_node *of_node, | 359 | const struct device_node *of_node, |
| 349 | u16 reg, | 360 | u16 reg, |
| @@ -1040,7 +1051,7 @@ static struct phy_driver ksphy_driver[] = { | |||
| 1040 | .name = "Micrel KSZ8061", | 1051 | .name = "Micrel KSZ8061", |
| 1041 | .phy_id_mask = MICREL_PHY_ID_MASK, | 1052 | .phy_id_mask = MICREL_PHY_ID_MASK, |
| 1042 | .features = PHY_BASIC_FEATURES, | 1053 | .features = PHY_BASIC_FEATURES, |
| 1043 | .config_init = kszphy_config_init, | 1054 | .config_init = ksz8061_config_init, |
| 1044 | .ack_interrupt = kszphy_ack_interrupt, | 1055 | .ack_interrupt = kszphy_ack_interrupt, |
| 1045 | .config_intr = kszphy_config_intr, | 1056 | .config_intr = kszphy_config_intr, |
| 1046 | .suspend = genphy_suspend, | 1057 | .suspend = genphy_suspend, |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 938803237d7f..85987aac31c4 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
| @@ -320,6 +320,10 @@ static int phylink_get_mac_state(struct phylink *pl, struct phylink_link_state * | |||
| 320 | linkmode_zero(state->lp_advertising); | 320 | linkmode_zero(state->lp_advertising); |
| 321 | state->interface = pl->link_config.interface; | 321 | state->interface = pl->link_config.interface; |
| 322 | state->an_enabled = pl->link_config.an_enabled; | 322 | state->an_enabled = pl->link_config.an_enabled; |
| 323 | state->speed = SPEED_UNKNOWN; | ||
| 324 | state->duplex = DUPLEX_UNKNOWN; | ||
| 325 | state->pause = MLO_PAUSE_NONE; | ||
| 326 | state->an_complete = 0; | ||
| 323 | state->link = 1; | 327 | state->link = 1; |
| 324 | 328 | ||
| 325 | return pl->ops->mac_link_state(ndev, state); | 329 | return pl->ops->mac_link_state(ndev, state); |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index fed298c0cb39..53f4f37b0ffd 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
| @@ -2167,9 +2167,9 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err) | |||
| 2167 | } | 2167 | } |
| 2168 | 2168 | ||
| 2169 | add_wait_queue(&tfile->wq.wait, &wait); | 2169 | add_wait_queue(&tfile->wq.wait, &wait); |
| 2170 | current->state = TASK_INTERRUPTIBLE; | ||
| 2171 | 2170 | ||
| 2172 | while (1) { | 2171 | while (1) { |
| 2172 | set_current_state(TASK_INTERRUPTIBLE); | ||
| 2173 | ptr = ptr_ring_consume(&tfile->tx_ring); | 2173 | ptr = ptr_ring_consume(&tfile->tx_ring); |
| 2174 | if (ptr) | 2174 | if (ptr) |
| 2175 | break; | 2175 | break; |
| @@ -2185,7 +2185,7 @@ static void *tun_ring_recv(struct tun_file *tfile, int noblock, int *err) | |||
| 2185 | schedule(); | 2185 | schedule(); |
| 2186 | } | 2186 | } |
| 2187 | 2187 | ||
| 2188 | current->state = TASK_RUNNING; | 2188 | __set_current_state(TASK_RUNNING); |
| 2189 | remove_wait_queue(&tfile->wq.wait, &wait); | 2189 | remove_wait_queue(&tfile->wq.wait, &wait); |
| 2190 | 2190 | ||
| 2191 | out: | 2191 | out: |
diff --git a/drivers/net/xen-netback/hash.c b/drivers/net/xen-netback/hash.c index 0ccb021f1e78..10d580c3dea3 100644 --- a/drivers/net/xen-netback/hash.c +++ b/drivers/net/xen-netback/hash.c | |||
| @@ -454,6 +454,8 @@ void xenvif_init_hash(struct xenvif *vif) | |||
| 454 | if (xenvif_hash_cache_size == 0) | 454 | if (xenvif_hash_cache_size == 0) |
| 455 | return; | 455 | return; |
| 456 | 456 | ||
| 457 | BUG_ON(vif->hash.cache.count); | ||
| 458 | |||
| 457 | spin_lock_init(&vif->hash.cache.lock); | 459 | spin_lock_init(&vif->hash.cache.lock); |
| 458 | INIT_LIST_HEAD(&vif->hash.cache.list); | 460 | INIT_LIST_HEAD(&vif->hash.cache.list); |
| 459 | } | 461 | } |
diff --git a/drivers/net/xen-netback/interface.c b/drivers/net/xen-netback/interface.c index 182d6770f102..6da12518e693 100644 --- a/drivers/net/xen-netback/interface.c +++ b/drivers/net/xen-netback/interface.c | |||
| @@ -153,6 +153,13 @@ static u16 xenvif_select_queue(struct net_device *dev, struct sk_buff *skb, | |||
| 153 | { | 153 | { |
| 154 | struct xenvif *vif = netdev_priv(dev); | 154 | struct xenvif *vif = netdev_priv(dev); |
| 155 | unsigned int size = vif->hash.size; | 155 | unsigned int size = vif->hash.size; |
| 156 | unsigned int num_queues; | ||
| 157 | |||
| 158 | /* If queues are not set up internally - always return 0 | ||
| 159 | * as the packet going to be dropped anyway */ | ||
| 160 | num_queues = READ_ONCE(vif->num_queues); | ||
| 161 | if (num_queues < 1) | ||
| 162 | return 0; | ||
| 156 | 163 | ||
| 157 | if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) | 164 | if (vif->hash.alg == XEN_NETIF_CTRL_HASH_ALGORITHM_NONE) |
| 158 | return fallback(dev, skb, NULL) % dev->real_num_tx_queues; | 165 | return fallback(dev, skb, NULL) % dev->real_num_tx_queues; |
diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c index 80aae3a32c2a..f09948b009dd 100644 --- a/drivers/net/xen-netback/netback.c +++ b/drivers/net/xen-netback/netback.c | |||
| @@ -1072,11 +1072,6 @@ static int xenvif_handle_frag_list(struct xenvif_queue *queue, struct sk_buff *s | |||
| 1072 | skb_frag_size_set(&frags[i], len); | 1072 | skb_frag_size_set(&frags[i], len); |
| 1073 | } | 1073 | } |
| 1074 | 1074 | ||
| 1075 | /* Copied all the bits from the frag list -- free it. */ | ||
| 1076 | skb_frag_list_init(skb); | ||
| 1077 | xenvif_skb_zerocopy_prepare(queue, nskb); | ||
| 1078 | kfree_skb(nskb); | ||
| 1079 | |||
| 1080 | /* Release all the original (foreign) frags. */ | 1075 | /* Release all the original (foreign) frags. */ |
| 1081 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) | 1076 | for (f = 0; f < skb_shinfo(skb)->nr_frags; f++) |
| 1082 | skb_frag_unref(skb, f); | 1077 | skb_frag_unref(skb, f); |
| @@ -1145,6 +1140,8 @@ static int xenvif_tx_submit(struct xenvif_queue *queue) | |||
| 1145 | xenvif_fill_frags(queue, skb); | 1140 | xenvif_fill_frags(queue, skb); |
| 1146 | 1141 | ||
| 1147 | if (unlikely(skb_has_frag_list(skb))) { | 1142 | if (unlikely(skb_has_frag_list(skb))) { |
| 1143 | struct sk_buff *nskb = skb_shinfo(skb)->frag_list; | ||
| 1144 | xenvif_skb_zerocopy_prepare(queue, nskb); | ||
| 1148 | if (xenvif_handle_frag_list(queue, skb)) { | 1145 | if (xenvif_handle_frag_list(queue, skb)) { |
| 1149 | if (net_ratelimit()) | 1146 | if (net_ratelimit()) |
| 1150 | netdev_err(queue->vif->dev, | 1147 | netdev_err(queue->vif->dev, |
| @@ -1153,6 +1150,9 @@ static int xenvif_tx_submit(struct xenvif_queue *queue) | |||
| 1153 | kfree_skb(skb); | 1150 | kfree_skb(skb); |
| 1154 | continue; | 1151 | continue; |
| 1155 | } | 1152 | } |
| 1153 | /* Copied all the bits from the frag list -- free it. */ | ||
| 1154 | skb_frag_list_init(skb); | ||
| 1155 | kfree_skb(nskb); | ||
| 1156 | } | 1156 | } |
| 1157 | 1157 | ||
| 1158 | skb->dev = queue->vif->dev; | 1158 | skb->dev = queue->vif->dev; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 86dbb3e29139..848b54b7ec91 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
| @@ -3861,7 +3861,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) | |||
| 3861 | if (debug_value == 0) /* no output */ | 3861 | if (debug_value == 0) /* no output */ |
| 3862 | return 0; | 3862 | return 0; |
| 3863 | /* set low N bits */ | 3863 | /* set low N bits */ |
| 3864 | return (1 << debug_value) - 1; | 3864 | return (1U << debug_value) - 1; |
| 3865 | } | 3865 | } |
| 3866 | 3866 | ||
| 3867 | static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) | 3867 | static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) |
diff --git a/include/net/icmp.h b/include/net/icmp.h index 6ac3a5bd0117..e0f709d26dde 100644 --- a/include/net/icmp.h +++ b/include/net/icmp.h | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | 22 | ||
| 23 | #include <net/inet_sock.h> | 23 | #include <net/inet_sock.h> |
| 24 | #include <net/snmp.h> | 24 | #include <net/snmp.h> |
| 25 | #include <net/ip.h> | ||
| 25 | 26 | ||
| 26 | struct icmp_err { | 27 | struct icmp_err { |
| 27 | int errno; | 28 | int errno; |
| @@ -39,7 +40,13 @@ struct net_proto_family; | |||
| 39 | struct sk_buff; | 40 | struct sk_buff; |
| 40 | struct net; | 41 | struct net; |
| 41 | 42 | ||
| 42 | void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); | 43 | void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, |
| 44 | const struct ip_options *opt); | ||
| 45 | static inline void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | ||
| 46 | { | ||
| 47 | __icmp_send(skb_in, type, code, info, &IPCB(skb_in)->opt); | ||
| 48 | } | ||
| 49 | |||
| 43 | int icmp_rcv(struct sk_buff *skb); | 50 | int icmp_rcv(struct sk_buff *skb); |
| 44 | int icmp_err(struct sk_buff *skb, u32 info); | 51 | int icmp_err(struct sk_buff *skb, u32 info); |
| 45 | int icmp_init(void); | 52 | int icmp_init(void); |
diff --git a/include/net/ip.h b/include/net/ip.h index 8866bfce6121..be3cad9c2e4c 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
| @@ -667,6 +667,8 @@ static inline int ip_options_echo(struct net *net, struct ip_options *dopt, | |||
| 667 | } | 667 | } |
| 668 | 668 | ||
| 669 | void ip_options_fragment(struct sk_buff *skb); | 669 | void ip_options_fragment(struct sk_buff *skb); |
| 670 | int __ip_options_compile(struct net *net, struct ip_options *opt, | ||
| 671 | struct sk_buff *skb, __be32 *info); | ||
| 670 | int ip_options_compile(struct net *net, struct ip_options *opt, | 672 | int ip_options_compile(struct net *net, struct ip_options *opt, |
| 671 | struct sk_buff *skb); | 673 | struct sk_buff *skb); |
| 672 | int ip_options_get(struct net *net, struct ip_options_rcu **optp, | 674 | int ip_options_get(struct net *net, struct ip_options_rcu **optp, |
| @@ -716,7 +718,7 @@ extern int sysctl_icmp_msgs_burst; | |||
| 716 | int ip_misc_proc_init(void); | 718 | int ip_misc_proc_init(void); |
| 717 | #endif | 719 | #endif |
| 718 | 720 | ||
| 719 | int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, | 721 | int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, |
| 720 | struct netlink_ext_ack *extack); | 722 | struct netlink_ext_ack *extack); |
| 721 | 723 | ||
| 722 | #endif /* _IP_H */ | 724 | #endif /* _IP_H */ |
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 8577bb7f8be6..84470d1480aa 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
| @@ -559,12 +559,12 @@ static int map_create(union bpf_attr *attr) | |||
| 559 | err = bpf_map_new_fd(map, f_flags); | 559 | err = bpf_map_new_fd(map, f_flags); |
| 560 | if (err < 0) { | 560 | if (err < 0) { |
| 561 | /* failed to allocate fd. | 561 | /* failed to allocate fd. |
| 562 | * bpf_map_put() is needed because the above | 562 | * bpf_map_put_with_uref() is needed because the above |
| 563 | * bpf_map_alloc_id() has published the map | 563 | * bpf_map_alloc_id() has published the map |
| 564 | * to the userspace and the userspace may | 564 | * to the userspace and the userspace may |
| 565 | * have refcnt-ed it through BPF_MAP_GET_FD_BY_ID. | 565 | * have refcnt-ed it through BPF_MAP_GET_FD_BY_ID. |
| 566 | */ | 566 | */ |
| 567 | bpf_map_put(map); | 567 | bpf_map_put_with_uref(map); |
| 568 | return err; | 568 | return err; |
| 569 | } | 569 | } |
| 570 | 570 | ||
| @@ -1986,7 +1986,7 @@ static int bpf_map_get_fd_by_id(const union bpf_attr *attr) | |||
| 1986 | 1986 | ||
| 1987 | fd = bpf_map_new_fd(map, f_flags); | 1987 | fd = bpf_map_new_fd(map, f_flags); |
| 1988 | if (fd < 0) | 1988 | if (fd < 0) |
| 1989 | bpf_map_put(map); | 1989 | bpf_map_put_with_uref(map); |
| 1990 | 1990 | ||
| 1991 | return fd; | 1991 | return fd; |
| 1992 | } | 1992 | } |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 8f295b790297..5fcce2f4209d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
| @@ -6920,7 +6920,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) | |||
| 6920 | u32 off_reg; | 6920 | u32 off_reg; |
| 6921 | 6921 | ||
| 6922 | aux = &env->insn_aux_data[i + delta]; | 6922 | aux = &env->insn_aux_data[i + delta]; |
| 6923 | if (!aux->alu_state) | 6923 | if (!aux->alu_state || |
| 6924 | aux->alu_state == BPF_ALU_NON_POINTER) | ||
| 6924 | continue; | 6925 | continue; |
| 6925 | 6926 | ||
| 6926 | isneg = aux->alu_state & BPF_ALU_NEG_VALUE; | 6927 | isneg = aux->alu_state & BPF_ALU_NEG_VALUE; |
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index a1917025e155..410f19148106 100644 --- a/net/dsa/dsa2.c +++ b/net/dsa/dsa2.c | |||
| @@ -612,8 +612,8 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, | |||
| 612 | { | 612 | { |
| 613 | struct device_node *ports, *port; | 613 | struct device_node *ports, *port; |
| 614 | struct dsa_port *dp; | 614 | struct dsa_port *dp; |
| 615 | int err = 0; | ||
| 615 | u32 reg; | 616 | u32 reg; |
| 616 | int err; | ||
| 617 | 617 | ||
| 618 | ports = of_get_child_by_name(dn, "ports"); | 618 | ports = of_get_child_by_name(dn, "ports"); |
| 619 | if (!ports) { | 619 | if (!ports) { |
| @@ -624,19 +624,23 @@ static int dsa_switch_parse_ports_of(struct dsa_switch *ds, | |||
| 624 | for_each_available_child_of_node(ports, port) { | 624 | for_each_available_child_of_node(ports, port) { |
| 625 | err = of_property_read_u32(port, "reg", ®); | 625 | err = of_property_read_u32(port, "reg", ®); |
| 626 | if (err) | 626 | if (err) |
| 627 | return err; | 627 | goto out_put_node; |
| 628 | 628 | ||
| 629 | if (reg >= ds->num_ports) | 629 | if (reg >= ds->num_ports) { |
| 630 | return -EINVAL; | 630 | err = -EINVAL; |
| 631 | goto out_put_node; | ||
| 632 | } | ||
| 631 | 633 | ||
| 632 | dp = &ds->ports[reg]; | 634 | dp = &ds->ports[reg]; |
| 633 | 635 | ||
| 634 | err = dsa_port_parse_of(dp, port); | 636 | err = dsa_port_parse_of(dp, port); |
| 635 | if (err) | 637 | if (err) |
| 636 | return err; | 638 | goto out_put_node; |
| 637 | } | 639 | } |
| 638 | 640 | ||
| 639 | return 0; | 641 | out_put_node: |
| 642 | of_node_put(ports); | ||
| 643 | return err; | ||
| 640 | } | 644 | } |
| 641 | 645 | ||
| 642 | static int dsa_switch_parse_member_of(struct dsa_switch *ds, | 646 | static int dsa_switch_parse_member_of(struct dsa_switch *ds, |
diff --git a/net/dsa/port.c b/net/dsa/port.c index 2a2a878b5ce3..c2261697ee83 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c | |||
| @@ -292,6 +292,7 @@ static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp) | |||
| 292 | return ERR_PTR(-EPROBE_DEFER); | 292 | return ERR_PTR(-EPROBE_DEFER); |
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | of_node_put(phy_dn); | ||
| 295 | return phydev; | 296 | return phydev; |
| 296 | } | 297 | } |
| 297 | 298 | ||
diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index 777fa3b7fb13..f0165c5f376b 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c | |||
| @@ -667,7 +667,8 @@ static int cipso_v4_map_lvl_valid(const struct cipso_v4_doi *doi_def, u8 level) | |||
| 667 | case CIPSO_V4_MAP_PASS: | 667 | case CIPSO_V4_MAP_PASS: |
| 668 | return 0; | 668 | return 0; |
| 669 | case CIPSO_V4_MAP_TRANS: | 669 | case CIPSO_V4_MAP_TRANS: |
| 670 | if (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL) | 670 | if ((level < doi_def->map.std->lvl.cipso_size) && |
| 671 | (doi_def->map.std->lvl.cipso[level] < CIPSO_V4_INV_LVL)) | ||
| 671 | return 0; | 672 | return 0; |
| 672 | break; | 673 | break; |
| 673 | } | 674 | } |
| @@ -1735,13 +1736,26 @@ validate_return: | |||
| 1735 | */ | 1736 | */ |
| 1736 | void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) | 1737 | void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) |
| 1737 | { | 1738 | { |
| 1739 | unsigned char optbuf[sizeof(struct ip_options) + 40]; | ||
| 1740 | struct ip_options *opt = (struct ip_options *)optbuf; | ||
| 1741 | |||
| 1738 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) | 1742 | if (ip_hdr(skb)->protocol == IPPROTO_ICMP || error != -EACCES) |
| 1739 | return; | 1743 | return; |
| 1740 | 1744 | ||
| 1745 | /* | ||
| 1746 | * We might be called above the IP layer, | ||
| 1747 | * so we can not use icmp_send and IPCB here. | ||
| 1748 | */ | ||
| 1749 | |||
| 1750 | memset(opt, 0, sizeof(struct ip_options)); | ||
| 1751 | opt->optlen = ip_hdr(skb)->ihl*4 - sizeof(struct iphdr); | ||
| 1752 | if (__ip_options_compile(dev_net(skb->dev), opt, skb, NULL)) | ||
| 1753 | return; | ||
| 1754 | |||
| 1741 | if (gateway) | 1755 | if (gateway) |
| 1742 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0); | 1756 | __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_NET_ANO, 0, opt); |
| 1743 | else | 1757 | else |
| 1744 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0); | 1758 | __icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_ANO, 0, opt); |
| 1745 | } | 1759 | } |
| 1746 | 1760 | ||
| 1747 | /** | 1761 | /** |
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index fe4f6a624238..ed14ec245584 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c | |||
| @@ -710,6 +710,10 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb, | |||
| 710 | case RTA_GATEWAY: | 710 | case RTA_GATEWAY: |
| 711 | cfg->fc_gw = nla_get_be32(attr); | 711 | cfg->fc_gw = nla_get_be32(attr); |
| 712 | break; | 712 | break; |
| 713 | case RTA_VIA: | ||
| 714 | NL_SET_ERR_MSG(extack, "IPv4 does not support RTA_VIA attribute"); | ||
| 715 | err = -EINVAL; | ||
| 716 | goto errout; | ||
| 713 | case RTA_PRIORITY: | 717 | case RTA_PRIORITY: |
| 714 | cfg->fc_priority = nla_get_u32(attr); | 718 | cfg->fc_priority = nla_get_u32(attr); |
| 715 | break; | 719 | break; |
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 065997f414e6..3f24414150e2 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
| @@ -570,7 +570,8 @@ relookup_failed: | |||
| 570 | * MUST reply to only the first fragment. | 570 | * MUST reply to only the first fragment. |
| 571 | */ | 571 | */ |
| 572 | 572 | ||
| 573 | void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | 573 | void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info, |
| 574 | const struct ip_options *opt) | ||
| 574 | { | 575 | { |
| 575 | struct iphdr *iph; | 576 | struct iphdr *iph; |
| 576 | int room; | 577 | int room; |
| @@ -691,7 +692,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | |||
| 691 | iph->tos; | 692 | iph->tos; |
| 692 | mark = IP4_REPLY_MARK(net, skb_in->mark); | 693 | mark = IP4_REPLY_MARK(net, skb_in->mark); |
| 693 | 694 | ||
| 694 | if (ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in)) | 695 | if (__ip_options_echo(net, &icmp_param.replyopts.opt.opt, skb_in, opt)) |
| 695 | goto out_unlock; | 696 | goto out_unlock; |
| 696 | 697 | ||
| 697 | 698 | ||
| @@ -742,7 +743,7 @@ out_bh_enable: | |||
| 742 | local_bh_enable(); | 743 | local_bh_enable(); |
| 743 | out:; | 744 | out:; |
| 744 | } | 745 | } |
| 745 | EXPORT_SYMBOL(icmp_send); | 746 | EXPORT_SYMBOL(__icmp_send); |
| 746 | 747 | ||
| 747 | 748 | ||
| 748 | static void icmp_socket_deliver(struct sk_buff *skb, u32 info) | 749 | static void icmp_socket_deliver(struct sk_buff *skb, u32 info) |
diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index 51d8efba6de2..1f4737b77067 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c | |||
| @@ -307,11 +307,10 @@ drop: | |||
| 307 | } | 307 | } |
| 308 | 308 | ||
| 309 | static int ip_rcv_finish_core(struct net *net, struct sock *sk, | 309 | static int ip_rcv_finish_core(struct net *net, struct sock *sk, |
| 310 | struct sk_buff *skb) | 310 | struct sk_buff *skb, struct net_device *dev) |
| 311 | { | 311 | { |
| 312 | const struct iphdr *iph = ip_hdr(skb); | 312 | const struct iphdr *iph = ip_hdr(skb); |
| 313 | int (*edemux)(struct sk_buff *skb); | 313 | int (*edemux)(struct sk_buff *skb); |
| 314 | struct net_device *dev = skb->dev; | ||
| 315 | struct rtable *rt; | 314 | struct rtable *rt; |
| 316 | int err; | 315 | int err; |
| 317 | 316 | ||
| @@ -400,6 +399,7 @@ drop_error: | |||
| 400 | 399 | ||
| 401 | static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | 400 | static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
| 402 | { | 401 | { |
| 402 | struct net_device *dev = skb->dev; | ||
| 403 | int ret; | 403 | int ret; |
| 404 | 404 | ||
| 405 | /* if ingress device is enslaved to an L3 master device pass the | 405 | /* if ingress device is enslaved to an L3 master device pass the |
| @@ -409,7 +409,7 @@ static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
| 409 | if (!skb) | 409 | if (!skb) |
| 410 | return NET_RX_SUCCESS; | 410 | return NET_RX_SUCCESS; |
| 411 | 411 | ||
| 412 | ret = ip_rcv_finish_core(net, sk, skb); | 412 | ret = ip_rcv_finish_core(net, sk, skb, dev); |
| 413 | if (ret != NET_RX_DROP) | 413 | if (ret != NET_RX_DROP) |
| 414 | ret = dst_input(skb); | 414 | ret = dst_input(skb); |
| 415 | return ret; | 415 | return ret; |
| @@ -545,6 +545,7 @@ static void ip_list_rcv_finish(struct net *net, struct sock *sk, | |||
| 545 | 545 | ||
| 546 | INIT_LIST_HEAD(&sublist); | 546 | INIT_LIST_HEAD(&sublist); |
| 547 | list_for_each_entry_safe(skb, next, head, list) { | 547 | list_for_each_entry_safe(skb, next, head, list) { |
| 548 | struct net_device *dev = skb->dev; | ||
| 548 | struct dst_entry *dst; | 549 | struct dst_entry *dst; |
| 549 | 550 | ||
| 550 | skb_list_del_init(skb); | 551 | skb_list_del_init(skb); |
| @@ -554,7 +555,7 @@ static void ip_list_rcv_finish(struct net *net, struct sock *sk, | |||
| 554 | skb = l3mdev_ip_rcv(skb); | 555 | skb = l3mdev_ip_rcv(skb); |
| 555 | if (!skb) | 556 | if (!skb) |
| 556 | continue; | 557 | continue; |
| 557 | if (ip_rcv_finish_core(net, sk, skb) == NET_RX_DROP) | 558 | if (ip_rcv_finish_core(net, sk, skb, dev) == NET_RX_DROP) |
| 558 | continue; | 559 | continue; |
| 559 | 560 | ||
| 560 | dst = skb_dst(skb); | 561 | dst = skb_dst(skb); |
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c index ed194d46c00e..32a35043c9f5 100644 --- a/net/ipv4/ip_options.c +++ b/net/ipv4/ip_options.c | |||
| @@ -251,8 +251,9 @@ static void spec_dst_fill(__be32 *spec_dst, struct sk_buff *skb) | |||
| 251 | * If opt == NULL, then skb->data should point to IP header. | 251 | * If opt == NULL, then skb->data should point to IP header. |
| 252 | */ | 252 | */ |
| 253 | 253 | ||
| 254 | int ip_options_compile(struct net *net, | 254 | int __ip_options_compile(struct net *net, |
| 255 | struct ip_options *opt, struct sk_buff *skb) | 255 | struct ip_options *opt, struct sk_buff *skb, |
| 256 | __be32 *info) | ||
| 256 | { | 257 | { |
| 257 | __be32 spec_dst = htonl(INADDR_ANY); | 258 | __be32 spec_dst = htonl(INADDR_ANY); |
| 258 | unsigned char *pp_ptr = NULL; | 259 | unsigned char *pp_ptr = NULL; |
| @@ -468,11 +469,22 @@ eol: | |||
| 468 | return 0; | 469 | return 0; |
| 469 | 470 | ||
| 470 | error: | 471 | error: |
| 471 | if (skb) { | 472 | if (info) |
| 472 | icmp_send(skb, ICMP_PARAMETERPROB, 0, htonl((pp_ptr-iph)<<24)); | 473 | *info = htonl((pp_ptr-iph)<<24); |
| 473 | } | ||
| 474 | return -EINVAL; | 474 | return -EINVAL; |
| 475 | } | 475 | } |
| 476 | |||
| 477 | int ip_options_compile(struct net *net, | ||
| 478 | struct ip_options *opt, struct sk_buff *skb) | ||
| 479 | { | ||
| 480 | int ret; | ||
| 481 | __be32 info; | ||
| 482 | |||
| 483 | ret = __ip_options_compile(net, opt, skb, &info); | ||
| 484 | if (ret != 0 && skb) | ||
| 485 | icmp_send(skb, ICMP_PARAMETERPROB, 0, info); | ||
| 486 | return ret; | ||
| 487 | } | ||
| 476 | EXPORT_SYMBOL(ip_options_compile); | 488 | EXPORT_SYMBOL(ip_options_compile); |
| 477 | 489 | ||
| 478 | /* | 490 | /* |
diff --git a/net/ipv4/netlink.c b/net/ipv4/netlink.c index f86bb4f06609..d8e3a1fb8e82 100644 --- a/net/ipv4/netlink.c +++ b/net/ipv4/netlink.c | |||
| @@ -3,9 +3,10 @@ | |||
| 3 | #include <linux/types.h> | 3 | #include <linux/types.h> |
| 4 | #include <net/net_namespace.h> | 4 | #include <net/net_namespace.h> |
| 5 | #include <net/netlink.h> | 5 | #include <net/netlink.h> |
| 6 | #include <linux/in6.h> | ||
| 6 | #include <net/ip.h> | 7 | #include <net/ip.h> |
| 7 | 8 | ||
| 8 | int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, | 9 | int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, u8 family, |
| 9 | struct netlink_ext_ack *extack) | 10 | struct netlink_ext_ack *extack) |
| 10 | { | 11 | { |
| 11 | *ip_proto = nla_get_u8(attr); | 12 | *ip_proto = nla_get_u8(attr); |
| @@ -13,11 +14,19 @@ int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, | |||
| 13 | switch (*ip_proto) { | 14 | switch (*ip_proto) { |
| 14 | case IPPROTO_TCP: | 15 | case IPPROTO_TCP: |
| 15 | case IPPROTO_UDP: | 16 | case IPPROTO_UDP: |
| 17 | return 0; | ||
| 16 | case IPPROTO_ICMP: | 18 | case IPPROTO_ICMP: |
| 19 | if (family != AF_INET) | ||
| 20 | break; | ||
| 21 | return 0; | ||
| 22 | #if IS_ENABLED(CONFIG_IPV6) | ||
| 23 | case IPPROTO_ICMPV6: | ||
| 24 | if (family != AF_INET6) | ||
| 25 | break; | ||
| 17 | return 0; | 26 | return 0; |
| 18 | default: | 27 | #endif |
| 19 | NL_SET_ERR_MSG(extack, "Unsupported ip proto"); | ||
| 20 | return -EOPNOTSUPP; | ||
| 21 | } | 28 | } |
| 29 | NL_SET_ERR_MSG(extack, "Unsupported ip proto"); | ||
| 30 | return -EOPNOTSUPP; | ||
| 22 | } | 31 | } |
| 23 | EXPORT_SYMBOL_GPL(rtm_getroute_parse_ip_proto); | 32 | EXPORT_SYMBOL_GPL(rtm_getroute_parse_ip_proto); |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 5163b64f8fb3..7bb9128c8363 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
| @@ -2803,7 +2803,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
| 2803 | 2803 | ||
| 2804 | if (tb[RTA_IP_PROTO]) { | 2804 | if (tb[RTA_IP_PROTO]) { |
| 2805 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], | 2805 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], |
| 2806 | &ip_proto, extack); | 2806 | &ip_proto, AF_INET, extack); |
| 2807 | if (err) | 2807 | if (err) |
| 2808 | return err; | 2808 | return err; |
| 2809 | } | 2809 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index ce15dc4ccbfa..8dad1d690b78 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
| @@ -4182,6 +4182,10 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
| 4182 | cfg->fc_gateway = nla_get_in6_addr(tb[RTA_GATEWAY]); | 4182 | cfg->fc_gateway = nla_get_in6_addr(tb[RTA_GATEWAY]); |
| 4183 | cfg->fc_flags |= RTF_GATEWAY; | 4183 | cfg->fc_flags |= RTF_GATEWAY; |
| 4184 | } | 4184 | } |
| 4185 | if (tb[RTA_VIA]) { | ||
| 4186 | NL_SET_ERR_MSG(extack, "IPv6 does not support RTA_VIA attribute"); | ||
| 4187 | goto errout; | ||
| 4188 | } | ||
| 4185 | 4189 | ||
| 4186 | if (tb[RTA_DST]) { | 4190 | if (tb[RTA_DST]) { |
| 4187 | int plen = (rtm->rtm_dst_len + 7) >> 3; | 4191 | int plen = (rtm->rtm_dst_len + 7) >> 3; |
| @@ -4889,7 +4893,8 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
| 4889 | 4893 | ||
| 4890 | if (tb[RTA_IP_PROTO]) { | 4894 | if (tb[RTA_IP_PROTO]) { |
| 4891 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], | 4895 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], |
| 4892 | &fl6.flowi6_proto, extack); | 4896 | &fl6.flowi6_proto, AF_INET6, |
| 4897 | extack); | ||
| 4893 | if (err) | 4898 | if (err) |
| 4894 | goto errout; | 4899 | goto errout; |
| 4895 | } | 4900 | } |
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c index e8a1dabef803..09e440e8dfae 100644 --- a/net/ipv6/sit.c +++ b/net/ipv6/sit.c | |||
| @@ -1873,6 +1873,7 @@ static int __net_init sit_init_net(struct net *net) | |||
| 1873 | 1873 | ||
| 1874 | err_reg_dev: | 1874 | err_reg_dev: |
| 1875 | ipip6_dev_free(sitn->fb_tunnel_dev); | 1875 | ipip6_dev_free(sitn->fb_tunnel_dev); |
| 1876 | free_netdev(sitn->fb_tunnel_dev); | ||
| 1876 | err_alloc_dev: | 1877 | err_alloc_dev: |
| 1877 | return err; | 1878 | return err; |
| 1878 | } | 1879 | } |
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 7d55d4c04088..fa763e2e50ec 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
| @@ -1838,6 +1838,9 @@ static int rtm_to_route_config(struct sk_buff *skb, | |||
| 1838 | goto errout; | 1838 | goto errout; |
| 1839 | break; | 1839 | break; |
| 1840 | } | 1840 | } |
| 1841 | case RTA_GATEWAY: | ||
| 1842 | NL_SET_ERR_MSG(extack, "MPLS does not support RTA_GATEWAY attribute"); | ||
| 1843 | goto errout; | ||
| 1841 | case RTA_VIA: | 1844 | case RTA_VIA: |
| 1842 | { | 1845 | { |
| 1843 | if (nla_get_via(nla, &cfg->rc_via_alen, | 1846 | if (nla_get_via(nla, &cfg->rc_via_alen, |
diff --git a/net/netlabel/netlabel_kapi.c b/net/netlabel/netlabel_kapi.c index ea7c67050792..ee3e5b6471a6 100644 --- a/net/netlabel/netlabel_kapi.c +++ b/net/netlabel/netlabel_kapi.c | |||
| @@ -903,7 +903,8 @@ int netlbl_bitmap_walk(const unsigned char *bitmap, u32 bitmap_len, | |||
| 903 | (state == 0 && (byte & bitmask) == 0)) | 903 | (state == 0 && (byte & bitmask) == 0)) |
| 904 | return bit_spot; | 904 | return bit_spot; |
| 905 | 905 | ||
| 906 | bit_spot++; | 906 | if (++bit_spot >= bitmap_len) |
| 907 | return -1; | ||
| 907 | bitmask >>= 1; | 908 | bitmask >>= 1; |
| 908 | if (bitmask == 0) { | 909 | if (bitmask == 0) { |
| 909 | byte = bitmap[++byte_offset]; | 910 | byte = bitmap[++byte_offset]; |
diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c index 6a196e438b6c..d1fc019e932e 100644 --- a/net/nfc/llcp_commands.c +++ b/net/nfc/llcp_commands.c | |||
| @@ -419,6 +419,10 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
| 419 | sock->service_name, | 419 | sock->service_name, |
| 420 | sock->service_name_len, | 420 | sock->service_name_len, |
| 421 | &service_name_tlv_length); | 421 | &service_name_tlv_length); |
| 422 | if (!service_name_tlv) { | ||
| 423 | err = -ENOMEM; | ||
| 424 | goto error_tlv; | ||
| 425 | } | ||
| 422 | size += service_name_tlv_length; | 426 | size += service_name_tlv_length; |
| 423 | } | 427 | } |
| 424 | 428 | ||
| @@ -429,9 +433,17 @@ int nfc_llcp_send_connect(struct nfc_llcp_sock *sock) | |||
| 429 | 433 | ||
| 430 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | 434 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, |
| 431 | &miux_tlv_length); | 435 | &miux_tlv_length); |
| 436 | if (!miux_tlv) { | ||
| 437 | err = -ENOMEM; | ||
| 438 | goto error_tlv; | ||
| 439 | } | ||
| 432 | size += miux_tlv_length; | 440 | size += miux_tlv_length; |
| 433 | 441 | ||
| 434 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | 442 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); |
| 443 | if (!rw_tlv) { | ||
| 444 | err = -ENOMEM; | ||
| 445 | goto error_tlv; | ||
| 446 | } | ||
| 435 | size += rw_tlv_length; | 447 | size += rw_tlv_length; |
| 436 | 448 | ||
| 437 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); | 449 | pr_debug("SKB size %d SN length %zu\n", size, sock->service_name_len); |
| @@ -484,9 +496,17 @@ int nfc_llcp_send_cc(struct nfc_llcp_sock *sock) | |||
| 484 | 496 | ||
| 485 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, | 497 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&miux, 0, |
| 486 | &miux_tlv_length); | 498 | &miux_tlv_length); |
| 499 | if (!miux_tlv) { | ||
| 500 | err = -ENOMEM; | ||
| 501 | goto error_tlv; | ||
| 502 | } | ||
| 487 | size += miux_tlv_length; | 503 | size += miux_tlv_length; |
| 488 | 504 | ||
| 489 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); | 505 | rw_tlv = nfc_llcp_build_tlv(LLCP_TLV_RW, &rw, 0, &rw_tlv_length); |
| 506 | if (!rw_tlv) { | ||
| 507 | err = -ENOMEM; | ||
| 508 | goto error_tlv; | ||
| 509 | } | ||
| 490 | size += rw_tlv_length; | 510 | size += rw_tlv_length; |
| 491 | 511 | ||
| 492 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); | 512 | skb = llcp_allocate_pdu(sock, LLCP_PDU_CC, size); |
diff --git a/net/nfc/llcp_core.c b/net/nfc/llcp_core.c index ef4026a23e80..4fa015208aab 100644 --- a/net/nfc/llcp_core.c +++ b/net/nfc/llcp_core.c | |||
| @@ -532,10 +532,10 @@ static u8 nfc_llcp_reserve_sdp_ssap(struct nfc_llcp_local *local) | |||
| 532 | 532 | ||
| 533 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | 533 | static int nfc_llcp_build_gb(struct nfc_llcp_local *local) |
| 534 | { | 534 | { |
| 535 | u8 *gb_cur, *version_tlv, version, version_length; | 535 | u8 *gb_cur, version, version_length; |
| 536 | u8 *lto_tlv, lto_length; | 536 | u8 lto_length, wks_length, miux_length; |
| 537 | u8 *wks_tlv, wks_length; | 537 | u8 *version_tlv = NULL, *lto_tlv = NULL, |
| 538 | u8 *miux_tlv, miux_length; | 538 | *wks_tlv = NULL, *miux_tlv = NULL; |
| 539 | __be16 wks = cpu_to_be16(local->local_wks); | 539 | __be16 wks = cpu_to_be16(local->local_wks); |
| 540 | u8 gb_len = 0; | 540 | u8 gb_len = 0; |
| 541 | int ret = 0; | 541 | int ret = 0; |
| @@ -543,17 +543,33 @@ static int nfc_llcp_build_gb(struct nfc_llcp_local *local) | |||
| 543 | version = LLCP_VERSION_11; | 543 | version = LLCP_VERSION_11; |
| 544 | version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, | 544 | version_tlv = nfc_llcp_build_tlv(LLCP_TLV_VERSION, &version, |
| 545 | 1, &version_length); | 545 | 1, &version_length); |
| 546 | if (!version_tlv) { | ||
| 547 | ret = -ENOMEM; | ||
| 548 | goto out; | ||
| 549 | } | ||
| 546 | gb_len += version_length; | 550 | gb_len += version_length; |
| 547 | 551 | ||
| 548 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, <o_length); | 552 | lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, <o_length); |
| 553 | if (!lto_tlv) { | ||
| 554 | ret = -ENOMEM; | ||
| 555 | goto out; | ||
| 556 | } | ||
| 549 | gb_len += lto_length; | 557 | gb_len += lto_length; |
| 550 | 558 | ||
| 551 | pr_debug("Local wks 0x%lx\n", local->local_wks); | 559 | pr_debug("Local wks 0x%lx\n", local->local_wks); |
| 552 | wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&wks, 2, &wks_length); | 560 | wks_tlv = nfc_llcp_build_tlv(LLCP_TLV_WKS, (u8 *)&wks, 2, &wks_length); |
| 561 | if (!wks_tlv) { | ||
| 562 | ret = -ENOMEM; | ||
| 563 | goto out; | ||
| 564 | } | ||
| 553 | gb_len += wks_length; | 565 | gb_len += wks_length; |
| 554 | 566 | ||
| 555 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, | 567 | miux_tlv = nfc_llcp_build_tlv(LLCP_TLV_MIUX, (u8 *)&local->miux, 0, |
| 556 | &miux_length); | 568 | &miux_length); |
| 569 | if (!miux_tlv) { | ||
| 570 | ret = -ENOMEM; | ||
| 571 | goto out; | ||
| 572 | } | ||
| 557 | gb_len += miux_length; | 573 | gb_len += miux_length; |
| 558 | 574 | ||
| 559 | gb_len += ARRAY_SIZE(llcp_magic); | 575 | gb_len += ARRAY_SIZE(llcp_magic); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 8af6c11d2482..faa1addf89b3 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
| @@ -199,8 +199,7 @@ err3: | |||
| 199 | err2: | 199 | err2: |
| 200 | kfree(tname); | 200 | kfree(tname); |
| 201 | err1: | 201 | err1: |
| 202 | if (ret == ACT_P_CREATED) | 202 | tcf_idr_release(*a, bind); |
| 203 | tcf_idr_release(*a, bind); | ||
| 204 | return err; | 203 | return err; |
| 205 | } | 204 | } |
| 206 | 205 | ||
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c index 64dba3708fce..cfceed28c333 100644 --- a/net/sched/act_skbedit.c +++ b/net/sched/act_skbedit.c | |||
| @@ -189,8 +189,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla, | |||
| 189 | 189 | ||
| 190 | params_new = kzalloc(sizeof(*params_new), GFP_KERNEL); | 190 | params_new = kzalloc(sizeof(*params_new), GFP_KERNEL); |
| 191 | if (unlikely(!params_new)) { | 191 | if (unlikely(!params_new)) { |
| 192 | if (ret == ACT_P_CREATED) | 192 | tcf_idr_release(*a, bind); |
| 193 | tcf_idr_release(*a, bind); | ||
| 194 | return -ENOMEM; | 193 | return -ENOMEM; |
| 195 | } | 194 | } |
| 196 | 195 | ||
diff --git a/net/sched/act_tunnel_key.c b/net/sched/act_tunnel_key.c index 8b43fe0130f7..3f943de9a2c9 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
| @@ -377,7 +377,8 @@ static int tunnel_key_init(struct net *net, struct nlattr *nla, | |||
| 377 | return ret; | 377 | return ret; |
| 378 | 378 | ||
| 379 | release_tun_meta: | 379 | release_tun_meta: |
| 380 | dst_release(&metadata->dst); | 380 | if (metadata) |
| 381 | dst_release(&metadata->dst); | ||
| 381 | 382 | ||
| 382 | err_out: | 383 | err_out: |
| 383 | if (exists) | 384 | if (exists) |
diff --git a/net/sched/sch_netem.c b/net/sched/sch_netem.c index 75046ec72144..cc9d8133afcd 100644 --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c | |||
| @@ -447,6 +447,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 447 | int nb = 0; | 447 | int nb = 0; |
| 448 | int count = 1; | 448 | int count = 1; |
| 449 | int rc = NET_XMIT_SUCCESS; | 449 | int rc = NET_XMIT_SUCCESS; |
| 450 | int rc_drop = NET_XMIT_DROP; | ||
| 450 | 451 | ||
| 451 | /* Do not fool qdisc_drop_all() */ | 452 | /* Do not fool qdisc_drop_all() */ |
| 452 | skb->prev = NULL; | 453 | skb->prev = NULL; |
| @@ -486,6 +487,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 486 | q->duplicate = 0; | 487 | q->duplicate = 0; |
| 487 | rootq->enqueue(skb2, rootq, to_free); | 488 | rootq->enqueue(skb2, rootq, to_free); |
| 488 | q->duplicate = dupsave; | 489 | q->duplicate = dupsave; |
| 490 | rc_drop = NET_XMIT_SUCCESS; | ||
| 489 | } | 491 | } |
| 490 | 492 | ||
| 491 | /* | 493 | /* |
| @@ -498,7 +500,7 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 498 | if (skb_is_gso(skb)) { | 500 | if (skb_is_gso(skb)) { |
| 499 | segs = netem_segment(skb, sch, to_free); | 501 | segs = netem_segment(skb, sch, to_free); |
| 500 | if (!segs) | 502 | if (!segs) |
| 501 | return NET_XMIT_DROP; | 503 | return rc_drop; |
| 502 | } else { | 504 | } else { |
| 503 | segs = skb; | 505 | segs = skb; |
| 504 | } | 506 | } |
| @@ -521,8 +523,10 @@ static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch, | |||
| 521 | 1<<(prandom_u32() % 8); | 523 | 1<<(prandom_u32() % 8); |
| 522 | } | 524 | } |
| 523 | 525 | ||
| 524 | if (unlikely(sch->q.qlen >= sch->limit)) | 526 | if (unlikely(sch->q.qlen >= sch->limit)) { |
| 525 | return qdisc_drop_all(skb, sch, to_free); | 527 | qdisc_drop_all(skb, sch, to_free); |
| 528 | return rc_drop; | ||
| 529 | } | ||
| 526 | 530 | ||
| 527 | qdisc_qstats_backlog_inc(sch, skb); | 531 | qdisc_qstats_backlog_inc(sch, skb); |
| 528 | 532 | ||
diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 64bef313d436..5cb7c1ff97e9 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c | |||
| @@ -192,7 +192,7 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, | |||
| 192 | if (unlikely(!max_data)) { | 192 | if (unlikely(!max_data)) { |
| 193 | max_data = sctp_min_frag_point(sctp_sk(asoc->base.sk), | 193 | max_data = sctp_min_frag_point(sctp_sk(asoc->base.sk), |
| 194 | sctp_datachk_len(&asoc->stream)); | 194 | sctp_datachk_len(&asoc->stream)); |
| 195 | pr_warn_ratelimited("%s: asoc:%p frag_point is zero, forcing max_data to default minimum (%Zu)", | 195 | pr_warn_ratelimited("%s: asoc:%p frag_point is zero, forcing max_data to default minimum (%zu)", |
| 196 | __func__, asoc, max_data); | 196 | __func__, asoc, max_data); |
| 197 | } | 197 | } |
| 198 | 198 | ||
diff --git a/net/socket.c b/net/socket.c index d80d87a395ea..320f51b22b19 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -577,6 +577,7 @@ static void __sock_release(struct socket *sock, struct inode *inode) | |||
| 577 | if (inode) | 577 | if (inode) |
| 578 | inode_lock(inode); | 578 | inode_lock(inode); |
| 579 | sock->ops->release(sock); | 579 | sock->ops->release(sock); |
| 580 | sock->sk = NULL; | ||
| 580 | if (inode) | 581 | if (inode) |
| 581 | inode_unlock(inode); | 582 | inode_unlock(inode); |
| 582 | sock->ops = NULL; | 583 | sock->ops = NULL; |
diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 684f2125fc6b..70343ac448b1 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c | |||
| @@ -379,11 +379,13 @@ static int tipc_sk_sock_err(struct socket *sock, long *timeout) | |||
| 379 | 379 | ||
| 380 | #define tipc_wait_for_cond(sock_, timeo_, condition_) \ | 380 | #define tipc_wait_for_cond(sock_, timeo_, condition_) \ |
| 381 | ({ \ | 381 | ({ \ |
| 382 | DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ | ||
| 382 | struct sock *sk_; \ | 383 | struct sock *sk_; \ |
| 383 | int rc_; \ | 384 | int rc_; \ |
| 384 | \ | 385 | \ |
| 385 | while ((rc_ = !(condition_))) { \ | 386 | while ((rc_ = !(condition_))) { \ |
| 386 | DEFINE_WAIT_FUNC(wait_, woken_wake_function); \ | 387 | /* coupled with smp_wmb() in tipc_sk_proto_rcv() */ \ |
| 388 | smp_rmb(); \ | ||
| 387 | sk_ = (sock_)->sk; \ | 389 | sk_ = (sock_)->sk; \ |
| 388 | rc_ = tipc_sk_sock_err((sock_), timeo_); \ | 390 | rc_ = tipc_sk_sock_err((sock_), timeo_); \ |
| 389 | if (rc_) \ | 391 | if (rc_) \ |
| @@ -1983,6 +1985,8 @@ static void tipc_sk_proto_rcv(struct sock *sk, | |||
| 1983 | return; | 1985 | return; |
| 1984 | case SOCK_WAKEUP: | 1986 | case SOCK_WAKEUP: |
| 1985 | tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0); | 1987 | tipc_dest_del(&tsk->cong_links, msg_orignode(hdr), 0); |
| 1988 | /* coupled with smp_rmb() in tipc_wait_for_cond() */ | ||
| 1989 | smp_wmb(); | ||
| 1986 | tsk->cong_link_cnt--; | 1990 | tsk->cong_link_cnt--; |
| 1987 | wakeup = true; | 1991 | wakeup = true; |
| 1988 | break; | 1992 | break; |
diff --git a/tools/testing/selftests/net/pmtu.sh b/tools/testing/selftests/net/pmtu.sh index e2c94e47707c..912b2dc50be3 100755 --- a/tools/testing/selftests/net/pmtu.sh +++ b/tools/testing/selftests/net/pmtu.sh | |||
| @@ -103,6 +103,15 @@ | |||
| 103 | # and check that configured MTU is used on link creation and changes, and | 103 | # and check that configured MTU is used on link creation and changes, and |
| 104 | # that MTU is properly calculated instead when MTU is not configured from | 104 | # that MTU is properly calculated instead when MTU is not configured from |
| 105 | # userspace | 105 | # userspace |
| 106 | # | ||
| 107 | # - cleanup_ipv4_exception | ||
| 108 | # Similar to pmtu_ipv4_vxlan4_exception, but explicitly generate PMTU | ||
| 109 | # exceptions on multiple CPUs and check that the veth device tear-down | ||
| 110 | # happens in a timely manner | ||
| 111 | # | ||
| 112 | # - cleanup_ipv6_exception | ||
| 113 | # Same as above, but use IPv6 transport from A to B | ||
| 114 | |||
| 106 | 115 | ||
| 107 | # Kselftest framework requirement - SKIP code is 4. | 116 | # Kselftest framework requirement - SKIP code is 4. |
| 108 | ksft_skip=4 | 117 | ksft_skip=4 |
| @@ -135,7 +144,9 @@ tests=" | |||
| 135 | pmtu_vti6_default_mtu vti6: default MTU assignment | 144 | pmtu_vti6_default_mtu vti6: default MTU assignment |
| 136 | pmtu_vti4_link_add_mtu vti4: MTU setting on link creation | 145 | pmtu_vti4_link_add_mtu vti4: MTU setting on link creation |
| 137 | pmtu_vti6_link_add_mtu vti6: MTU setting on link creation | 146 | pmtu_vti6_link_add_mtu vti6: MTU setting on link creation |
| 138 | pmtu_vti6_link_change_mtu vti6: MTU changes on link changes" | 147 | pmtu_vti6_link_change_mtu vti6: MTU changes on link changes |
| 148 | cleanup_ipv4_exception ipv4: cleanup of cached exceptions | ||
| 149 | cleanup_ipv6_exception ipv6: cleanup of cached exceptions" | ||
| 139 | 150 | ||
| 140 | NS_A="ns-$(mktemp -u XXXXXX)" | 151 | NS_A="ns-$(mktemp -u XXXXXX)" |
| 141 | NS_B="ns-$(mktemp -u XXXXXX)" | 152 | NS_B="ns-$(mktemp -u XXXXXX)" |
| @@ -263,8 +274,6 @@ setup_fou_or_gue() { | |||
| 263 | 274 | ||
| 264 | ${ns_a} ip link set ${encap}_a up | 275 | ${ns_a} ip link set ${encap}_a up |
| 265 | ${ns_b} ip link set ${encap}_b up | 276 | ${ns_b} ip link set ${encap}_b up |
| 266 | |||
| 267 | sleep 1 | ||
| 268 | } | 277 | } |
| 269 | 278 | ||
| 270 | setup_fou44() { | 279 | setup_fou44() { |
| @@ -302,6 +311,10 @@ setup_gue66() { | |||
| 302 | setup_namespaces() { | 311 | setup_namespaces() { |
| 303 | for n in ${NS_A} ${NS_B} ${NS_R1} ${NS_R2}; do | 312 | for n in ${NS_A} ${NS_B} ${NS_R1} ${NS_R2}; do |
| 304 | ip netns add ${n} || return 1 | 313 | ip netns add ${n} || return 1 |
| 314 | |||
| 315 | # Disable DAD, so that we don't have to wait to use the | ||
| 316 | # configured IPv6 addresses | ||
| 317 | ip netns exec ${n} sysctl -q net/ipv6/conf/default/accept_dad=0 | ||
| 305 | done | 318 | done |
| 306 | } | 319 | } |
| 307 | 320 | ||
| @@ -337,8 +350,6 @@ setup_vti() { | |||
| 337 | 350 | ||
| 338 | ${ns_a} ip link set vti${proto}_a up | 351 | ${ns_a} ip link set vti${proto}_a up |
| 339 | ${ns_b} ip link set vti${proto}_b up | 352 | ${ns_b} ip link set vti${proto}_b up |
| 340 | |||
| 341 | sleep 1 | ||
| 342 | } | 353 | } |
| 343 | 354 | ||
| 344 | setup_vti4() { | 355 | setup_vti4() { |
| @@ -375,8 +386,6 @@ setup_vxlan_or_geneve() { | |||
| 375 | 386 | ||
| 376 | ${ns_a} ip link set ${type}_a up | 387 | ${ns_a} ip link set ${type}_a up |
| 377 | ${ns_b} ip link set ${type}_b up | 388 | ${ns_b} ip link set ${type}_b up |
| 378 | |||
| 379 | sleep 1 | ||
| 380 | } | 389 | } |
| 381 | 390 | ||
| 382 | setup_geneve4() { | 391 | setup_geneve4() { |
| @@ -588,8 +597,8 @@ test_pmtu_ipvX() { | |||
| 588 | mtu "${ns_b}" veth_B-R2 1500 | 597 | mtu "${ns_b}" veth_B-R2 1500 |
| 589 | 598 | ||
| 590 | # Create route exceptions | 599 | # Create route exceptions |
| 591 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s 1800 ${dst1} > /dev/null | 600 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1} > /dev/null |
| 592 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s 1800 ${dst2} > /dev/null | 601 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2} > /dev/null |
| 593 | 602 | ||
| 594 | # Check that exceptions have been created with the correct PMTU | 603 | # Check that exceptions have been created with the correct PMTU |
| 595 | pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" | 604 | pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" |
| @@ -621,7 +630,7 @@ test_pmtu_ipvX() { | |||
| 621 | # Decrease remote MTU on path via R2, get new exception | 630 | # Decrease remote MTU on path via R2, get new exception |
| 622 | mtu "${ns_r2}" veth_R2-B 400 | 631 | mtu "${ns_r2}" veth_R2-B 400 |
| 623 | mtu "${ns_b}" veth_B-R2 400 | 632 | mtu "${ns_b}" veth_B-R2 400 |
| 624 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s 1400 ${dst2} > /dev/null | 633 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2} > /dev/null |
| 625 | pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" | 634 | pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" |
| 626 | check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 | 635 | check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 |
| 627 | 636 | ||
| @@ -638,7 +647,7 @@ test_pmtu_ipvX() { | |||
| 638 | check_pmtu_value "1500" "${pmtu_2}" "increasing local MTU" || return 1 | 647 | check_pmtu_value "1500" "${pmtu_2}" "increasing local MTU" || return 1 |
| 639 | 648 | ||
| 640 | # Get new exception | 649 | # Get new exception |
| 641 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s 1400 ${dst2} > /dev/null | 650 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2} > /dev/null |
| 642 | pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" | 651 | pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" |
| 643 | check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 | 652 | check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 |
| 644 | } | 653 | } |
| @@ -687,7 +696,7 @@ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception() { | |||
| 687 | 696 | ||
| 688 | mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000)) | 697 | mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000)) |
| 689 | mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000)) | 698 | mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000)) |
| 690 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s $((${ll_mtu} + 500)) ${dst} > /dev/null | 699 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} > /dev/null |
| 691 | 700 | ||
| 692 | # Check that exception was created | 701 | # Check that exception was created |
| 693 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" | 702 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" |
| @@ -767,7 +776,7 @@ test_pmtu_ipvX_over_fouY_or_gueY() { | |||
| 767 | 776 | ||
| 768 | mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000)) | 777 | mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000)) |
| 769 | mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000)) | 778 | mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000)) |
| 770 | ${ns_a} ${ping} -q -M want -i 0.1 -w 2 -s $((${ll_mtu} + 500)) ${dst} > /dev/null | 779 | ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} > /dev/null |
| 771 | 780 | ||
| 772 | # Check that exception was created | 781 | # Check that exception was created |
| 773 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" | 782 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" |
| @@ -825,13 +834,13 @@ test_pmtu_vti4_exception() { | |||
| 825 | 834 | ||
| 826 | # Send DF packet without exceeding link layer MTU, check that no | 835 | # Send DF packet without exceeding link layer MTU, check that no |
| 827 | # exception is created | 836 | # exception is created |
| 828 | ${ns_a} ping -q -M want -i 0.1 -w 2 -s ${ping_payload} ${tunnel4_b_addr} > /dev/null | 837 | ${ns_a} ping -q -M want -i 0.1 -w 1 -s ${ping_payload} ${tunnel4_b_addr} > /dev/null |
| 829 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" | 838 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" |
| 830 | check_pmtu_value "" "${pmtu}" "sending packet smaller than PMTU (IP payload length ${esp_payload_rfc4106})" || return 1 | 839 | check_pmtu_value "" "${pmtu}" "sending packet smaller than PMTU (IP payload length ${esp_payload_rfc4106})" || return 1 |
| 831 | 840 | ||
| 832 | # Now exceed link layer MTU by one byte, check that exception is created | 841 | # Now exceed link layer MTU by one byte, check that exception is created |
| 833 | # with the right PMTU value | 842 | # with the right PMTU value |
| 834 | ${ns_a} ping -q -M want -i 0.1 -w 2 -s $((ping_payload + 1)) ${tunnel4_b_addr} > /dev/null | 843 | ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((ping_payload + 1)) ${tunnel4_b_addr} > /dev/null |
| 835 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" | 844 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" |
| 836 | check_pmtu_value "${esp_payload_rfc4106}" "${pmtu}" "exceeding PMTU (IP payload length $((esp_payload_rfc4106 + 1)))" | 845 | check_pmtu_value "${esp_payload_rfc4106}" "${pmtu}" "exceeding PMTU (IP payload length $((esp_payload_rfc4106 + 1)))" |
| 837 | } | 846 | } |
| @@ -847,7 +856,7 @@ test_pmtu_vti6_exception() { | |||
| 847 | mtu "${ns_b}" veth_b 4000 | 856 | mtu "${ns_b}" veth_b 4000 |
| 848 | mtu "${ns_a}" vti6_a 5000 | 857 | mtu "${ns_a}" vti6_a 5000 |
| 849 | mtu "${ns_b}" vti6_b 5000 | 858 | mtu "${ns_b}" vti6_b 5000 |
| 850 | ${ns_a} ${ping6} -q -i 0.1 -w 2 -s 60000 ${tunnel6_b_addr} > /dev/null | 859 | ${ns_a} ${ping6} -q -i 0.1 -w 1 -s 60000 ${tunnel6_b_addr} > /dev/null |
| 851 | 860 | ||
| 852 | # Check that exception was created | 861 | # Check that exception was created |
| 853 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})" | 862 | pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})" |
| @@ -1008,6 +1017,61 @@ test_pmtu_vti6_link_change_mtu() { | |||
| 1008 | return ${fail} | 1017 | return ${fail} |
| 1009 | } | 1018 | } |
| 1010 | 1019 | ||
| 1020 | check_command() { | ||
| 1021 | cmd=${1} | ||
| 1022 | |||
| 1023 | if ! which ${cmd} > /dev/null 2>&1; then | ||
| 1024 | err " missing required command: '${cmd}'" | ||
| 1025 | return 1 | ||
| 1026 | fi | ||
| 1027 | return 0 | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | test_cleanup_vxlanX_exception() { | ||
| 1031 | outer="${1}" | ||
| 1032 | encap="vxlan" | ||
| 1033 | ll_mtu=4000 | ||
| 1034 | |||
| 1035 | check_command taskset || return 2 | ||
| 1036 | cpu_list=$(grep -m 2 processor /proc/cpuinfo | cut -d ' ' -f 2) | ||
| 1037 | |||
| 1038 | setup namespaces routing ${encap}${outer} || return 2 | ||
| 1039 | trace "${ns_a}" ${encap}_a "${ns_b}" ${encap}_b \ | ||
| 1040 | "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ | ||
| 1041 | "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B | ||
| 1042 | |||
| 1043 | # Create route exception by exceeding link layer MTU | ||
| 1044 | mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) | ||
| 1045 | mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) | ||
| 1046 | mtu "${ns_b}" veth_B-R1 ${ll_mtu} | ||
| 1047 | mtu "${ns_r1}" veth_R1-B ${ll_mtu} | ||
| 1048 | |||
| 1049 | mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000)) | ||
| 1050 | mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000)) | ||
| 1051 | |||
| 1052 | # Fill exception cache for multiple CPUs (2) | ||
| 1053 | # we can always use inner IPv4 for that | ||
| 1054 | for cpu in ${cpu_list}; do | ||
| 1055 | taskset --cpu-list ${cpu} ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${tunnel4_b_addr} > /dev/null | ||
| 1056 | done | ||
| 1057 | |||
| 1058 | ${ns_a} ip link del dev veth_A-R1 & | ||
| 1059 | iplink_pid=$! | ||
| 1060 | sleep 1 | ||
| 1061 | if [ "$(cat /proc/${iplink_pid}/cmdline 2>/dev/null | tr -d '\0')" = "iplinkdeldevveth_A-R1" ]; then | ||
| 1062 | err " can't delete veth device in a timely manner, PMTU dst likely leaked" | ||
| 1063 | return 1 | ||
| 1064 | fi | ||
| 1065 | } | ||
| 1066 | |||
| 1067 | test_cleanup_ipv6_exception() { | ||
| 1068 | test_cleanup_vxlanX_exception 6 | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | test_cleanup_ipv4_exception() { | ||
| 1072 | test_cleanup_vxlanX_exception 4 | ||
| 1073 | } | ||
| 1074 | |||
| 1011 | usage() { | 1075 | usage() { |
| 1012 | echo | 1076 | echo |
| 1013 | echo "$0 [OPTIONS] [TEST]..." | 1077 | echo "$0 [OPTIONS] [TEST]..." |
diff --git a/tools/testing/selftests/net/udpgro.sh b/tools/testing/selftests/net/udpgro.sh index aeac53a99aeb..ac2a30be9b32 100755 --- a/tools/testing/selftests/net/udpgro.sh +++ b/tools/testing/selftests/net/udpgro.sh | |||
| @@ -37,7 +37,7 @@ run_one() { | |||
| 37 | 37 | ||
| 38 | cfg_veth | 38 | cfg_veth |
| 39 | 39 | ||
| 40 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} && \ | 40 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} && \ |
| 41 | echo "ok" || \ | 41 | echo "ok" || \ |
| 42 | echo "failed" & | 42 | echo "failed" & |
| 43 | 43 | ||
| @@ -81,7 +81,7 @@ run_one_nat() { | |||
| 81 | # will land on the 'plain' one | 81 | # will land on the 'plain' one |
| 82 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 & | 82 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -G ${family} -b ${addr1} -n 0 & |
| 83 | pid=$! | 83 | pid=$! |
| 84 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${family} -b ${addr2%/*} ${rx_args} && \ | 84 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${family} -b ${addr2%/*} ${rx_args} && \ |
| 85 | echo "ok" || \ | 85 | echo "ok" || \ |
| 86 | echo "failed"& | 86 | echo "failed"& |
| 87 | 87 | ||
| @@ -99,8 +99,8 @@ run_one_2sock() { | |||
| 99 | 99 | ||
| 100 | cfg_veth | 100 | cfg_veth |
| 101 | 101 | ||
| 102 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} -p 12345 & | 102 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 1000 -R 10 ${rx_args} -p 12345 & |
| 103 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx ${rx_args} && \ | 103 | ip netns exec "${PEER_NS}" ./udpgso_bench_rx -C 2000 -R 10 ${rx_args} && \ |
| 104 | echo "ok" || \ | 104 | echo "ok" || \ |
| 105 | echo "failed" & | 105 | echo "failed" & |
| 106 | 106 | ||
diff --git a/tools/testing/selftests/net/udpgso_bench_rx.c b/tools/testing/selftests/net/udpgso_bench_rx.c index 0c960f673324..db3d4a8b5a4c 100644 --- a/tools/testing/selftests/net/udpgso_bench_rx.c +++ b/tools/testing/selftests/net/udpgso_bench_rx.c | |||
| @@ -45,6 +45,8 @@ static int cfg_alen = sizeof(struct sockaddr_in6); | |||
| 45 | static int cfg_expected_pkt_nr; | 45 | static int cfg_expected_pkt_nr; |
| 46 | static int cfg_expected_pkt_len; | 46 | static int cfg_expected_pkt_len; |
| 47 | static int cfg_expected_gso_size; | 47 | static int cfg_expected_gso_size; |
| 48 | static int cfg_connect_timeout_ms; | ||
| 49 | static int cfg_rcv_timeout_ms; | ||
| 48 | static struct sockaddr_storage cfg_bind_addr; | 50 | static struct sockaddr_storage cfg_bind_addr; |
| 49 | 51 | ||
| 50 | static bool interrupted; | 52 | static bool interrupted; |
| @@ -87,7 +89,7 @@ static unsigned long gettimeofday_ms(void) | |||
| 87 | return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); | 89 | return (tv.tv_sec * 1000) + (tv.tv_usec / 1000); |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 90 | static void do_poll(int fd) | 92 | static void do_poll(int fd, int timeout_ms) |
| 91 | { | 93 | { |
| 92 | struct pollfd pfd; | 94 | struct pollfd pfd; |
| 93 | int ret; | 95 | int ret; |
| @@ -102,8 +104,16 @@ static void do_poll(int fd) | |||
| 102 | break; | 104 | break; |
| 103 | if (ret == -1) | 105 | if (ret == -1) |
| 104 | error(1, errno, "poll"); | 106 | error(1, errno, "poll"); |
| 105 | if (ret == 0) | 107 | if (ret == 0) { |
| 106 | continue; | 108 | if (!timeout_ms) |
| 109 | continue; | ||
| 110 | |||
| 111 | timeout_ms -= 10; | ||
| 112 | if (timeout_ms <= 0) { | ||
| 113 | interrupted = true; | ||
| 114 | break; | ||
| 115 | } | ||
| 116 | } | ||
| 107 | if (pfd.revents != POLLIN) | 117 | if (pfd.revents != POLLIN) |
| 108 | error(1, errno, "poll: 0x%x expected 0x%x\n", | 118 | error(1, errno, "poll: 0x%x expected 0x%x\n", |
| 109 | pfd.revents, POLLIN); | 119 | pfd.revents, POLLIN); |
| @@ -134,7 +144,7 @@ static int do_socket(bool do_tcp) | |||
| 134 | if (listen(accept_fd, 1)) | 144 | if (listen(accept_fd, 1)) |
| 135 | error(1, errno, "listen"); | 145 | error(1, errno, "listen"); |
| 136 | 146 | ||
| 137 | do_poll(accept_fd); | 147 | do_poll(accept_fd, cfg_connect_timeout_ms); |
| 138 | if (interrupted) | 148 | if (interrupted) |
| 139 | exit(0); | 149 | exit(0); |
| 140 | 150 | ||
| @@ -273,7 +283,9 @@ static void do_flush_udp(int fd) | |||
| 273 | 283 | ||
| 274 | static void usage(const char *filepath) | 284 | static void usage(const char *filepath) |
| 275 | { | 285 | { |
| 276 | error(1, 0, "Usage: %s [-Grtv] [-b addr] [-p port] [-l pktlen] [-n packetnr] [-S gsosize]", filepath); | 286 | error(1, 0, "Usage: %s [-C connect_timeout] [-Grtv] [-b addr] [-p port]" |
| 287 | " [-l pktlen] [-n packetnr] [-R rcv_timeout] [-S gsosize]", | ||
| 288 | filepath); | ||
| 277 | } | 289 | } |
| 278 | 290 | ||
| 279 | static void parse_opts(int argc, char **argv) | 291 | static void parse_opts(int argc, char **argv) |
| @@ -282,7 +294,7 @@ static void parse_opts(int argc, char **argv) | |||
| 282 | 294 | ||
| 283 | /* bind to any by default */ | 295 | /* bind to any by default */ |
| 284 | setup_sockaddr(PF_INET6, "::", &cfg_bind_addr); | 296 | setup_sockaddr(PF_INET6, "::", &cfg_bind_addr); |
| 285 | while ((c = getopt(argc, argv, "4b:Gl:n:p:rS:tv")) != -1) { | 297 | while ((c = getopt(argc, argv, "4b:C:Gl:n:p:rR:S:tv")) != -1) { |
| 286 | switch (c) { | 298 | switch (c) { |
| 287 | case '4': | 299 | case '4': |
| 288 | cfg_family = PF_INET; | 300 | cfg_family = PF_INET; |
| @@ -292,6 +304,9 @@ static void parse_opts(int argc, char **argv) | |||
| 292 | case 'b': | 304 | case 'b': |
| 293 | setup_sockaddr(cfg_family, optarg, &cfg_bind_addr); | 305 | setup_sockaddr(cfg_family, optarg, &cfg_bind_addr); |
| 294 | break; | 306 | break; |
| 307 | case 'C': | ||
| 308 | cfg_connect_timeout_ms = strtoul(optarg, NULL, 0); | ||
| 309 | break; | ||
| 295 | case 'G': | 310 | case 'G': |
| 296 | cfg_gro_segment = true; | 311 | cfg_gro_segment = true; |
| 297 | break; | 312 | break; |
| @@ -307,6 +322,9 @@ static void parse_opts(int argc, char **argv) | |||
| 307 | case 'r': | 322 | case 'r': |
| 308 | cfg_read_all = true; | 323 | cfg_read_all = true; |
| 309 | break; | 324 | break; |
| 325 | case 'R': | ||
| 326 | cfg_rcv_timeout_ms = strtoul(optarg, NULL, 0); | ||
| 327 | break; | ||
| 310 | case 'S': | 328 | case 'S': |
| 311 | cfg_expected_gso_size = strtol(optarg, NULL, 0); | 329 | cfg_expected_gso_size = strtol(optarg, NULL, 0); |
| 312 | break; | 330 | break; |
| @@ -329,8 +347,9 @@ static void parse_opts(int argc, char **argv) | |||
| 329 | 347 | ||
| 330 | static void do_recv(void) | 348 | static void do_recv(void) |
| 331 | { | 349 | { |
| 350 | int timeout_ms = cfg_tcp ? cfg_rcv_timeout_ms : cfg_connect_timeout_ms; | ||
| 332 | unsigned long tnow, treport; | 351 | unsigned long tnow, treport; |
| 333 | int fd, loop = 0; | 352 | int fd; |
| 334 | 353 | ||
| 335 | fd = do_socket(cfg_tcp); | 354 | fd = do_socket(cfg_tcp); |
| 336 | 355 | ||
| @@ -342,12 +361,7 @@ static void do_recv(void) | |||
| 342 | 361 | ||
| 343 | treport = gettimeofday_ms() + 1000; | 362 | treport = gettimeofday_ms() + 1000; |
| 344 | do { | 363 | do { |
| 345 | /* force termination after the second poll(); this cope both | 364 | do_poll(fd, timeout_ms); |
| 346 | * with sender slower than receiver and missing packet errors | ||
| 347 | */ | ||
| 348 | if (cfg_expected_pkt_nr && loop++) | ||
| 349 | interrupted = true; | ||
| 350 | do_poll(fd); | ||
| 351 | 365 | ||
| 352 | if (cfg_tcp) | 366 | if (cfg_tcp) |
| 353 | do_flush_tcp(fd); | 367 | do_flush_tcp(fd); |
| @@ -365,6 +379,8 @@ static void do_recv(void) | |||
| 365 | treport = tnow + 1000; | 379 | treport = tnow + 1000; |
| 366 | } | 380 | } |
| 367 | 381 | ||
| 382 | timeout_ms = cfg_rcv_timeout_ms; | ||
| 383 | |||
| 368 | } while (!interrupted); | 384 | } while (!interrupted); |
| 369 | 385 | ||
| 370 | if (cfg_expected_pkt_nr && (packets != cfg_expected_pkt_nr)) | 386 | if (cfg_expected_pkt_nr && (packets != cfg_expected_pkt_nr)) |
