Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'net-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from Jakub Kicinski:
Previous releases - regressions:

- netlink: avoid infinite retry looping in netlink_unicast()

Previous releases - always broken:

- packet: fix a race in packet_set_ring() and packet_notifier()

- ipv6: reject malicious packets in ipv6_gso_segment()

- sched: mqprio: fix stack out-of-bounds write in tc entry parsing

- net: drop UFO packets (injected via virtio) in udp_rcv_segment()

- eth: mlx5: correctly set gso_segs when LRO is used, avoid false
positive checksum validation errors

- netpoll: prevent hanging NAPI when netcons gets enabled

- phy: mscc: fix parsing of unicast frames for PTP timestamping

- a number of device tree / OF reference leak fixes"

* tag 'net-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (44 commits)
pptp: fix pptp_xmit() error path
net: ti: icssg-prueth: Fix skb handling for XDP_PASS
net: Update threaded state in napi config in netif_set_threaded
selftests: netdevsim: Xfail nexthop test on slow machines
eth: fbnic: Lock the tx_dropped update
eth: fbnic: Fix tx_dropped reporting
eth: fbnic: remove the debugging trick of super high page bias
net: ftgmac100: fix potential NULL pointer access in ftgmac100_phy_disconnect
dt-bindings: net: Replace bouncing Alexandru Tachici emails
dpll: zl3073x: ZL3073X_I2C and ZL3073X_SPI should depend on NET
net/sched: mqprio: fix stack out-of-bounds write in tc entry parsing
Revert "net: mdio_bus: Use devm for getting reset GPIO"
selftests: net: packetdrill: xfail all problems on slow machines
net/packet: fix a race in packet_set_ring() and packet_notifier()
benet: fix BUG when creating VFs
net: airoha: npu: Add missing MODULE_FIRMWARE macros
net: devmem: fix DMA direction on unmapping
ipa: fix compile-testing with qcom-mdt=m
eth: fbnic: unlink NAPIs from queues on error to open
net: Add locking to protect skb->dev access in ip_output
...

+363 -138
+1 -1
Documentation/devicetree/bindings/net/adi,adin.yaml
··· 7 7 title: Analog Devices ADIN1200/ADIN1300 PHY 8 8 9 9 maintainers: 10 - - Alexandru Tachici <alexandru.tachici@analog.com> 10 + - Marcelo Schmitt <marcelo.schmitt@analog.com> 11 11 12 12 description: | 13 13 Bindings for Analog Devices Industrial Ethernet PHYs
+1 -1
Documentation/devicetree/bindings/net/adi,adin1110.yaml
··· 7 7 title: ADI ADIN1110 MAC-PHY 8 8 9 9 maintainers: 10 - - Alexandru Tachici <alexandru.tachici@analog.com> 10 + - Marcelo Schmitt <marcelo.schmitt@analog.com> 11 11 12 12 description: | 13 13 The ADIN1110 is a low power single port 10BASE-T1L MAC-
+3 -3
Documentation/netlink/specs/ethtool.yaml
··· 2344 2344 request: 2345 2345 attributes: 2346 2346 - header 2347 - reply: 2348 - attributes: 2349 - - header 2350 2347 - offset 2351 2348 - length 2352 2349 - page 2353 2350 - bank 2354 2351 - i2c-address 2352 + reply: 2353 + attributes: 2354 + - header 2355 2355 - data 2356 2356 dump: *module-eeprom-get-op 2357 2357 -
+5 -5
drivers/dpll/zl3073x/Kconfig
··· 1 1 # SPDX-License-Identifier: GPL-2.0-only 2 2 3 3 config ZL3073X 4 - tristate "Microchip Azurite DPLL/PTP/SyncE devices" 4 + tristate "Microchip Azurite DPLL/PTP/SyncE devices" if COMPILE_TEST 5 5 depends on NET 6 6 select DPLL 7 7 select NET_DEVLINK ··· 16 16 17 17 config ZL3073X_I2C 18 18 tristate "I2C bus implementation for Microchip Azurite devices" 19 - depends on I2C && ZL3073X 19 + depends on I2C && NET 20 20 select REGMAP_I2C 21 - default m 21 + select ZL3073X 22 22 help 23 23 This is I2C bus implementation for Microchip Azurite DPLL/PTP/SyncE 24 24 devices. ··· 28 28 29 29 config ZL3073X_SPI 30 30 tristate "SPI bus implementation for Microchip Azurite devices" 31 - depends on SPI && ZL3073X 31 + depends on NET && SPI 32 32 select REGMAP_SPI 33 - default m 33 + select ZL3073X 34 34 help 35 35 This is SPI bus implementation for Microchip Azurite DPLL/PTP/SyncE 36 36 devices.
+2
drivers/net/ethernet/airoha/airoha_npu.c
··· 579 579 }; 580 580 module_platform_driver(airoha_npu_driver); 581 581 582 + MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_DATA); 583 + MODULE_FIRMWARE(NPU_EN7581_FIRMWARE_RV32); 582 584 MODULE_LICENSE("GPL"); 583 585 MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); 584 586 MODULE_DESCRIPTION("Airoha Network Processor Unit driver");
+20 -6
drivers/net/ethernet/airoha/airoha_ppe.c
··· 508 508 FIELD_PREP(AIROHA_FOE_IB2_NBQ, nbq); 509 509 } 510 510 511 - struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, 512 - u32 hash) 511 + static struct airoha_foe_entry * 512 + airoha_ppe_foe_get_entry_locked(struct airoha_ppe *ppe, u32 hash) 513 513 { 514 + lockdep_assert_held(&ppe_lock); 515 + 514 516 if (hash < PPE_SRAM_NUM_ENTRIES) { 515 517 u32 *hwe = ppe->foe + hash * sizeof(struct airoha_foe_entry); 516 518 struct airoha_eth *eth = ppe->eth; ··· 537 535 } 538 536 539 537 return ppe->foe + hash * sizeof(struct airoha_foe_entry); 538 + } 539 + 540 + struct airoha_foe_entry *airoha_ppe_foe_get_entry(struct airoha_ppe *ppe, 541 + u32 hash) 542 + { 543 + struct airoha_foe_entry *hwe; 544 + 545 + spin_lock_bh(&ppe_lock); 546 + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); 547 + spin_unlock_bh(&ppe_lock); 548 + 549 + return hwe; 540 550 } 541 551 542 552 static bool airoha_ppe_foe_compare_entry(struct airoha_flow_table_entry *e, ··· 665 651 struct airoha_flow_table_entry *f; 666 652 int type; 667 653 668 - hwe_p = airoha_ppe_foe_get_entry(ppe, hash); 654 + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, hash); 669 655 if (!hwe_p) 670 656 return -EINVAL; 671 657 ··· 717 703 718 704 spin_lock_bh(&ppe_lock); 719 705 720 - hwe = airoha_ppe_foe_get_entry(ppe, hash); 706 + hwe = airoha_ppe_foe_get_entry_locked(ppe, hash); 721 707 if (!hwe) 722 708 goto unlock; 723 709 ··· 832 818 u32 ib1, state; 833 819 int idle; 834 820 835 - hwe = airoha_ppe_foe_get_entry(ppe, iter->hash); 821 + hwe = airoha_ppe_foe_get_entry_locked(ppe, iter->hash); 836 822 if (!hwe) 837 823 continue; 838 824 ··· 869 855 if (e->hash == 0xffff) 870 856 goto unlock; 871 857 872 - hwe_p = airoha_ppe_foe_get_entry(ppe, e->hash); 858 + hwe_p = airoha_ppe_foe_get_entry_locked(ppe, e->hash); 873 859 if (!hwe_p) 874 860 goto unlock; 875 861
+1 -1
drivers/net/ethernet/emulex/benet/be_cmds.c
··· 3856 3856 status = be_mcc_notify_wait(adapter); 3857 3857 3858 3858 err: 3859 - dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); 3860 3859 spin_unlock_bh(&adapter->mcc_lock); 3860 + dma_free_coherent(&adapter->pdev->dev, cmd.size, cmd.va, cmd.dma); 3861 3861 return status; 3862 3862 } 3863 3863
+4 -3
drivers/net/ethernet/faraday/ftgmac100.c
··· 1750 1750 static void ftgmac100_phy_disconnect(struct net_device *netdev) 1751 1751 { 1752 1752 struct ftgmac100 *priv = netdev_priv(netdev); 1753 + struct phy_device *phydev = netdev->phydev; 1753 1754 1754 - if (!netdev->phydev) 1755 + if (!phydev) 1755 1756 return; 1756 1757 1757 - phy_disconnect(netdev->phydev); 1758 + phy_disconnect(phydev); 1758 1759 if (of_phy_is_fixed_link(priv->dev->of_node)) 1759 1760 of_phy_deregister_fixed_link(priv->dev->of_node); 1760 1761 1761 1762 if (priv->use_ncsi) 1762 - fixed_phy_unregister(netdev->phydev); 1763 + fixed_phy_unregister(phydev); 1763 1764 } 1764 1765 1765 1766 static void ftgmac100_destroy_mdio(struct net_device *netdev)
+3 -1
drivers/net/ethernet/freescale/dpaa/dpaa_ethtool.c
··· 371 371 of_node_put(ptp_node); 372 372 } 373 373 374 - if (ptp_dev) 374 + if (ptp_dev) { 375 375 ptp = platform_get_drvdata(ptp_dev); 376 + put_device(&ptp_dev->dev); 377 + } 376 378 377 379 if (ptp) 378 380 info->phc_index = ptp->phc_index;
+12 -2
drivers/net/ethernet/freescale/enetc/enetc_pf.c
··· 829 829 { 830 830 struct platform_device *ierb_pdev; 831 831 struct device_node *ierb_node; 832 + int ret; 832 833 833 834 ierb_node = of_find_compatible_node(NULL, NULL, 834 835 "fsl,ls1028a-enetc-ierb"); 835 - if (!ierb_node || !of_device_is_available(ierb_node)) 836 + if (!ierb_node) 836 837 return -ENODEV; 838 + 839 + if (!of_device_is_available(ierb_node)) { 840 + of_node_put(ierb_node); 841 + return -ENODEV; 842 + } 837 843 838 844 ierb_pdev = of_find_device_by_node(ierb_node); 839 845 of_node_put(ierb_node); ··· 847 841 if (!ierb_pdev) 848 842 return -EPROBE_DEFER; 849 843 850 - return enetc_ierb_register_pf(ierb_pdev, pdev); 844 + ret = enetc_ierb_register_pf(ierb_pdev, pdev); 845 + 846 + put_device(&ierb_pdev->dev); 847 + 848 + return ret; 851 849 } 852 850 853 851 static const struct enetc_si_ops enetc_psi_ops = {
+3 -1
drivers/net/ethernet/freescale/gianfar_ethtool.c
··· 1475 1475 if (ptp_node) { 1476 1476 ptp_dev = of_find_device_by_node(ptp_node); 1477 1477 of_node_put(ptp_node); 1478 - if (ptp_dev) 1478 + if (ptp_dev) { 1479 1479 ptp = platform_get_drvdata(ptp_dev); 1480 + put_device(&ptp_dev->dev); 1481 + } 1480 1482 } 1481 1483 1482 1484 if (ptp)
-1
drivers/net/ethernet/mediatek/mtk_wed.c
··· 2782 2782 if (!pdev) 2783 2783 goto err_of_node_put; 2784 2784 2785 - get_device(&pdev->dev); 2786 2785 irq = platform_get_irq(pdev, 0); 2787 2786 if (irq < 0) 2788 2787 goto err_put_device;
+1
drivers/net/ethernet/mellanox/mlx5/core/en_rx.c
··· 1574 1574 unsigned int hdrlen = mlx5e_lro_update_hdr(skb, cqe, cqe_bcnt); 1575 1575 1576 1576 skb_shinfo(skb)->gso_size = DIV_ROUND_UP(cqe_bcnt - hdrlen, lro_num_seg); 1577 + skb_shinfo(skb)->gso_segs = lro_num_seg; 1577 1578 /* Subtract one since we already counted this as one 1578 1579 * "regular" packet in mlx5e_complete_rx_cqe() 1579 1580 */
+9 -5
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
··· 33 33 dev_warn(fbd->dev, 34 34 "Error %d sending host ownership message to the firmware\n", 35 35 err); 36 - goto free_resources; 36 + goto err_reset_queues; 37 37 } 38 38 39 39 err = fbnic_time_start(fbn); ··· 57 57 fbnic_time_stop(fbn); 58 58 release_ownership: 59 59 fbnic_fw_xmit_ownership_msg(fbn->fbd, false); 60 + err_reset_queues: 61 + fbnic_reset_netif_queues(fbn); 60 62 free_resources: 61 63 fbnic_free_resources(fbn); 62 64 free_napi_vectors: ··· 422 420 tx_packets = stats->packets; 423 421 tx_dropped = stats->dropped; 424 422 425 - stats64->tx_bytes = tx_bytes; 426 - stats64->tx_packets = tx_packets; 427 - stats64->tx_dropped = tx_dropped; 428 - 429 423 /* Record drops from Tx HW Datapath */ 424 + spin_lock(&fbd->hw_stats_lock); 430 425 tx_dropped += fbd->hw_stats.tmi.drop.frames.value + 431 426 fbd->hw_stats.tti.cm_drop.frames.value + 432 427 fbd->hw_stats.tti.frame_drop.frames.value + 433 428 fbd->hw_stats.tti.tbi_drop.frames.value; 429 + spin_unlock(&fbd->hw_stats_lock); 430 + 431 + stats64->tx_bytes = tx_bytes; 432 + stats64->tx_packets = tx_packets; 433 + stats64->tx_dropped = tx_dropped; 434 434 435 435 for (i = 0; i < fbn->num_tx_queues; i++) { 436 436 struct fbnic_ring *txr = fbn->tx[i];
+2 -2
drivers/net/ethernet/meta/fbnic/fbnic_txrx.c
··· 661 661 { 662 662 struct fbnic_rx_buf *rx_buf = &ring->rx_buf[idx]; 663 663 664 - page_pool_fragment_page(page, PAGECNT_BIAS_MAX); 665 - rx_buf->pagecnt_bias = PAGECNT_BIAS_MAX; 664 + page_pool_fragment_page(page, FBNIC_PAGECNT_BIAS_MAX); 665 + rx_buf->pagecnt_bias = FBNIC_PAGECNT_BIAS_MAX; 666 666 rx_buf->page = page; 667 667 } 668 668
+2 -4
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h
··· 91 91 struct u64_stats_sync syncp; 92 92 }; 93 93 94 - /* Pagecnt bias is long max to reserve the last bit to catch overflow 95 - * cases where if we overcharge the bias it will flip over to be negative. 96 - */ 97 - #define PAGECNT_BIAS_MAX LONG_MAX 94 + #define FBNIC_PAGECNT_BIAS_MAX PAGE_SIZE 95 + 98 96 struct fbnic_rx_buf { 99 97 struct page *page; 100 98 long pagecnt_bias;
+1 -1
drivers/net/ethernet/sfc/tc_encap_actions.c
··· 442 442 rule = container_of(acts, struct efx_tc_flow_rule, acts); 443 443 if (rule->fallback) 444 444 fallback = rule->fallback; 445 - else /* fallback: deliver to PF */ 445 + else /* fallback of the fallback: deliver to PF */ 446 446 fallback = &efx->tc->facts.pf; 447 447 rc = efx_mae_update_rule(efx, fallback->fw_id, 448 448 rule->fw_id);
+18 -5
drivers/net/ethernet/ti/icssg/icss_iep.c
··· 685 685 struct platform_device *pdev; 686 686 struct device_node *iep_np; 687 687 struct icss_iep *iep; 688 + int ret; 688 689 689 690 iep_np = of_parse_phandle(np, "ti,iep", idx); 690 - if (!iep_np || !of_device_is_available(iep_np)) 691 + if (!iep_np) 691 692 return ERR_PTR(-ENODEV); 693 + 694 + if (!of_device_is_available(iep_np)) { 695 + of_node_put(iep_np); 696 + return ERR_PTR(-ENODEV); 697 + } 692 698 693 699 pdev = of_find_device_by_node(iep_np); 694 700 of_node_put(iep_np); ··· 704 698 return ERR_PTR(-EPROBE_DEFER); 705 699 706 700 iep = platform_get_drvdata(pdev); 707 - if (!iep) 708 - return ERR_PTR(-EPROBE_DEFER); 701 + if (!iep) { 702 + ret = -EPROBE_DEFER; 703 + goto err_put_pdev; 704 + } 709 705 710 706 device_lock(iep->dev); 711 707 if (iep->client_np) { 712 708 device_unlock(iep->dev); 713 709 dev_err(iep->dev, "IEP is already acquired by %s", 714 710 iep->client_np->name); 715 - return ERR_PTR(-EBUSY); 711 + ret = -EBUSY; 712 + goto err_put_pdev; 716 713 } 717 714 iep->client_np = np; 718 715 device_unlock(iep->dev); 719 - get_device(iep->dev); 720 716 721 717 return iep; 718 + 719 + err_put_pdev: 720 + put_device(&pdev->dev); 721 + 722 + return ERR_PTR(ret); 722 723 } 723 724 EXPORT_SYMBOL_GPL(icss_iep_get_idx); 724 725
+8 -7
drivers/net/ethernet/ti/icssg/icssg_common.c
··· 706 706 struct page_pool *pool; 707 707 struct sk_buff *skb; 708 708 struct xdp_buff xdp; 709 + int headroom, ret; 709 710 u32 *psdata; 710 711 void *pa; 711 - int ret; 712 712 713 713 *xdp_state = 0; 714 714 pool = rx_chn->pg_pool; ··· 757 757 xdp_prepare_buff(&xdp, pa, PRUETH_HEADROOM, pkt_len, false); 758 758 759 759 *xdp_state = emac_run_xdp(emac, &xdp, page, &pkt_len); 760 - if (*xdp_state == ICSSG_XDP_PASS) 761 - skb = xdp_build_skb_from_buff(&xdp); 762 - else 760 + if (*xdp_state != ICSSG_XDP_PASS) 763 761 goto requeue; 762 + headroom = xdp.data - xdp.data_hard_start; 763 + pkt_len = xdp.data_end - xdp.data; 764 764 } else { 765 - /* prepare skb and send to n/w stack */ 766 - skb = napi_build_skb(pa, PAGE_SIZE); 765 + headroom = PRUETH_HEADROOM; 767 766 } 768 767 768 + /* prepare skb and send to n/w stack */ 769 + skb = napi_build_skb(pa, PAGE_SIZE); 769 770 if (!skb) { 770 771 ndev->stats.rx_dropped++; 771 772 page_pool_recycle_direct(pool, page); 772 773 goto requeue; 773 774 } 774 775 775 - skb_reserve(skb, PRUETH_HEADROOM); 776 + skb_reserve(skb, headroom); 776 777 skb_put(skb, pkt_len); 777 778 skb->dev = ndev; 778 779
+1 -1
drivers/net/ipa/Kconfig
··· 5 5 depends on INTERCONNECT 6 6 depends on QCOM_RPROC_COMMON || (QCOM_RPROC_COMMON=n && COMPILE_TEST) 7 7 depends on QCOM_AOSS_QMP || QCOM_AOSS_QMP=n 8 - select QCOM_MDT_LOADER if ARCH_QCOM 8 + select QCOM_MDT_LOADER 9 9 select QCOM_SCM 10 10 select QCOM_QMI_HELPERS 11 11 help
+5 -1
drivers/net/ipa/ipa_sysfs.c
··· 37 37 return "4.11"; 38 38 case IPA_VERSION_5_0: 39 39 return "5.0"; 40 + case IPA_VERSION_5_1: 41 + return "5.1"; 42 + case IPA_VERSION_5_5: 43 + return "5.5"; 40 44 default: 41 - return "0.0"; /* Won't happen (checked at probe time) */ 45 + return "0.0"; /* Should not happen */ 42 46 } 43 47 } 44 48
+2 -3
drivers/net/mdio/mdio-bcm-unimac.c
··· 209 209 if (ret) 210 210 return ret; 211 211 212 - if (!priv->clk) 212 + rate = clk_get_rate(priv->clk); 213 + if (!rate) 213 214 rate = 250000000; 214 - else 215 - rate = clk_get_rate(priv->clk); 216 215 217 216 div = (rate / (2 * priv->clk_freq)) - 1; 218 217 if (div & ~MDIO_CLK_DIV_MASK) {
+1
drivers/net/phy/mscc/mscc_ptp.c
··· 900 900 get_unaligned_be32(ptp_multicast)); 901 901 } else { 902 902 val |= ANA_ETH1_FLOW_ADDR_MATCH2_ANY_MULTICAST; 903 + val |= ANA_ETH1_FLOW_ADDR_MATCH2_ANY_UNICAST; 903 904 vsc85xx_ts_write_csr(phydev, blk, 904 905 MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(0), val); 905 906 vsc85xx_ts_write_csr(phydev, blk,
+1
drivers/net/phy/mscc/mscc_ptp.h
··· 98 98 #define MSCC_ANA_ETH1_FLOW_ADDR_MATCH2(x) (MSCC_ANA_ETH1_FLOW_ENA(x) + 3) 99 99 #define ANA_ETH1_FLOW_ADDR_MATCH2_MASK_MASK GENMASK(22, 20) 100 100 #define ANA_ETH1_FLOW_ADDR_MATCH2_ANY_MULTICAST 0x400000 101 + #define ANA_ETH1_FLOW_ADDR_MATCH2_ANY_UNICAST 0x200000 101 102 #define ANA_ETH1_FLOW_ADDR_MATCH2_FULL_ADDR 0x100000 102 103 #define ANA_ETH1_FLOW_ADDR_MATCH2_SRC_DEST_MASK GENMASK(17, 16) 103 104 #define ANA_ETH1_FLOW_ADDR_MATCH2_SRC_DEST 0x020000
+1
drivers/net/phy/smsc.c
··· 785 785 786 786 /* PHY_BASIC_FEATURES */ 787 787 788 + .flags = PHY_RST_AFTER_CLK_EN, 788 789 .probe = smsc_phy_probe, 789 790 790 791 /* basic functions */
+11 -7
drivers/net/ppp/pptp.c
··· 159 159 int len; 160 160 unsigned char *data; 161 161 __u32 seq_recv; 162 - 163 - 164 162 struct rtable *rt; 165 163 struct net_device *tdev; 166 164 struct iphdr *iph; 167 165 int max_headroom; 168 166 169 167 if (sk_pppox(po)->sk_state & PPPOX_DEAD) 170 - goto tx_error; 168 + goto tx_drop; 171 169 172 170 rt = pptp_route_output(po, &fl4); 173 171 if (IS_ERR(rt)) 174 - goto tx_error; 172 + goto tx_drop; 175 173 176 174 tdev = rt->dst.dev; 177 175 ··· 177 179 178 180 if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) { 179 181 struct sk_buff *new_skb = skb_realloc_headroom(skb, max_headroom); 180 - if (!new_skb) { 181 - ip_rt_put(rt); 182 + 183 + if (!new_skb) 182 184 goto tx_error; 183 - } 185 + 184 186 if (skb->sk) 185 187 skb_set_owner_w(new_skb, skb->sk); 186 188 consume_skb(skb); 187 189 skb = new_skb; 188 190 } 191 + 192 + /* Ensure we can safely access protocol field and LCP code */ 193 + if (!pskb_may_pull(skb, 3)) 194 + goto tx_error; 189 195 190 196 data = skb->data; 191 197 islcp = ((data[0] << 8) + data[1]) == PPP_LCP && 1 <= data[2] && data[2] <= 7; ··· 264 262 return 1; 265 263 266 264 tx_error: 265 + ip_rt_put(rt); 266 + tx_drop: 267 267 kfree_skb(skb); 268 268 return 1; 269 269 }
+23
include/linux/skbuff.h
··· 3033 3033 skb->transport_header = offset; 3034 3034 } 3035 3035 3036 + /** 3037 + * skb_reset_transport_header_careful - conditionally reset transport header 3038 + * @skb: buffer to alter 3039 + * 3040 + * Hardened version of skb_reset_transport_header(). 3041 + * 3042 + * Returns: true if the operation was a success. 3043 + */ 3044 + static inline bool __must_check 3045 + skb_reset_transport_header_careful(struct sk_buff *skb) 3046 + { 3047 + long offset = skb->data - skb->head; 3048 + 3049 + if (unlikely(offset != (typeof(skb->transport_header))offset)) 3050 + return false; 3051 + 3052 + if (unlikely(offset == (typeof(skb->transport_header))~0U)) 3053 + return false; 3054 + 3055 + skb->transport_header = offset; 3056 + return true; 3057 + } 3058 + 3036 3059 static inline void skb_set_transport_header(struct sk_buff *skb, 3037 3060 const int offset) 3038 3061 {
+12
include/net/dst.h
··· 568 568 return READ_ONCE(dst->dev); 569 569 } 570 570 571 + static inline struct net_device *dst_dev_rcu(const struct dst_entry *dst) 572 + { 573 + /* In the future, use rcu_dereference(dst->dev) */ 574 + WARN_ON_ONCE(!rcu_read_lock_held()); 575 + return READ_ONCE(dst->dev); 576 + } 577 + 571 578 static inline struct net_device *skb_dst_dev(const struct sk_buff *skb) 572 579 { 573 580 return dst_dev(skb_dst(skb)); 581 + } 582 + 583 + static inline struct net_device *skb_dst_dev_rcu(const struct sk_buff *skb) 584 + { 585 + return dst_dev_rcu(skb_dst(skb)); 574 586 } 575 587 576 588 static inline struct net *skb_dst_dev_net(const struct sk_buff *skb)
+18 -6
include/net/udp.h
··· 586 586 { 587 587 netdev_features_t features = NETIF_F_SG; 588 588 struct sk_buff *segs; 589 + int drop_count; 590 + 591 + /* 592 + * Segmentation in UDP receive path is only for UDP GRO, drop udp 593 + * fragmentation offload (UFO) packets. 594 + */ 595 + if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) { 596 + drop_count = 1; 597 + goto drop; 598 + } 589 599 590 600 /* Avoid csum recalculation by skb_segment unless userspace explicitly 591 601 * asks for the final checksum values ··· 619 609 */ 620 610 segs = __skb_gso_segment(skb, features, false); 621 611 if (IS_ERR_OR_NULL(segs)) { 622 - int segs_nr = skb_shinfo(skb)->gso_segs; 623 - 624 - atomic_add(segs_nr, &sk->sk_drops); 625 - SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, segs_nr); 626 - kfree_skb(skb); 627 - return NULL; 612 + drop_count = skb_shinfo(skb)->gso_segs; 613 + goto drop; 628 614 } 629 615 630 616 consume_skb(skb); 631 617 return segs; 618 + 619 + drop: 620 + atomic_add(drop_count, &sk->sk_drops); 621 + SNMP_ADD_STATS(__UDPX_MIB(sk, ipv4), UDP_MIB_INERRORS, drop_count); 622 + kfree_skb(skb); 623 + return NULL; 632 624 } 633 625 634 626 static inline void udp_post_segment_fix_csum(struct sk_buff *skb)
+9 -17
net/core/dev.c
··· 6978 6978 if (napi->config) 6979 6979 napi->config->threaded = threaded; 6980 6980 6981 + /* Setting/unsetting threaded mode on a napi might not immediately 6982 + * take effect, if the current napi instance is actively being 6983 + * polled. In this case, the switch between threaded mode and 6984 + * softirq mode will happen in the next round of napi_schedule(). 6985 + * This should not cause hiccups/stalls to the live traffic. 6986 + */ 6981 6987 if (!threaded && napi->thread) { 6982 6988 napi_stop_kthread(napi); 6983 6989 } else { ··· 7017 7011 7018 7012 WRITE_ONCE(dev->threaded, threaded); 7019 7013 7020 - /* Make sure kthread is created before THREADED bit 7021 - * is set. 7022 - */ 7023 - smp_mb__before_atomic(); 7024 - 7025 - /* Setting/unsetting threaded mode on a napi might not immediately 7026 - * take effect, if the current napi instance is actively being 7027 - * polled. In this case, the switch between threaded mode and 7028 - * softirq mode will happen in the next round of napi_schedule(). 7029 - * This should not cause hiccups/stalls to the live traffic. 7030 - */ 7031 - list_for_each_entry(napi, &dev->napi_list, dev_list) { 7032 - if (!threaded && napi->thread) 7033 - napi_stop_kthread(napi); 7034 - else 7035 - assign_bit(NAPI_STATE_THREADED, &napi->state, threaded); 7036 - } 7014 + /* The error should not occur as the kthreads are already created. */ 7015 + list_for_each_entry(napi, &dev->napi_list, dev_list) 7016 + WARN_ON_ONCE(napi_set_threaded(napi, threaded)); 7037 7017 7038 7018 return err; 7039 7019 }
+3 -3
net/core/devmem.c
··· 70 70 gen_pool_destroy(binding->chunk_pool); 71 71 72 72 dma_buf_unmap_attachment_unlocked(binding->attachment, binding->sgt, 73 - DMA_FROM_DEVICE); 73 + binding->direction); 74 74 dma_buf_detach(binding->dmabuf, binding->attachment); 75 75 dma_buf_put(binding->dmabuf); 76 76 xa_destroy(&binding->bound_rxqs); 77 77 kvfree(binding->tx_vec); 78 78 kfree(binding); 79 79 } 80 - EXPORT_SYMBOL(__net_devmem_dmabuf_binding_free); 81 80 82 81 struct net_iov * 83 82 net_devmem_alloc_dmabuf(struct net_devmem_dmabuf_binding *binding) ··· 207 208 mutex_init(&binding->lock); 208 209 209 210 binding->dmabuf = dmabuf; 211 + binding->direction = direction; 210 212 211 213 binding->attachment = dma_buf_attach(binding->dmabuf, dev->dev.parent); 212 214 if (IS_ERR(binding->attachment)) { ··· 312 312 kvfree(binding->tx_vec); 313 313 err_unmap: 314 314 dma_buf_unmap_attachment_unlocked(binding->attachment, binding->sgt, 315 - DMA_FROM_DEVICE); 315 + direction); 316 316 err_detach: 317 317 dma_buf_detach(dmabuf, binding->attachment); 318 318 err_free_binding:
+3 -4
net/core/devmem.h
··· 56 56 */ 57 57 u32 id; 58 58 59 + /* DMA direction, FROM_DEVICE for Rx binding, TO_DEVICE for Tx. */ 60 + enum dma_data_direction direction; 61 + 59 62 /* Array of net_iov pointers for this binding, sorted by virtual 60 63 * address. This array is convenient to map the virtual addresses to 61 64 * net_iovs in the TX path. ··· 165 162 } 166 163 167 164 static inline void net_devmem_put_net_iov(struct net_iov *niov) 168 - { 169 - } 170 - 171 - static inline void __net_devmem_dmabuf_binding_free(struct work_struct *wq) 172 165 { 173 166 } 174 167
+7
net/core/netpoll.c
··· 768 768 if (err) 769 769 goto flush; 770 770 rtnl_unlock(); 771 + 772 + /* Make sure all NAPI polls which started before dev->npinfo 773 + * was visible have exited before we start calling NAPI poll. 774 + * NAPI skips locking if dev->npinfo is NULL. 775 + */ 776 + synchronize_rcu(); 777 + 771 778 return 0; 772 779 773 780 flush:
+10 -5
net/ipv4/ip_output.c
··· 425 425 426 426 int ip_output(struct net *net, struct sock *sk, struct sk_buff *skb) 427 427 { 428 - struct net_device *dev = skb_dst_dev(skb), *indev = skb->dev; 428 + struct net_device *dev, *indev = skb->dev; 429 + int ret_val; 429 430 431 + rcu_read_lock(); 432 + dev = skb_dst_dev_rcu(skb); 430 433 skb->dev = dev; 431 434 skb->protocol = htons(ETH_P_IP); 432 435 433 - return NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, 434 - net, sk, skb, indev, dev, 435 - ip_finish_output, 436 - !(IPCB(skb)->flags & IPSKB_REROUTED)); 436 + ret_val = NF_HOOK_COND(NFPROTO_IPV4, NF_INET_POST_ROUTING, 437 + net, sk, skb, indev, dev, 438 + ip_finish_output, 439 + !(IPCB(skb)->flags & IPSKB_REROUTED)); 440 + rcu_read_unlock(); 441 + return ret_val; 437 442 } 438 443 EXPORT_SYMBOL(ip_output); 439 444
+3 -1
net/ipv6/ip6_offload.c
··· 148 148 149 149 ops = rcu_dereference(inet6_offloads[proto]); 150 150 if (likely(ops && ops->callbacks.gso_segment)) { 151 - skb_reset_transport_header(skb); 151 + if (!skb_reset_transport_header_careful(skb)) 152 + goto out; 153 + 152 154 segs = ops->callbacks.gso_segment(skb, features); 153 155 if (!segs) 154 156 skb->network_header = skb_mac_header(skb) + nhoff - skb->head;
+6
net/kcm/kcmsock.c
··· 19 19 #include <linux/rculist.h> 20 20 #include <linux/skbuff.h> 21 21 #include <linux/socket.h> 22 + #include <linux/splice.h> 22 23 #include <linux/uaccess.h> 23 24 #include <linux/workqueue.h> 24 25 #include <linux/syscalls.h> ··· 1029 1028 int err = 0; 1030 1029 ssize_t copied; 1031 1030 struct sk_buff *skb; 1031 + 1032 + if (sock->file->f_flags & O_NONBLOCK || flags & SPLICE_F_NONBLOCK) 1033 + flags = MSG_DONTWAIT; 1034 + else 1035 + flags = 0; 1032 1036 1033 1037 /* Only support splice for SOCKSEQPACKET */ 1034 1038
+1 -1
net/netlink/af_netlink.c
··· 1218 1218 nlk = nlk_sk(sk); 1219 1219 rmem = atomic_add_return(skb->truesize, &sk->sk_rmem_alloc); 1220 1220 1221 - if ((rmem == skb->truesize || rmem < READ_ONCE(sk->sk_rcvbuf)) && 1221 + if ((rmem == skb->truesize || rmem <= READ_ONCE(sk->sk_rcvbuf)) && 1222 1222 !test_bit(NETLINK_S_CONGESTED, &nlk->state)) { 1223 1223 netlink_skb_set_owner_r(skb, sk); 1224 1224 return 0;
+6 -6
net/packet/af_packet.c
··· 4573 4573 spin_lock(&po->bind_lock); 4574 4574 was_running = packet_sock_flag(po, PACKET_SOCK_RUNNING); 4575 4575 num = po->num; 4576 - if (was_running) { 4577 - WRITE_ONCE(po->num, 0); 4576 + WRITE_ONCE(po->num, 0); 4577 + if (was_running) 4578 4578 __unregister_prot_hook(sk, false); 4579 - } 4579 + 4580 4580 spin_unlock(&po->bind_lock); 4581 4581 4582 4582 synchronize_net(); ··· 4608 4608 mutex_unlock(&po->pg_vec_lock); 4609 4609 4610 4610 spin_lock(&po->bind_lock); 4611 - if (was_running) { 4612 - WRITE_ONCE(po->num, num); 4611 + WRITE_ONCE(po->num, num); 4612 + if (was_running) 4613 4613 register_prot_hook(sk); 4614 - } 4614 + 4615 4615 spin_unlock(&po->bind_lock); 4616 4616 if (pg_vec && (po->tp_version > TPACKET_V2)) { 4617 4617 /* Because we don't support block-based V3 on tx-ring */
+1 -1
net/sched/sch_mqprio.c
··· 152 152 static const struct 153 153 nla_policy mqprio_tc_entry_policy[TCA_MQPRIO_TC_ENTRY_MAX + 1] = { 154 154 [TCA_MQPRIO_TC_ENTRY_INDEX] = NLA_POLICY_MAX(NLA_U32, 155 - TC_QOPT_MAX_QUEUE), 155 + TC_QOPT_MAX_QUEUE - 1), 156 156 [TCA_MQPRIO_TC_ENTRY_FP] = NLA_POLICY_RANGE(NLA_U32, 157 157 TC_FP_EXPRESS, 158 158 TC_FP_PREEMPTIBLE),
+18 -3
net/sched/sch_taprio.c
··· 43 43 #define TAPRIO_SUPPORTED_FLAGS \ 44 44 (TCA_TAPRIO_ATTR_FLAG_TXTIME_ASSIST | TCA_TAPRIO_ATTR_FLAG_FULL_OFFLOAD) 45 45 #define TAPRIO_FLAGS_INVALID U32_MAX 46 + /* Minimum value for picos_per_byte to ensure non-zero duration 47 + * for minimum-sized Ethernet frames (ETH_ZLEN = 60). 48 + * 60 * 17 > PSEC_PER_NSEC (1000) 49 + */ 50 + #define TAPRIO_PICOS_PER_BYTE_MIN 17 46 51 47 52 struct sched_entry { 48 53 /* Durations between this GCL entry and the GCL entry where the ··· 1289 1284 } 1290 1285 1291 1286 static void taprio_set_picos_per_byte(struct net_device *dev, 1292 - struct taprio_sched *q) 1287 + struct taprio_sched *q, 1288 + struct netlink_ext_ack *extack) 1293 1289 { 1294 1290 struct ethtool_link_ksettings ecmd; 1295 1291 int speed = SPEED_10; ··· 1306 1300 1307 1301 skip: 1308 1302 picos_per_byte = (USEC_PER_SEC * 8) / speed; 1303 + if (picos_per_byte < TAPRIO_PICOS_PER_BYTE_MIN) { 1304 + if (!extack) 1305 + pr_warn("Link speed %d is too high. Schedule may be inaccurate.\n", 1306 + speed); 1307 + NL_SET_ERR_MSG_FMT_MOD(extack, 1308 + "Link speed %d is too high. Schedule may be inaccurate.", 1309 + speed); 1310 + picos_per_byte = TAPRIO_PICOS_PER_BYTE_MIN; 1311 + } 1309 1312 1310 1313 atomic64_set(&q->picos_per_byte, picos_per_byte); 1311 1314 netdev_dbg(dev, "taprio: set %s's picos_per_byte to: %lld, linkspeed: %d\n", ··· 1339 1324 if (dev != qdisc_dev(q->root)) 1340 1325 continue; 1341 1326 1342 - taprio_set_picos_per_byte(dev, q); 1327 + taprio_set_picos_per_byte(dev, q, NULL); 1343 1328 1344 1329 stab = rtnl_dereference(q->root->stab); 1345 1330 ··· 1859 1844 q->flags = taprio_flags; 1860 1845 1861 1846 /* Needed for length_to_duration() during netlink attribute parsing */ 1862 - taprio_set_picos_per_byte(dev, q); 1847 + taprio_set_picos_per_byte(dev, q, extack); 1863 1848 1864 1849 err = taprio_parse_mqprio_opt(dev, mqprio, extack, q->flags); 1865 1850 if (err < 0)
+1
tools/testing/selftests/drivers/net/Makefile
··· 11 11 12 12 TEST_PROGS := \ 13 13 napi_id.py \ 14 + napi_threaded.py \ 14 15 netcons_basic.sh \ 15 16 netcons_cmdline.sh \ 16 17 netcons_fragmented_msg.sh \
+111
tools/testing/selftests/drivers/net/napi_threaded.py
··· 1 + #!/usr/bin/env python3 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + """ 5 + Test napi threaded states. 6 + """ 7 + 8 + from lib.py import ksft_run, ksft_exit 9 + from lib.py import ksft_eq, ksft_ne, ksft_ge 10 + from lib.py import NetDrvEnv, NetdevFamily 11 + from lib.py import cmd, defer, ethtool 12 + 13 + 14 + def _assert_napi_threaded_enabled(nl, napi_id) -> None: 15 + napi = nl.napi_get({'id': napi_id}) 16 + ksft_eq(napi['threaded'], 'enabled') 17 + ksft_ne(napi.get('pid'), None) 18 + 19 + 20 + def _assert_napi_threaded_disabled(nl, napi_id) -> None: 21 + napi = nl.napi_get({'id': napi_id}) 22 + ksft_eq(napi['threaded'], 'disabled') 23 + ksft_eq(napi.get('pid'), None) 24 + 25 + 26 + def _set_threaded_state(cfg, threaded) -> None: 27 + cmd(f"echo {threaded} > /sys/class/net/{cfg.ifname}/threaded") 28 + 29 + 30 + def _setup_deferred_cleanup(cfg) -> None: 31 + combined = ethtool(f"-l {cfg.ifname}", json=True)[0].get("combined", 0) 32 + ksft_ge(combined, 2) 33 + defer(ethtool, f"-L {cfg.ifname} combined {combined}") 34 + 35 + threaded = cmd(f"cat /sys/class/net/{cfg.ifname}/threaded").stdout 36 + defer(_set_threaded_state, cfg, threaded) 37 + 38 + 39 + def enable_dev_threaded_disable_napi_threaded(cfg, nl) -> None: 40 + """ 41 + Test that when napi threaded is enabled at device level and 42 + then disabled at napi level for one napi, the threaded state 43 + of all napis is preserved after a change in number of queues. 44 + """ 45 + 46 + napis = nl.napi_get({'ifindex': cfg.ifindex}, dump=True) 47 + ksft_ge(len(napis), 2) 48 + 49 + napi0_id = napis[0]['id'] 50 + napi1_id = napis[1]['id'] 51 + 52 + _setup_deferred_cleanup(cfg) 53 + 54 + # set threaded 55 + _set_threaded_state(cfg, 1) 56 + 57 + # check napi threaded is set for both napis 58 + _assert_napi_threaded_enabled(nl, napi0_id) 59 + _assert_napi_threaded_enabled(nl, napi1_id) 60 + 61 + # disable threaded for napi1 62 + nl.napi_set({'id': napi1_id, 'threaded': 'disabled'}) 63 + 64 + cmd(f"ethtool -L {cfg.ifname} combined 1") 65 + cmd(f"ethtool -L {cfg.ifname} combined 2") 66 + _assert_napi_threaded_enabled(nl, napi0_id) 67 + _assert_napi_threaded_disabled(nl, napi1_id) 68 + 69 + 70 + def change_num_queues(cfg, nl) -> None: 71 + """ 72 + Test that when napi threaded is enabled at device level, 73 + the napi threaded state is preserved after a change in 74 + number of queues. 75 + """ 76 + 77 + napis = nl.napi_get({'ifindex': cfg.ifindex}, dump=True) 78 + ksft_ge(len(napis), 2) 79 + 80 + napi0_id = napis[0]['id'] 81 + napi1_id = napis[1]['id'] 82 + 83 + _setup_deferred_cleanup(cfg) 84 + 85 + # set threaded 86 + _set_threaded_state(cfg, 1) 87 + 88 + # check napi threaded is set for both napis 89 + _assert_napi_threaded_enabled(nl, napi0_id) 90 + _assert_napi_threaded_enabled(nl, napi1_id) 91 + 92 + cmd(f"ethtool -L {cfg.ifname} combined 1") 93 + cmd(f"ethtool -L {cfg.ifname} combined 2") 94 + 95 + # check napi threaded is set for both napis 96 + _assert_napi_threaded_enabled(nl, napi0_id) 97 + _assert_napi_threaded_enabled(nl, napi1_id) 98 + 99 + 100 + def main() -> None: 101 + """ Ksft boiler plate main """ 102 + 103 + with NetDrvEnv(__file__, queue_count=2) as cfg: 104 + ksft_run([change_num_queues, 105 + enable_dev_threaded_disable_napi_threaded], 106 + args=(cfg, NetdevFamily())) 107 + ksft_exit() 108 + 109 + 110 + if __name__ == "__main__": 111 + main()
+1 -1
tools/testing/selftests/drivers/net/netdevsim/nexthop.sh
··· 1053 1053 1054 1054 setup_prepare 1055 1055 1056 - tests_run 1056 + xfail_on_slow tests_run 1057 1057 1058 1058 exit $EXIT_STATUS
+1 -18
tools/testing/selftests/net/packetdrill/ksft_runner.sh
··· 35 35 36 36 if [[ -n "${KSFT_MACHINE_SLOW}" ]]; then 37 37 optargs+=('--tolerance_usecs=14000') 38 - 39 - # xfail tests that are known flaky with dbg config, not fixable. 40 - # still run them for coverage (and expect 100% pass without dbg). 41 - declare -ar xfail_list=( 42 - "tcp_blocking_blocking-connect.pkt" 43 - "tcp_blocking_blocking-read.pkt" 44 - "tcp_eor_no-coalesce-retrans.pkt" 45 - "tcp_fast_recovery_prr-ss.*.pkt" 46 - "tcp_sack_sack-route-refresh-ip-tos.pkt" 47 - "tcp_slow_start_slow-start-after-win-update.pkt" 48 - "tcp_timestamping.*.pkt" 49 - "tcp_user_timeout_user-timeout-probe.pkt" 50 - "tcp_zerocopy_cl.*.pkt" 51 - "tcp_zerocopy_epoll_.*.pkt" 52 - "tcp_tcp_info_tcp-info-.*-limited.pkt" 53 - ) 54 - readonly xfail_regex="^($(printf '%s|' "${xfail_list[@]}"))$" 55 - [[ "$script" =~ ${xfail_regex} ]] && failfunc=ktap_test_xfail 38 + failfunc=ktap_test_xfail 56 39 fi 57 40 58 41 ktap_print_header
+3 -3
tools/testing/selftests/net/test_neigh.sh
··· 289 289 orig_base_reachable=$(ip -j ntable show name "$tbl_name" | jq '.[] | select(has("thresh1")) | .["base_reachable"]') 290 290 run_cmd "ip ntable change name $tbl_name thresh1 10 base_reachable 10000" 291 291 orig_gc_stale=$(ip -n "$ns1" -j ntable show name "$tbl_name" dev veth0 | jq '.[]["gc_stale"]') 292 - run_cmd "ip -n $ns1 ntable change name $tbl_name dev veth0 gc_stale 5000" 293 - # Wait orig_base_reachable/2 for the new interval to take effect. 294 - run_cmd "sleep $(((orig_base_reachable / 1000) / 2 + 2))" 292 + run_cmd "ip -n $ns1 ntable change name $tbl_name dev veth0 gc_stale 1000" 295 293 run_cmd "ip -n $ns1 neigh add $ip_addr lladdr $mac nud stale dev veth0 extern_valid" 296 294 run_cmd "ip -n $ns1 neigh add ${subnet}3 lladdr $mac nud stale dev veth0" 295 + # Wait orig_base_reachable/2 for the new interval to take effect. 296 + run_cmd "sleep $(((orig_base_reachable / 1000) / 2 + 2))" 297 297 for i in {1..20}; do 298 298 run_cmd "ip -n $ns1 neigh add ${subnet}$((i + 4)) nud none dev veth0" 299 299 done
+8 -8
tools/testing/selftests/net/vlan_hw_filter.sh
··· 55 55 ip netns exec ${NETNS} ip link add bond0 type bond mode 0 56 56 ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q 57 57 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off 58 - ip netns exec ${NETNS} ifconfig bond0 up 58 + ip netns exec ${NETNS} ip link set dev bond0 up 59 59 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on 60 - ip netns exec ${NETNS} ifconfig bond0 down 61 - ip netns exec ${NETNS} ifconfig bond0 up 60 + ip netns exec ${NETNS} ip link set dev bond0 down 61 + ip netns exec ${NETNS} ip link set dev bond0 up 62 62 ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" 63 63 cleanup 64 64 } ··· 68 68 setup 69 69 ip netns exec ${NETNS} ip link add bond0 type bond mode 0 70 70 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off 71 - ip netns exec ${NETNS} ifconfig bond0 up 71 + ip netns exec ${NETNS} ip link set dev bond0 up 72 72 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on 73 73 ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q 74 - ip netns exec ${NETNS} ifconfig bond0 down 75 - ip netns exec ${NETNS} ifconfig bond0 up 74 + ip netns exec ${NETNS} ip link set dev bond0 down 75 + ip netns exec ${NETNS} ip link set dev bond0 up 76 76 ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" 77 77 cleanup 78 78 } ··· 84 84 ip netns exec ${NETNS} ip link add bond0 type bond mode 0 85 85 ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q 86 86 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off 87 - ip netns exec ${NETNS} ifconfig bond0 up 87 + ip netns exec ${NETNS} ip link set dev bond0 up 88 88 ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on 89 - ip netns exec ${NETNS} ifconfig bond0 down 89 + ip netns exec ${NETNS} ip link set dev bond0 down 90 90 ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function" 91 91 cleanup 92 92 }