diff options
author | David S. Miller <davem@davemloft.net> | 2019-03-02 15:54:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-03-02 15:54:35 -0500 |
commit | 9eb359140cd307f8a14f61c19b155ffca5291057 (patch) | |
tree | 22d5143608ef1744ca4b7025414777defe8bcca5 | |
parent | cf29576fee6016fa7004262cb98f57a2269178f1 (diff) | |
parent | 07f12b26e21ab359261bf75cfcb424fdc7daeb6d (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
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 ee1455758764..d8328866908c 100644 --- a/drivers/net/dsa/lantiq_gswip.c +++ b/drivers/net/dsa/lantiq_gswip.c | |||
@@ -1163,6 +1163,12 @@ static struct platform_driver gswip_driver = { | |||
1163 | 1163 | ||
1164 | module_platform_driver(gswip_driver); | 1164 | module_platform_driver(gswip_driver); |
1165 | 1165 | ||
1166 | MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin"); | ||
1167 | MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin"); | ||
1168 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin"); | ||
1169 | MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin"); | ||
1170 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin"); | ||
1171 | MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin"); | ||
1166 | MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); | 1172 | MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); |
1167 | MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); | 1173 | MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); |
1168 | MODULE_LICENSE("GPL v2"); | 1174 | MODULE_LICENSE("GPL v2"); |
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c index a3a2eb985ace..e4ad16b2dc38 100644 --- a/drivers/net/dsa/mv88e6xxx/chip.c +++ b/drivers/net/dsa/mv88e6xxx/chip.c | |||
@@ -922,7 +922,7 @@ static uint64_t _mv88e6xxx_get_ethtool_stat(struct mv88e6xxx_chip *chip, | |||
922 | default: | 922 | default: |
923 | return U64_MAX; | 923 | return U64_MAX; |
924 | } | 924 | } |
925 | value = (((u64)high) << 16) | low; | 925 | value = (((u64)high) << 32) | low; |
926 | return value; | 926 | return value; |
927 | } | 927 | } |
928 | 928 | ||
@@ -3118,7 +3118,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = { | |||
3118 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, | 3118 | .port_disable_pri_override = mv88e6xxx_port_disable_pri_override, |
3119 | .port_link_state = mv88e6352_port_link_state, | 3119 | .port_link_state = mv88e6352_port_link_state, |
3120 | .port_get_cmode = mv88e6185_port_get_cmode, | 3120 | .port_get_cmode = mv88e6185_port_get_cmode, |
3121 | .stats_snapshot = mv88e6320_g1_stats_snapshot, | 3121 | .stats_snapshot = mv88e6xxx_g1_stats_snapshot, |
3122 | .stats_set_histogram = mv88e6095_g1_stats_set_histogram, | 3122 | .stats_set_histogram = mv88e6095_g1_stats_set_histogram, |
3123 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, | 3123 | .stats_get_sset_count = mv88e6095_stats_get_sset_count, |
3124 | .stats_get_strings = mv88e6095_stats_get_strings, | 3124 | .stats_get_strings = mv88e6095_stats_get_strings, |
@@ -4620,6 +4620,14 @@ static int mv88e6xxx_smi_init(struct mv88e6xxx_chip *chip, | |||
4620 | return 0; | 4620 | return 0; |
4621 | } | 4621 | } |
4622 | 4622 | ||
4623 | static void mv88e6xxx_ports_cmode_init(struct mv88e6xxx_chip *chip) | ||
4624 | { | ||
4625 | int i; | ||
4626 | |||
4627 | for (i = 0; i < mv88e6xxx_num_ports(chip); i++) | ||
4628 | chip->ports[i].cmode = MV88E6XXX_PORT_STS_CMODE_INVALID; | ||
4629 | } | ||
4630 | |||
4623 | static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, | 4631 | static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, |
4624 | int port) | 4632 | int port) |
4625 | { | 4633 | { |
@@ -4656,6 +4664,8 @@ static const char *mv88e6xxx_drv_probe(struct device *dsa_dev, | |||
4656 | if (err) | 4664 | if (err) |
4657 | goto free; | 4665 | goto free; |
4658 | 4666 | ||
4667 | mv88e6xxx_ports_cmode_init(chip); | ||
4668 | |||
4659 | mutex_lock(&chip->reg_lock); | 4669 | mutex_lock(&chip->reg_lock); |
4660 | err = mv88e6xxx_switch_reset(chip); | 4670 | err = mv88e6xxx_switch_reset(chip); |
4661 | mutex_unlock(&chip->reg_lock); | 4671 | mutex_unlock(&chip->reg_lock); |
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c index ee7029f4ee22..9f6ac116c214 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 7eb5ea948d61..b31dba1b1a55 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 | |||
@@ -279,6 +279,9 @@ static int hw_atl_b0_hw_offload_set(struct aq_hw_s *self, | |||
279 | 279 | ||
280 | static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) | 280 | static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) |
281 | { | 281 | { |
282 | /* Tx TC/Queue number config */ | ||
283 | hw_atl_rpb_tps_tx_tc_mode_set(self, 1U); | ||
284 | |||
282 | hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); | 285 | hw_atl_thm_lso_tcp_flag_of_first_pkt_set(self, 0x0FF6U); |
283 | hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); | 286 | hw_atl_thm_lso_tcp_flag_of_middle_pkt_set(self, 0x0FF6U); |
284 | hw_atl_thm_lso_tcp_flag_of_last_pkt_set(self, 0x0F7FU); | 287 | 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 f72194c77f5f..0722b8e01964 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 40e6c1e44b5b..d46351890b16 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 50b4dee5562d..fb45bc2d99cf 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 42fe9e0cceec..0bb9d7b3a2b6 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c | |||
@@ -504,6 +504,12 @@ normal_tx: | |||
504 | } | 504 | } |
505 | 505 | ||
506 | length >>= 9; | 506 | length >>= 9; |
507 | if (unlikely(length >= ARRAY_SIZE(bnxt_lhint_arr))) { | ||
508 | dev_warn_ratelimited(&pdev->dev, "Dropped oversize %d bytes TX packet.\n", | ||
509 | skb->len); | ||
510 | i = 0; | ||
511 | goto tx_dma_error; | ||
512 | } | ||
507 | flags |= bnxt_lhint_arr[length]; | 513 | flags |= bnxt_lhint_arr[length]; |
508 | txbd->tx_bd_len_flags_type = cpu_to_le32(flags); | 514 | txbd->tx_bd_len_flags_type = cpu_to_le32(flags); |
509 | 515 | ||
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 fc09c5c1a4de..8448d01819ef 100644 --- a/drivers/net/phy/dp83867.c +++ b/drivers/net/phy/dp83867.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/module.h> | 11 | #include <linux/module.h> |
12 | #include <linux/of.h> | 12 | #include <linux/of.h> |
13 | #include <linux/phy.h> | 13 | #include <linux/phy.h> |
14 | #include <linux/delay.h> | ||
14 | 15 | ||
15 | #include <dt-bindings/net/ti-dp83867.h> | 16 | #include <dt-bindings/net/ti-dp83867.h> |
16 | 17 | ||
@@ -304,6 +305,8 @@ static int dp83867_phy_reset(struct phy_device *phydev) | |||
304 | if (err < 0) | 305 | if (err < 0) |
305 | return err; | 306 | return err; |
306 | 307 | ||
308 | usleep_range(10, 20); | ||
309 | |||
307 | return dp83867_config_init(phydev); | 310 | return dp83867_config_init(phydev); |
308 | } | 311 | } |
309 | 312 | ||
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 38d5bd877346..352da24f1f33 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -340,6 +340,17 @@ static int ksz8041_config_aneg(struct phy_device *phydev) | |||
340 | return genphy_config_aneg(phydev); | 340 | return genphy_config_aneg(phydev); |
341 | } | 341 | } |
342 | 342 | ||
343 | static int ksz8061_config_init(struct phy_device *phydev) | ||
344 | { | ||
345 | int ret; | ||
346 | |||
347 | ret = phy_write_mmd(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A); | ||
348 | if (ret) | ||
349 | return ret; | ||
350 | |||
351 | return kszphy_config_init(phydev); | ||
352 | } | ||
353 | |||
343 | static int ksz9021_load_values_from_of(struct phy_device *phydev, | 354 | static int ksz9021_load_values_from_of(struct phy_device *phydev, |
344 | const struct device_node *of_node, | 355 | const struct device_node *of_node, |
345 | u16 reg, | 356 | u16 reg, |
@@ -1015,7 +1026,7 @@ static struct phy_driver ksphy_driver[] = { | |||
1015 | .name = "Micrel KSZ8061", | 1026 | .name = "Micrel KSZ8061", |
1016 | .phy_id_mask = MICREL_PHY_ID_MASK, | 1027 | .phy_id_mask = MICREL_PHY_ID_MASK, |
1017 | .features = PHY_BASIC_FEATURES, | 1028 | .features = PHY_BASIC_FEATURES, |
1018 | .config_init = kszphy_config_init, | 1029 | .config_init = ksz8061_config_init, |
1019 | .ack_interrupt = kszphy_ack_interrupt, | 1030 | .ack_interrupt = kszphy_ack_interrupt, |
1020 | .config_intr = kszphy_config_intr, | 1031 | .config_intr = kszphy_config_intr, |
1021 | .suspend = genphy_suspend, | 1032 | .suspend = genphy_suspend, |
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c index 59d175a5ba54..89750c7dfd6f 100644 --- a/drivers/net/phy/phylink.c +++ b/drivers/net/phy/phylink.c | |||
@@ -324,6 +324,10 @@ static int phylink_get_mac_state(struct phylink *pl, struct phylink_link_state * | |||
324 | linkmode_zero(state->lp_advertising); | 324 | linkmode_zero(state->lp_advertising); |
325 | state->interface = pl->link_config.interface; | 325 | state->interface = pl->link_config.interface; |
326 | state->an_enabled = pl->link_config.an_enabled; | 326 | state->an_enabled = pl->link_config.an_enabled; |
327 | state->speed = SPEED_UNKNOWN; | ||
328 | state->duplex = DUPLEX_UNKNOWN; | ||
329 | state->pause = MLO_PAUSE_NONE; | ||
330 | state->an_complete = 0; | ||
327 | state->link = 1; | 331 | state->link = 1; |
328 | 332 | ||
329 | return pl->ops->mac_link_state(ndev, state); | 333 | return pl->ops->mac_link_state(ndev, state); |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 80bff1b4ec17..1d68921723dc 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 c801a832851c..1d9940d4e8c7 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 c10b60297d28..26f69cf763f4 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -3887,7 +3887,7 @@ static inline u32 netif_msg_init(int debug_value, int default_msg_enable_bits) | |||
3887 | if (debug_value == 0) /* no output */ | 3887 | if (debug_value == 0) /* no output */ |
3888 | return 0; | 3888 | return 0; |
3889 | /* set low N bits */ | 3889 | /* set low N bits */ |
3890 | return (1 << debug_value) - 1; | 3890 | return (1U << debug_value) - 1; |
3891 | } | 3891 | } |
3892 | 3892 | ||
3893 | static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) | 3893 | 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 ec7c552af76b..797a99c7493e 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c | |||
@@ -577,12 +577,12 @@ static int map_create(union bpf_attr *attr) | |||
577 | err = bpf_map_new_fd(map, f_flags); | 577 | err = bpf_map_new_fd(map, f_flags); |
578 | if (err < 0) { | 578 | if (err < 0) { |
579 | /* failed to allocate fd. | 579 | /* failed to allocate fd. |
580 | * bpf_map_put() is needed because the above | 580 | * bpf_map_put_with_uref() is needed because the above |
581 | * bpf_map_alloc_id() has published the map | 581 | * bpf_map_alloc_id() has published the map |
582 | * to the userspace and the userspace may | 582 | * to the userspace and the userspace may |
583 | * have refcnt-ed it through BPF_MAP_GET_FD_BY_ID. | 583 | * have refcnt-ed it through BPF_MAP_GET_FD_BY_ID. |
584 | */ | 584 | */ |
585 | bpf_map_put(map); | 585 | bpf_map_put_with_uref(map); |
586 | return err; | 586 | return err; |
587 | } | 587 | } |
588 | 588 | ||
@@ -2025,7 +2025,7 @@ static int bpf_map_get_fd_by_id(const union bpf_attr *attr) | |||
2025 | 2025 | ||
2026 | fd = bpf_map_new_fd(map, f_flags); | 2026 | fd = bpf_map_new_fd(map, f_flags); |
2027 | if (fd < 0) | 2027 | if (fd < 0) |
2028 | bpf_map_put(map); | 2028 | bpf_map_put_with_uref(map); |
2029 | 2029 | ||
2030 | return fd; | 2030 | return fd; |
2031 | } | 2031 | } |
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 1b9496c41383..ebc3b264aa4d 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c | |||
@@ -7559,7 +7559,8 @@ static int fixup_bpf_calls(struct bpf_verifier_env *env) | |||
7559 | u32 off_reg; | 7559 | u32 off_reg; |
7560 | 7560 | ||
7561 | aux = &env->insn_aux_data[i + delta]; | 7561 | aux = &env->insn_aux_data[i + delta]; |
7562 | if (!aux->alu_state) | 7562 | if (!aux->alu_state || |
7563 | aux->alu_state == BPF_ALU_NON_POINTER) | ||
7563 | continue; | 7564 | continue; |
7564 | 7565 | ||
7565 | isneg = aux->alu_state & BPF_ALU_NEG_VALUE; | 7566 | isneg = aux->alu_state & BPF_ALU_NEG_VALUE; |
diff --git a/net/dsa/dsa2.c b/net/dsa/dsa2.c index 8c431e0f3627..c00ee464afc7 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 a2dad10646cb..caeef4c99dc0 100644 --- a/net/dsa/port.c +++ b/net/dsa/port.c | |||
@@ -337,6 +337,7 @@ static struct phy_device *dsa_port_get_phy_device(struct dsa_port *dp) | |||
337 | return ERR_PTR(-EPROBE_DEFER); | 337 | return ERR_PTR(-EPROBE_DEFER); |
338 | } | 338 | } |
339 | 339 | ||
340 | of_node_put(phy_dn); | ||
340 | return phydev; | 341 | return phydev; |
341 | } | 342 | } |
342 | 343 | ||
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 364cfe5e414b..f3a5893b1e86 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 cd6b5694f99e..ecce2dc78f17 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 e3ac458b5d8b..738ff0a1a048 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2876,7 +2876,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
2876 | 2876 | ||
2877 | if (tb[RTA_IP_PROTO]) { | 2877 | if (tb[RTA_IP_PROTO]) { |
2878 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], | 2878 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], |
2879 | &ip_proto, extack); | 2879 | &ip_proto, AF_INET, extack); |
2880 | if (err) | 2880 | if (err) |
2881 | return err; | 2881 | return err; |
2882 | } | 2882 | } |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 6181b4a18178..4ef4bbdb49d4 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -4176,6 +4176,10 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh, | |||
4176 | cfg->fc_gateway = nla_get_in6_addr(tb[RTA_GATEWAY]); | 4176 | cfg->fc_gateway = nla_get_in6_addr(tb[RTA_GATEWAY]); |
4177 | cfg->fc_flags |= RTF_GATEWAY; | 4177 | cfg->fc_flags |= RTF_GATEWAY; |
4178 | } | 4178 | } |
4179 | if (tb[RTA_VIA]) { | ||
4180 | NL_SET_ERR_MSG(extack, "IPv6 does not support RTA_VIA attribute"); | ||
4181 | goto errout; | ||
4182 | } | ||
4179 | 4183 | ||
4180 | if (tb[RTA_DST]) { | 4184 | if (tb[RTA_DST]) { |
4181 | int plen = (rtm->rtm_dst_len + 7) >> 3; | 4185 | int plen = (rtm->rtm_dst_len + 7) >> 3; |
@@ -4949,7 +4953,8 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh, | |||
4949 | 4953 | ||
4950 | if (tb[RTA_IP_PROTO]) { | 4954 | if (tb[RTA_IP_PROTO]) { |
4951 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], | 4955 | err = rtm_getroute_parse_ip_proto(tb[RTA_IP_PROTO], |
4952 | &fl6.flowi6_proto, extack); | 4956 | &fl6.flowi6_proto, AF_INET6, |
4957 | extack); | ||
4953 | if (err) | 4958 | if (err) |
4954 | goto errout; | 4959 | goto errout; |
4955 | } | 4960 | } |
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 2662a23c658e..f7c544592ec8 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -1874,6 +1874,9 @@ static int rtm_to_route_config(struct sk_buff *skb, | |||
1874 | goto errout; | 1874 | goto errout; |
1875 | break; | 1875 | break; |
1876 | } | 1876 | } |
1877 | case RTA_GATEWAY: | ||
1878 | NL_SET_ERR_MSG(extack, "MPLS does not support RTA_GATEWAY attribute"); | ||
1879 | goto errout; | ||
1877 | case RTA_VIA: | 1880 | case RTA_VIA: |
1878 | { | 1881 | { |
1879 | if (nla_get_via(nla, &cfg->rc_via_alen, | 1882 | 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 1bad190710ad..98f5b6ea77b4 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 39f8a67ea940..65879500b688 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 fc2b884b170c..2a5f215ae876 100644 --- a/net/sched/act_tunnel_key.c +++ b/net/sched/act_tunnel_key.c | |||
@@ -394,7 +394,8 @@ release_dst_cache: | |||
394 | dst_cache_destroy(&metadata->u.tun_info.dst_cache); | 394 | dst_cache_destroy(&metadata->u.tun_info.dst_cache); |
395 | #endif | 395 | #endif |
396 | release_tun_meta: | 396 | release_tun_meta: |
397 | dst_release(&metadata->dst); | 397 | if (metadata) |
398 | dst_release(&metadata->dst); | ||
398 | 399 | ||
399 | err_out: | 400 | err_out: |
400 | if (exists) | 401 | 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 643a1648fcc2..3c176a12fe48 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 8c81db337431..e482b342bfa8 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)) |