aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2019-03-02 11:46:34 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2019-03-02 11:46:34 -0500
commitc93d9218ea561d6a91b23449cfd637ddec91dc23 (patch)
tree6593f88489428185ec6e9c526e5ec37036231431
parentfa3294c58c58c4fa87ee0356b6cb1901db00533e (diff)
parent07f12b26e21ab359261bf75cfcb424fdc7daeb6d (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Pull networking fixes from David Miller: 1) Fix refcount leak in act_ipt during replace, from Davide Caratti. 2) Set task state properly in tun during blocking reads, from Timur Celik. 3) Leaked reference in DSA, from Wen Yang. 4) NULL deref in act_tunnel_key, from Vlad Buslov. 5) cipso_v4_erro can reference the skb IPCB in inappropriate contexts thus referencing garbage, from Nazarov Sergey. 6) Don't accept RTA_VIA and RTA_GATEWAY in contexts where those attributes make no sense. 7) Fix hung sendto in tipc, from Tung Nguyen. 8) Out-of-bounds access in netlabel, from Paul Moore. 9) Grant reference leak in xen-netback, from Igor Druzhinin. 10) Fix tx stalls with lan743x, from Bryan Whitehead. 11) Fix interrupt storm with mv88e6xxx, from Hein Kallweit. 12) Memory leak in sit on device registry failure, from Mao Wenan. * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (44 commits) net: sit: fix memory leak in sit_init_net() net: dsa: mv88e6xxx: Fix statistics on mv88e6161 geneve: correctly handle ipv6.disable module parameter net: dsa: mv88e6xxx: prevent interrupt storm caused by mv88e6390x_port_set_cmode bpf: fix sanitation rewrite in case of non-pointers ipv4: Add ICMPv6 support when parse route ipproto MIPS: eBPF: Fix icache flush end address lan743x: Fix TX Stall Issue net: phy: phylink: fix uninitialized variable in phylink_get_mac_state net: aquantia: regression on cpus with high cores: set mode with 8 queues selftests: fixes for UDP GRO bpf: drop refcount if bpf_map_new_fd() fails in map_create() net: dsa: mv88e6xxx: power serdes on/off for 10G interfaces on 6390X net: dsa: mv88e6xxx: Fix u64 statistics xen-netback: don't populate the hash cache on XenBus disconnect xen-netback: fix occasional leak of grant ref mappings under memory pressure sctp: chunk.c: correct format string for size_t in printk net: netem: fix skb length BUG_ON in __skb_to_sgvec netlabel: fix out-of-bounds memory accesses ipv4: Pass original device to ip_rcv_finish_core ...
-rw-r--r--arch/mips/net/ebpf_jit.c2
-rw-r--r--drivers/net/dsa/lantiq_gswip.c6
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c14
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.c8
-rw-r--r--drivers/net/dsa/mv88e6xxx/port.h1
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c3
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.c9
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh.h4
-rw-r--r--drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_llh_internal.h13
-rw-r--r--drivers/net/ethernet/broadcom/bnxt/bnxt.c6
-rw-r--r--drivers/net/ethernet/microchip/enc28j60.c2
-rw-r--r--drivers/net/ethernet/microchip/lan743x_main.c16
-rw-r--r--drivers/net/geneve.c11
-rw-r--r--drivers/net/hyperv/netvsc_drv.c22
-rw-r--r--drivers/net/phy/dp83867.c3
-rw-r--r--drivers/net/phy/micrel.c13
-rw-r--r--drivers/net/phy/phylink.c4
-rw-r--r--drivers/net/tun.c4
-rw-r--r--drivers/net/xen-netback/hash.c2
-rw-r--r--drivers/net/xen-netback/interface.c7
-rw-r--r--drivers/net/xen-netback/netback.c10
-rw-r--r--include/linux/netdevice.h2
-rw-r--r--include/net/icmp.h9
-rw-r--r--include/net/ip.h4
-rw-r--r--kernel/bpf/syscall.c6
-rw-r--r--kernel/bpf/verifier.c3
-rw-r--r--net/dsa/dsa2.c16
-rw-r--r--net/dsa/port.c1
-rw-r--r--net/ipv4/cipso_ipv4.c20
-rw-r--r--net/ipv4/fib_frontend.c4
-rw-r--r--net/ipv4/icmp.c7
-rw-r--r--net/ipv4/ip_input.c9
-rw-r--r--net/ipv4/ip_options.c22
-rw-r--r--net/ipv4/netlink.c17
-rw-r--r--net/ipv4/route.c2
-rw-r--r--net/ipv6/route.c7
-rw-r--r--net/ipv6/sit.c1
-rw-r--r--net/mpls/af_mpls.c3
-rw-r--r--net/netlabel/netlabel_kapi.c3
-rw-r--r--net/nfc/llcp_commands.c20
-rw-r--r--net/nfc/llcp_core.c24
-rw-r--r--net/sched/act_ipt.c3
-rw-r--r--net/sched/act_skbedit.c3
-rw-r--r--net/sched/act_tunnel_key.c3
-rw-r--r--net/sched/sch_netem.c10
-rw-r--r--net/sctp/chunk.c2
-rw-r--r--net/socket.c1
-rw-r--r--net/tipc/socket.c6
-rwxr-xr-xtools/testing/selftests/net/pmtu.sh96
-rwxr-xr-xtools/testing/selftests/net/udpgro.sh8
-rw-r--r--tools/testing/selftests/net/udpgso_bench_rx.c42
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
1163module_platform_driver(gswip_driver); 1163module_platform_driver(gswip_driver);
1164 1164
1165MODULE_FIRMWARE("lantiq/xrx300_phy11g_a21.bin");
1166MODULE_FIRMWARE("lantiq/xrx300_phy22f_a21.bin");
1167MODULE_FIRMWARE("lantiq/xrx200_phy11g_a14.bin");
1168MODULE_FIRMWARE("lantiq/xrx200_phy11g_a22.bin");
1169MODULE_FIRMWARE("lantiq/xrx200_phy22f_a14.bin");
1170MODULE_FIRMWARE("lantiq/xrx200_phy22f_a22.bin");
1165MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>"); 1171MODULE_AUTHOR("Hauke Mehrtens <hauke@hauke-m.de>");
1166MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver"); 1172MODULE_DESCRIPTION("Lantiq / Intel GSWIP driver");
1167MODULE_LICENSE("GPL v2"); 1173MODULE_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
4598static 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
4598static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds, 4606static 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
276static int hw_atl_b0_hw_init_tx_path(struct aq_hw_s *self) 276static 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
1277void 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
1277void hw_atl_tpb_tx_buff_hi_threshold_per_tc_set(struct aq_hw_s *aq_hw, 1286void 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 */
609void 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 */
609void hw_atl_tpb_tx_buff_en_set(struct aq_hw_s *aq_hw, u32 tx_buff_en); 613void 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");
1681MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>"); 1681MODULE_AUTHOR("Claudio Lanconelli <lanconelli.claudio@eptar.com>");
1682MODULE_LICENSE("GPL"); 1682MODULE_LICENSE("GPL");
1683module_param_named(debug, debug.msg_enable, int, 0); 1683module_param_named(debug, debug.msg_enable, int, 0);
1684MODULE_PARM_DESC(debug, "Debug verbosity level (0=none, ..., ffff=all)"); 1684MODULE_PARM_DESC(debug, "Debug verbosity level in amount of bits set (0=none, ..., 31=all)");
1685MODULE_ALIAS("spi:" DRV_NAME); 1685MODULE_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
1402static void lan743x_tx_frame_add_lso(struct lan743x_tx *tx, 1402static 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:
692static int geneve_open(struct net_device *dev) 692static 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
747static 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
747static struct sk_buff *netvsc_alloc_recv_skb(struct net_device *net, 755static 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
347static 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
347static int ksz9021_load_values_from_of(struct phy_device *phydev, 358static 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
2191out: 2191out:
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
3867static inline void __netif_tx_lock(struct netdev_queue *txq, int cpu) 3867static 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
26struct icmp_err { 27struct icmp_err {
27 int errno; 28 int errno;
@@ -39,7 +40,13 @@ struct net_proto_family;
39struct sk_buff; 40struct sk_buff;
40struct net; 41struct net;
41 42
42void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info); 43void __icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info,
44 const struct ip_options *opt);
45static 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
43int icmp_rcv(struct sk_buff *skb); 50int icmp_rcv(struct sk_buff *skb);
44int icmp_err(struct sk_buff *skb, u32 info); 51int icmp_err(struct sk_buff *skb, u32 info);
45int icmp_init(void); 52int 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
669void ip_options_fragment(struct sk_buff *skb); 669void ip_options_fragment(struct sk_buff *skb);
670int __ip_options_compile(struct net *net, struct ip_options *opt,
671 struct sk_buff *skb, __be32 *info);
670int ip_options_compile(struct net *net, struct ip_options *opt, 672int ip_options_compile(struct net *net, struct ip_options *opt,
671 struct sk_buff *skb); 673 struct sk_buff *skb);
672int ip_options_get(struct net *net, struct ip_options_rcu **optp, 674int ip_options_get(struct net *net, struct ip_options_rcu **optp,
@@ -716,7 +718,7 @@ extern int sysctl_icmp_msgs_burst;
716int ip_misc_proc_init(void); 718int ip_misc_proc_init(void);
717#endif 719#endif
718 720
719int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, 721int 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", &reg); 625 err = of_property_read_u32(port, "reg", &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; 641out_put_node:
642 of_node_put(ports);
643 return err;
640} 644}
641 645
642static int dsa_switch_parse_member_of(struct dsa_switch *ds, 646static 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 */
1736void cipso_v4_error(struct sk_buff *skb, int error, u32 gateway) 1737void 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
573void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) 573void __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();
743out:; 744out:;
744} 745}
745EXPORT_SYMBOL(icmp_send); 746EXPORT_SYMBOL(__icmp_send);
746 747
747 748
748static void icmp_socket_deliver(struct sk_buff *skb, u32 info) 749static 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
309static int ip_rcv_finish_core(struct net *net, struct sock *sk, 309static 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
401static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb) 400static 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
254int ip_options_compile(struct net *net, 254int __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
470error: 471error:
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
477int 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}
476EXPORT_SYMBOL(ip_options_compile); 488EXPORT_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
8int rtm_getroute_parse_ip_proto(struct nlattr *attr, u8 *ip_proto, 9int 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}
23EXPORT_SYMBOL_GPL(rtm_getroute_parse_ip_proto); 32EXPORT_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
1874err_reg_dev: 1874err_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);
1876err_alloc_dev: 1877err_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
533static int nfc_llcp_build_gb(struct nfc_llcp_local *local) 533static 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, &lto_length); 552 lto_tlv = nfc_llcp_build_tlv(LLCP_TLV_LTO, &local->lto, 1, &lto_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:
199err2: 199err2:
200 kfree(tname); 200 kfree(tname);
201err1: 201err1:
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
379release_tun_meta: 379release_tun_meta:
380 dst_release(&metadata->dst); 380 if (metadata)
381 dst_release(&metadata->dst);
381 382
382err_out: 383err_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.
108ksft_skip=4 117ksft_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
140NS_A="ns-$(mktemp -u XXXXXX)" 151NS_A="ns-$(mktemp -u XXXXXX)"
141NS_B="ns-$(mktemp -u XXXXXX)" 152NS_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
270setup_fou44() { 279setup_fou44() {
@@ -302,6 +311,10 @@ setup_gue66() {
302setup_namespaces() { 311setup_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
344setup_vti4() { 355setup_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
382setup_geneve4() { 391setup_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
1020check_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
1030test_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
1067test_cleanup_ipv6_exception() {
1068 test_cleanup_vxlanX_exception 6
1069}
1070
1071test_cleanup_ipv4_exception() {
1072 test_cleanup_vxlanX_exception 4
1073}
1074
1011usage() { 1075usage() {
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);
45static int cfg_expected_pkt_nr; 45static int cfg_expected_pkt_nr;
46static int cfg_expected_pkt_len; 46static int cfg_expected_pkt_len;
47static int cfg_expected_gso_size; 47static int cfg_expected_gso_size;
48static int cfg_connect_timeout_ms;
49static int cfg_rcv_timeout_ms;
48static struct sockaddr_storage cfg_bind_addr; 50static struct sockaddr_storage cfg_bind_addr;
49 51
50static bool interrupted; 52static 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
90static void do_poll(int fd) 92static 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
274static void usage(const char *filepath) 284static 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
279static void parse_opts(int argc, char **argv) 291static 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
330static void do_recv(void) 348static 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))