mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-01 10:42:11 +00:00
Including fixes from bluetooth, can and netfilter.
Current release - new code bugs: - bonding: ipv6: correct address used in Neighbour Advertisement parsing (src vs dst typo) - fec: properly scope IRQ coalesce setup during link up to supported chips only Previous releases - regressions: - Bluetooth fixes for fake CSR clones (knockoffs): - re-add ERR_DATA_REPORTING quirk - fix crash when device is replugged - Bluetooth: - silence a user-triggerable dmesg error message - L2CAP: fix u8 overflow, oob access - correct vendor codec definition - fix support for Read Local Supported Codecs V2 - ti: am65-cpsw: fix RGMII configuration at SPEED_10 - mana: fix race on per-CQ variable NAPI work_done Previous releases - always broken: - af_unix: diag: fetch user_ns from in_skb in unix_diag_get_exact(), avoid null-deref - af_can: fix NULL pointer dereference in can_rcv_filter - can: slcan: fix UAF with a freed work - can: can327: flush TX_work on ldisc .close() - macsec: add missing attribute validation for offload - ipv6: avoid use-after-free in ip6_fragment() - nft_set_pipapo: actually validate intervals in fields after the first one - mvneta: prevent oob access in mvneta_config_rss() - ipv4: fix incorrect route flushing when table ID 0 is used, or when source address is deleted - phy: mxl-gpy: add workaround for IRQ bug on GPY215B and GPY215C Signed-off-by: Jakub Kicinski <kuba@kernel.org> -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE6jPA+I1ugmIBA4hXMUZtbf5SIrsFAmOSS98ACgkQMUZtbf5S Irssbg//aTPi8bJgyM/yH83QK1+6t23xiW0YscJG3CXr+lTIvXKRoyPjUwNmy1TG xr5+dkW73nEVr3Uxkunn1qo+74yYpwewd1gamOxmjD+TDIb2xn/ErN61X506eXTy 59thWoAMD0EOQrqDIcD4SEfdNMaASrJSD4t8rXwk/h7LMw+mrIsWNSeFL4HpgHOw lYwujLwDkkDJNWDWI8NcJiR3i+l7JGOHkcdYfhBZIodBCQ1y/u3AVpK0qZd6eeFs 3Waz7a0q9M0glHhXXMdN/v+XjxKRE1evkMjv842zABTSLy4lKKZPn//pXwA+bZ24 qHw2y1a7ZHiRBQMqNCddxzHhe6kfq8OyrCDAI8qupBTNFBXXKzJyxCrbabPNeern YW0oggN9dTkES17OeHraA5O8km1L6tfIbm6BLteXAwM4hDoxBSMQYtEDF26P4K1K UYufBjfL/hPhuoYNFZ//0laLow+6k8Sl7Pdk/fwd8InCb59YrYUpjod7kXMByw7m ++FO3guxnk32ZEWduG3Gc203Vi4acRrQkGqWbhMZtH+ccxexx2Efl6Xn+sq7r9Dv rl/PIQiuGdoFf7OaW64FS2Nj8eVAPcqbYUMEc3EBrFDs/CvGTkyzRUcQoLdEf2zu p2ldFTerGtek9F7dUs4GZr/vw29n0Q2dPdQVFIcuXo3Nz3wFNKI= =+mCl -----END PGP SIGNATURE----- Merge tag 'net-6.1-rc9' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Jakub Kicinski: "Including fixes from bluetooth, can and netfilter. Current release - new code bugs: - bonding: ipv6: correct address used in Neighbour Advertisement parsing (src vs dst typo) - fec: properly scope IRQ coalesce setup during link up to supported chips only Previous releases - regressions: - Bluetooth fixes for fake CSR clones (knockoffs): - re-add ERR_DATA_REPORTING quirk - fix crash when device is replugged - Bluetooth: - silence a user-triggerable dmesg error message - L2CAP: fix u8 overflow, oob access - correct vendor codec definition - fix support for Read Local Supported Codecs V2 - ti: am65-cpsw: fix RGMII configuration at SPEED_10 - mana: fix race on per-CQ variable NAPI work_done Previous releases - always broken: - af_unix: diag: fetch user_ns from in_skb in unix_diag_get_exact(), avoid null-deref - af_can: fix NULL pointer dereference in can_rcv_filter - can: slcan: fix UAF with a freed work - can: can327: flush TX_work on ldisc .close() - macsec: add missing attribute validation for offload - ipv6: avoid use-after-free in ip6_fragment() - nft_set_pipapo: actually validate intervals in fields after the first one - mvneta: prevent oob access in mvneta_config_rss() - ipv4: fix incorrect route flushing when table ID 0 is used, or when source address is deleted - phy: mxl-gpy: add workaround for IRQ bug on GPY215B and GPY215C" * tag 'net-6.1-rc9' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (77 commits) net: dsa: sja1105: avoid out of bounds access in sja1105_init_l2_policing() s390/qeth: fix use-after-free in hsci macsec: add missing attribute validation for offload net: mvneta: Fix an out of bounds check net: thunderbolt: fix memory leak in tbnet_open() ipv6: avoid use-after-free in ip6_fragment() net: plip: don't call kfree_skb/dev_kfree_skb() under spin_lock_irq() net: phy: mxl-gpy: add MDINT workaround net: dsa: mv88e6xxx: accept phy-mode = "internal" for internal PHY ports xen/netback: don't call kfree_skb() under spin_lock_irqsave() dpaa2-switch: Fix memory leak in dpaa2_switch_acl_entry_add() and dpaa2_switch_acl_entry_remove() ethernet: aeroflex: fix potential skb leak in greth_init_rings() tipc: call tipc_lxc_xmit without holding node_read_lock can: esd_usb: Allow REC and TEC to return to zero can: can327: flush TX_work on ldisc .close() can: slcan: fix freed work crash can: af_can: fix NULL pointer dereference in can_rcv_filter net: dsa: sja1105: fix memory leak in sja1105_setup_devlink_regions() ipv4: Fix incorrect route flushing when table ID 0 is used ipv4: Fix incorrect route flushing when source address is deleted ...
This commit is contained in:
commit
010b6761a9
@ -535,6 +535,7 @@ ForEachMacros:
|
||||
- 'perf_hpp_list__for_each_sort_list_safe'
|
||||
- 'perf_pmu__for_each_hybrid_pmu'
|
||||
- 'ping_portaddr_for_each_entry'
|
||||
- 'ping_portaddr_for_each_entry_rcu'
|
||||
- 'plist_for_each'
|
||||
- 'plist_for_each_continue'
|
||||
- 'plist_for_each_entry'
|
||||
|
@ -2056,6 +2056,11 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
|
||||
rp = (struct hci_rp_read_local_version *)skb->data;
|
||||
|
||||
bt_dev_info(hdev, "CSR: Setting up dongle with HCI ver=%u rev=%04x; LMP ver=%u subver=%04x; manufacturer=%u",
|
||||
le16_to_cpu(rp->hci_ver), le16_to_cpu(rp->hci_rev),
|
||||
le16_to_cpu(rp->lmp_ver), le16_to_cpu(rp->lmp_subver),
|
||||
le16_to_cpu(rp->manufacturer));
|
||||
|
||||
/* Detect a wide host of Chinese controllers that aren't CSR.
|
||||
*
|
||||
* Known fake bcdDevices: 0x0100, 0x0134, 0x1915, 0x2520, 0x7558, 0x8891
|
||||
@ -2118,6 +2123,7 @@ static int btusb_setup_csr(struct hci_dev *hdev)
|
||||
* without these the controller will lock up.
|
||||
*/
|
||||
set_bit(HCI_QUIRK_BROKEN_STORED_LINK_KEY, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_BROKEN_FILTER_CLEAR_ALL, &hdev->quirks);
|
||||
set_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks);
|
||||
|
||||
|
@ -3247,7 +3247,7 @@ static int bond_na_rcv(const struct sk_buff *skb, struct bonding *bond,
|
||||
goto out;
|
||||
|
||||
saddr = &combined->ip6.saddr;
|
||||
daddr = &combined->ip6.saddr;
|
||||
daddr = &combined->ip6.daddr;
|
||||
|
||||
slave_dbg(bond->dev, slave->dev, "%s: %s/%d av %d sv %d sip %pI6c tip %pI6c\n",
|
||||
__func__, slave->dev->name, bond_slave_state(slave),
|
||||
|
@ -796,9 +796,9 @@ static int can327_netdev_close(struct net_device *dev)
|
||||
|
||||
netif_stop_queue(dev);
|
||||
|
||||
/* Give UART one final chance to flush. */
|
||||
clear_bit(TTY_DO_WRITE_WAKEUP, &elm->tty->flags);
|
||||
flush_work(&elm->tx_work);
|
||||
/* We don't flush the UART TX queue here, as we want final stop
|
||||
* commands (like the above dummy char) to be flushed out.
|
||||
*/
|
||||
|
||||
can_rx_offload_disable(&elm->offload);
|
||||
elm->can.state = CAN_STATE_STOPPED;
|
||||
@ -1069,12 +1069,15 @@ static void can327_ldisc_close(struct tty_struct *tty)
|
||||
{
|
||||
struct can327 *elm = (struct can327 *)tty->disc_data;
|
||||
|
||||
/* unregister_netdev() calls .ndo_stop() so we don't have to.
|
||||
* Our .ndo_stop() also flushes the TTY write wakeup handler,
|
||||
* so we can safely set elm->tty = NULL after this.
|
||||
*/
|
||||
/* unregister_netdev() calls .ndo_stop() so we don't have to. */
|
||||
unregister_candev(elm->dev);
|
||||
|
||||
/* Give UART one final chance to flush.
|
||||
* No need to clear TTY_DO_WRITE_WAKEUP since .write_wakeup() is
|
||||
* serialised against .close() and will not be called once we return.
|
||||
*/
|
||||
flush_work(&elm->tx_work);
|
||||
|
||||
/* Mark channel as dead */
|
||||
spin_lock_bh(&elm->lock);
|
||||
tty->disc_data = NULL;
|
||||
|
@ -864,12 +864,14 @@ static void slcan_close(struct tty_struct *tty)
|
||||
{
|
||||
struct slcan *sl = (struct slcan *)tty->disc_data;
|
||||
|
||||
/* unregister_netdev() calls .ndo_stop() so we don't have to.
|
||||
* Our .ndo_stop() also flushes the TTY write wakeup handler,
|
||||
* so we can safely set sl->tty = NULL after this.
|
||||
*/
|
||||
unregister_candev(sl->dev);
|
||||
|
||||
/*
|
||||
* The netdev needn't be UP (so .ndo_stop() is not called). Hence make
|
||||
* sure this is not running before freeing it up.
|
||||
*/
|
||||
flush_work(&sl->tx_work);
|
||||
|
||||
/* Mark channel as dead */
|
||||
spin_lock_bh(&sl->lock);
|
||||
tty->disc_data = NULL;
|
||||
|
@ -234,6 +234,10 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
|
||||
u8 rxerr = msg->msg.rx.data[2];
|
||||
u8 txerr = msg->msg.rx.data[3];
|
||||
|
||||
netdev_dbg(priv->netdev,
|
||||
"CAN_ERR_EV_EXT: dlc=%#02x state=%02x ecc=%02x rec=%02x tec=%02x\n",
|
||||
msg->msg.rx.dlc, state, ecc, rxerr, txerr);
|
||||
|
||||
skb = alloc_can_err_skb(priv->netdev, &cf);
|
||||
if (skb == NULL) {
|
||||
stats->rx_dropped++;
|
||||
@ -260,6 +264,8 @@ static void esd_usb_rx_event(struct esd_usb_net_priv *priv,
|
||||
break;
|
||||
default:
|
||||
priv->can.state = CAN_STATE_ERROR_ACTIVE;
|
||||
txerr = 0;
|
||||
rxerr = 0;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
|
@ -833,10 +833,13 @@ static void mv88e6xxx_get_caps(struct dsa_switch *ds, int port,
|
||||
|
||||
chip->info->ops->phylink_get_caps(chip, port, config);
|
||||
|
||||
/* Internal ports need GMII for PHYLIB */
|
||||
if (mv88e6xxx_phy_is_internal(ds, port))
|
||||
if (mv88e6xxx_phy_is_internal(ds, port)) {
|
||||
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
|
||||
config->supported_interfaces);
|
||||
/* Internal ports with no phy-mode need GMII for PHYLIB */
|
||||
__set_bit(PHY_INTERFACE_MODE_GMII,
|
||||
config->supported_interfaces);
|
||||
}
|
||||
}
|
||||
|
||||
static void mv88e6xxx_mac_config(struct dsa_switch *ds, int port,
|
||||
|
@ -95,6 +95,8 @@ static int sja1105_setup_devlink_regions(struct dsa_switch *ds)
|
||||
if (IS_ERR(region)) {
|
||||
while (--i >= 0)
|
||||
dsa_devlink_region_destroy(priv->regions[i]);
|
||||
|
||||
kfree(priv->regions);
|
||||
return PTR_ERR(region);
|
||||
}
|
||||
|
||||
|
@ -1038,7 +1038,7 @@ static int sja1105_init_l2_policing(struct sja1105_private *priv)
|
||||
|
||||
policing[bcast].sharindx = port;
|
||||
/* Only SJA1110 has multicast policers */
|
||||
if (mcast <= table->ops->max_entry_count)
|
||||
if (mcast < table->ops->max_entry_count)
|
||||
policing[mcast].sharindx = port;
|
||||
}
|
||||
|
||||
|
@ -258,6 +258,7 @@ static int greth_init_rings(struct greth_private *greth)
|
||||
if (dma_mapping_error(greth->dev, dma_addr)) {
|
||||
if (netif_msg_ifup(greth))
|
||||
dev_err(greth->dev, "Could not create initial DMA mapping\n");
|
||||
dev_kfree_skb(skb);
|
||||
goto cleanup;
|
||||
}
|
||||
greth->rx_skbuff[i] = skb;
|
||||
|
@ -71,13 +71,14 @@ config BCM63XX_ENET
|
||||
config BCMGENET
|
||||
tristate "Broadcom GENET internal MAC support"
|
||||
depends on HAS_IOMEM
|
||||
depends on PTP_1588_CLOCK_OPTIONAL || !ARCH_BCM2835
|
||||
select MII
|
||||
select PHYLIB
|
||||
select FIXED_PHY
|
||||
select BCM7XXX_PHY
|
||||
select MDIO_BCM_UNIMAC
|
||||
select DIMLIB
|
||||
select BROADCOM_PHY if (ARCH_BCM2835 && PTP_1588_CLOCK_OPTIONAL)
|
||||
select BROADCOM_PHY if ARCH_BCM2835
|
||||
help
|
||||
This driver supports the built-in Ethernet MACs found in the
|
||||
Broadcom BCM7xxx Set Top Box family chipset.
|
||||
|
@ -2239,7 +2239,7 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
err = register_netdev(netdev);
|
||||
if (err) {
|
||||
dev_err(dev, "Failed to register netdevice\n");
|
||||
goto err_unregister_interrupts;
|
||||
goto err_destroy_workqueue;
|
||||
}
|
||||
|
||||
nic->msg_enable = debug;
|
||||
@ -2248,6 +2248,8 @@ static int nicvf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
|
||||
return 0;
|
||||
|
||||
err_destroy_workqueue:
|
||||
destroy_workqueue(nic->nicvf_rx_mode_wq);
|
||||
err_unregister_interrupts:
|
||||
nicvf_unregister_interrupts(nic);
|
||||
err_free_netdev:
|
||||
|
@ -132,6 +132,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
|
||||
DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
|
||||
dev_err(dev, "DMA mapping failed\n");
|
||||
kfree(cmd_buff);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -142,6 +143,7 @@ int dpaa2_switch_acl_entry_add(struct dpaa2_switch_filter_block *filter_block,
|
||||
DMA_TO_DEVICE);
|
||||
if (err) {
|
||||
dev_err(dev, "dpsw_acl_add_entry() failed %d\n", err);
|
||||
kfree(cmd_buff);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -172,6 +174,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
|
||||
DMA_TO_DEVICE);
|
||||
if (unlikely(dma_mapping_error(dev, acl_entry_cfg->key_iova))) {
|
||||
dev_err(dev, "DMA mapping failed\n");
|
||||
kfree(cmd_buff);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
@ -182,6 +185,7 @@ dpaa2_switch_acl_entry_remove(struct dpaa2_switch_filter_block *block,
|
||||
DMA_TO_DEVICE);
|
||||
if (err) {
|
||||
dev_err(dev, "dpsw_acl_remove_entry() failed %d\n", err);
|
||||
kfree(cmd_buff);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1220,7 +1220,8 @@ fec_restart(struct net_device *ndev)
|
||||
writel(0, fep->hwp + FEC_IMASK);
|
||||
|
||||
/* Init the interrupt coalescing */
|
||||
fec_enet_itr_coal_set(ndev);
|
||||
if (fep->quirks & FEC_QUIRK_HAS_COALESCE)
|
||||
fec_enet_itr_coal_set(ndev);
|
||||
}
|
||||
|
||||
static int fec_enet_ipc_handle_init(struct fec_enet_private *fep)
|
||||
|
@ -283,7 +283,7 @@ static int hisi_femac_rx(struct net_device *dev, int limit)
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
napi_gro_receive(&priv->napi, skb);
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += skb->len;
|
||||
dev->stats.rx_bytes += len;
|
||||
next:
|
||||
pos = (pos + 1) % rxq->num;
|
||||
if (rx_pkts_num >= limit)
|
||||
|
@ -550,7 +550,7 @@ static int hix5hd2_rx(struct net_device *dev, int limit)
|
||||
skb->protocol = eth_type_trans(skb, dev);
|
||||
napi_gro_receive(&priv->napi, skb);
|
||||
dev->stats.rx_packets++;
|
||||
dev->stats.rx_bytes += skb->len;
|
||||
dev->stats.rx_bytes += len;
|
||||
next:
|
||||
pos = dma_ring_incr(pos, RX_DESC_NUM);
|
||||
}
|
||||
|
@ -5936,9 +5936,9 @@ static netdev_tx_t e1000_xmit_frame(struct sk_buff *skb,
|
||||
e1000_tx_queue(tx_ring, tx_flags, count);
|
||||
/* Make sure there is space in the ring for the next send. */
|
||||
e1000_maybe_stop_tx(tx_ring,
|
||||
(MAX_SKB_FRAGS *
|
||||
((MAX_SKB_FRAGS + 1) *
|
||||
DIV_ROUND_UP(PAGE_SIZE,
|
||||
adapter->tx_fifo_limit) + 2));
|
||||
adapter->tx_fifo_limit) + 4));
|
||||
|
||||
if (!netdev_xmit_more() ||
|
||||
netif_xmit_stopped(netdev_get_tx_queue(netdev, 0))) {
|
||||
|
@ -4464,11 +4464,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* First 4 bytes of L4 header */
|
||||
if (usr_ip4_spec->l4_4_bytes == htonl(0xFFFFFFFF))
|
||||
new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
|
||||
else if (!usr_ip4_spec->l4_4_bytes)
|
||||
new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
|
||||
else
|
||||
if (usr_ip4_spec->l4_4_bytes)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Filtering on Type of Service is not supported. */
|
||||
@ -4507,11 +4503,7 @@ static int i40e_check_fdir_input_set(struct i40e_vsi *vsi,
|
||||
else
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (usr_ip6_spec->l4_4_bytes == htonl(0xFFFFFFFF))
|
||||
new_mask |= I40E_L4_SRC_MASK | I40E_L4_DST_MASK;
|
||||
else if (!usr_ip6_spec->l4_4_bytes)
|
||||
new_mask &= ~(I40E_L4_SRC_MASK | I40E_L4_DST_MASK);
|
||||
else
|
||||
if (usr_ip6_spec->l4_4_bytes)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
/* Filtering on Traffic class is not supported. */
|
||||
|
@ -10654,6 +10654,21 @@ static int i40e_rebuild_channels(struct i40e_vsi *vsi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_clean_xps_state - clean xps state for every tx_ring
|
||||
* @vsi: ptr to the VSI
|
||||
**/
|
||||
static void i40e_clean_xps_state(struct i40e_vsi *vsi)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (vsi->tx_rings)
|
||||
for (i = 0; i < vsi->num_queue_pairs; i++)
|
||||
if (vsi->tx_rings[i])
|
||||
clear_bit(__I40E_TX_XPS_INIT_DONE,
|
||||
vsi->tx_rings[i]->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_prep_for_reset - prep for the core to reset
|
||||
* @pf: board private structure
|
||||
@ -10678,8 +10693,10 @@ static void i40e_prep_for_reset(struct i40e_pf *pf)
|
||||
i40e_pf_quiesce_all_vsi(pf);
|
||||
|
||||
for (v = 0; v < pf->num_alloc_vsi; v++) {
|
||||
if (pf->vsi[v])
|
||||
if (pf->vsi[v]) {
|
||||
i40e_clean_xps_state(pf->vsi[v]);
|
||||
pf->vsi[v]->seid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
i40e_shutdown_adminq(&pf->hw);
|
||||
|
@ -1578,6 +1578,7 @@ bool i40e_reset_vf(struct i40e_vf *vf, bool flr)
|
||||
i40e_cleanup_reset_vf(vf);
|
||||
|
||||
i40e_flush(hw);
|
||||
usleep_range(20000, 40000);
|
||||
clear_bit(I40E_VF_STATE_RESETTING, &vf->vf_states);
|
||||
|
||||
return true;
|
||||
@ -1701,6 +1702,7 @@ bool i40e_reset_all_vfs(struct i40e_pf *pf, bool flr)
|
||||
}
|
||||
|
||||
i40e_flush(hw);
|
||||
usleep_range(20000, 40000);
|
||||
clear_bit(__I40E_VF_DISABLE, pf->state);
|
||||
|
||||
return true;
|
||||
|
@ -1413,6 +1413,8 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
|
||||
*data = 1;
|
||||
return -1;
|
||||
}
|
||||
wr32(E1000_IVAR_MISC, E1000_IVAR_VALID << 8);
|
||||
wr32(E1000_EIMS, BIT(0));
|
||||
} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
|
||||
shared_int = false;
|
||||
if (request_irq(irq,
|
||||
|
@ -4271,7 +4271,7 @@ static void mvneta_percpu_elect(struct mvneta_port *pp)
|
||||
/* Use the cpu associated to the rxq when it is online, in all
|
||||
* the other cases, use the cpu 0 which can't be offline.
|
||||
*/
|
||||
if (cpu_online(pp->rxq_def))
|
||||
if (pp->rxq_def < nr_cpu_ids && cpu_online(pp->rxq_def))
|
||||
elected_cpu = pp->rxq_def;
|
||||
|
||||
max_cpu = num_present_cpus();
|
||||
|
@ -1134,7 +1134,12 @@ int otx2_init_tc(struct otx2_nic *nic)
|
||||
return err;
|
||||
|
||||
tc->flow_ht_params = tc_flow_ht_params;
|
||||
return rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
|
||||
err = rhashtable_init(&tc->flow_table, &tc->flow_ht_params);
|
||||
if (err) {
|
||||
kfree(tc->tc_entries_bitmap);
|
||||
tc->tc_entries_bitmap = NULL;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL(otx2_init_tc);
|
||||
|
||||
|
@ -359,7 +359,7 @@ static int regmap_encx24j600_phy_reg_read(void *context, unsigned int reg,
|
||||
goto err_out;
|
||||
|
||||
usleep_range(26, 100);
|
||||
while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
|
||||
while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
|
||||
(mistat & BUSY))
|
||||
cpu_relax();
|
||||
|
||||
@ -397,7 +397,7 @@ static int regmap_encx24j600_phy_reg_write(void *context, unsigned int reg,
|
||||
goto err_out;
|
||||
|
||||
usleep_range(26, 100);
|
||||
while ((ret = regmap_read(ctx->regmap, MISTAT, &mistat) != 0) &&
|
||||
while (((ret = regmap_read(ctx->regmap, MISTAT, &mistat)) == 0) &&
|
||||
(mistat & BUSY))
|
||||
cpu_relax();
|
||||
|
||||
|
@ -317,7 +317,7 @@ int sparx5_fdma_xmit(struct sparx5 *sparx5, u32 *ifh, struct sk_buff *skb)
|
||||
next_dcb_hw = sparx5_fdma_next_dcb(tx, tx->curr_entry);
|
||||
db_hw = &next_dcb_hw->db[0];
|
||||
if (!(db_hw->status & FDMA_DCB_STATUS_DONE))
|
||||
tx->dropped++;
|
||||
return -EINVAL;
|
||||
db = list_first_entry(&tx->db_list, struct sparx5_db, list);
|
||||
list_move_tail(&db->list, &tx->db_list);
|
||||
next_dcb_hw->nextptr = FDMA_DCB_INVALID_DATA;
|
||||
|
@ -887,6 +887,8 @@ static int mchp_sparx5_probe(struct platform_device *pdev)
|
||||
|
||||
cleanup_ports:
|
||||
sparx5_cleanup_ports(sparx5);
|
||||
if (sparx5->mact_queue)
|
||||
destroy_workqueue(sparx5->mact_queue);
|
||||
cleanup_config:
|
||||
kfree(configs);
|
||||
cleanup_pnode:
|
||||
@ -911,6 +913,7 @@ static int mchp_sparx5_remove(struct platform_device *pdev)
|
||||
sparx5_cleanup_ports(sparx5);
|
||||
/* Unregister netdevs */
|
||||
sparx5_unregister_notifier_blocks(sparx5);
|
||||
destroy_workqueue(sparx5->mact_queue);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -234,9 +234,8 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
|
||||
sparx5_set_port_ifh(ifh, port->portno);
|
||||
|
||||
if (sparx5->ptp && skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) {
|
||||
ret = sparx5_ptp_txtstamp_request(port, skb);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (sparx5_ptp_txtstamp_request(port, skb) < 0)
|
||||
return NETDEV_TX_BUSY;
|
||||
|
||||
sparx5_set_port_ifh_rew_op(ifh, SPARX5_SKB_CB(skb)->rew_op);
|
||||
sparx5_set_port_ifh_pdu_type(ifh, SPARX5_SKB_CB(skb)->pdu_type);
|
||||
@ -250,23 +249,31 @@ netdev_tx_t sparx5_port_xmit_impl(struct sk_buff *skb, struct net_device *dev)
|
||||
else
|
||||
ret = sparx5_inject(sparx5, ifh, skb, dev);
|
||||
|
||||
if (ret == NETDEV_TX_OK) {
|
||||
stats->tx_bytes += skb->len;
|
||||
stats->tx_packets++;
|
||||
if (ret == -EBUSY)
|
||||
goto busy;
|
||||
if (ret < 0)
|
||||
goto drop;
|
||||
|
||||
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
|
||||
SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
|
||||
return ret;
|
||||
stats->tx_bytes += skb->len;
|
||||
stats->tx_packets++;
|
||||
sparx5->tx.packets++;
|
||||
|
||||
dev_kfree_skb_any(skb);
|
||||
} else {
|
||||
stats->tx_dropped++;
|
||||
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
|
||||
SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
|
||||
return NETDEV_TX_OK;
|
||||
|
||||
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
|
||||
SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
|
||||
sparx5_ptp_txtstamp_release(port, skb);
|
||||
}
|
||||
return ret;
|
||||
dev_consume_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
drop:
|
||||
stats->tx_dropped++;
|
||||
sparx5->tx.dropped++;
|
||||
dev_kfree_skb_any(skb);
|
||||
return NETDEV_TX_OK;
|
||||
busy:
|
||||
if (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP &&
|
||||
SPARX5_SKB_CB(skb)->rew_op == IFH_REW_OP_TWO_STEP_PTP)
|
||||
sparx5_ptp_txtstamp_release(port, skb);
|
||||
return NETDEV_TX_BUSY;
|
||||
}
|
||||
|
||||
static enum hrtimer_restart sparx5_injection_timeout(struct hrtimer *tmr)
|
||||
|
@ -498,7 +498,14 @@ enum {
|
||||
|
||||
#define GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT BIT(0)
|
||||
|
||||
#define GDMA_DRV_CAP_FLAGS1 GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT
|
||||
/* Advertise to the NIC firmware: the NAPI work_done variable race is fixed,
|
||||
* so the driver is able to reliably support features like busy_poll.
|
||||
*/
|
||||
#define GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX BIT(2)
|
||||
|
||||
#define GDMA_DRV_CAP_FLAGS1 \
|
||||
(GDMA_DRV_CAP_FLAG_1_EQ_SHARING_MULTI_VPORT | \
|
||||
GDMA_DRV_CAP_FLAG_1_NAPI_WKDONE_FIX)
|
||||
|
||||
#define GDMA_DRV_CAP_FLAGS2 0
|
||||
|
||||
|
@ -1303,10 +1303,11 @@ static void mana_poll_rx_cq(struct mana_cq *cq)
|
||||
xdp_do_flush();
|
||||
}
|
||||
|
||||
static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
|
||||
static int mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
|
||||
{
|
||||
struct mana_cq *cq = context;
|
||||
u8 arm_bit;
|
||||
int w;
|
||||
|
||||
WARN_ON_ONCE(cq->gdma_cq != gdma_queue);
|
||||
|
||||
@ -1315,26 +1316,31 @@ static void mana_cq_handler(void *context, struct gdma_queue *gdma_queue)
|
||||
else
|
||||
mana_poll_tx_cq(cq);
|
||||
|
||||
if (cq->work_done < cq->budget &&
|
||||
napi_complete_done(&cq->napi, cq->work_done)) {
|
||||
w = cq->work_done;
|
||||
|
||||
if (w < cq->budget &&
|
||||
napi_complete_done(&cq->napi, w)) {
|
||||
arm_bit = SET_ARM_BIT;
|
||||
} else {
|
||||
arm_bit = 0;
|
||||
}
|
||||
|
||||
mana_gd_ring_cq(gdma_queue, arm_bit);
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
static int mana_poll(struct napi_struct *napi, int budget)
|
||||
{
|
||||
struct mana_cq *cq = container_of(napi, struct mana_cq, napi);
|
||||
int w;
|
||||
|
||||
cq->work_done = 0;
|
||||
cq->budget = budget;
|
||||
|
||||
mana_cq_handler(cq, cq->gdma_cq);
|
||||
w = mana_cq_handler(cq, cq->gdma_cq);
|
||||
|
||||
return min(cq->work_done, budget);
|
||||
return min(w, budget);
|
||||
}
|
||||
|
||||
static void mana_schedule_napi(void *context, struct gdma_queue *gdma_queue)
|
||||
|
@ -282,7 +282,7 @@ netdev_tx_t nfp_nfdk_tx(struct sk_buff *skb, struct net_device *netdev)
|
||||
dma_len = skb_headlen(skb);
|
||||
if (skb_is_gso(skb))
|
||||
type = NFDK_DESC_TX_TYPE_TSO;
|
||||
else if (!nr_frags && dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
else if (!nr_frags && dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
type = NFDK_DESC_TX_TYPE_SIMPLE;
|
||||
else
|
||||
type = NFDK_DESC_TX_TYPE_GATHER;
|
||||
@ -927,7 +927,7 @@ nfp_nfdk_tx_xdp_buf(struct nfp_net_dp *dp, struct nfp_net_rx_ring *rx_ring,
|
||||
dma_len = pkt_len;
|
||||
dma_addr = rxbuf->dma_addr + dma_off;
|
||||
|
||||
if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
type = NFDK_DESC_TX_TYPE_SIMPLE;
|
||||
else
|
||||
type = NFDK_DESC_TX_TYPE_GATHER;
|
||||
@ -1325,7 +1325,7 @@ nfp_nfdk_ctrl_tx_one(struct nfp_net *nn, struct nfp_net_r_vector *r_vec,
|
||||
txbuf = &tx_ring->ktxbufs[wr_idx];
|
||||
|
||||
dma_len = skb_headlen(skb);
|
||||
if (dma_len < NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
if (dma_len <= NFDK_TX_MAX_DATA_PER_HEAD)
|
||||
type = NFDK_DESC_TX_TYPE_SIMPLE;
|
||||
else
|
||||
type = NFDK_DESC_TX_TYPE_GATHER;
|
||||
|
@ -841,7 +841,7 @@ static bool ravb_rx_gbeth(struct net_device *ndev, int *quota, int q)
|
||||
napi_gro_receive(&priv->napi[q],
|
||||
priv->rx_1st_skb);
|
||||
stats->rx_packets++;
|
||||
stats->rx_bytes += priv->rx_1st_skb->len;
|
||||
stats->rx_bytes += pkt_len;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -108,10 +108,10 @@ static struct stmmac_axi *stmmac_axi_setup(struct platform_device *pdev)
|
||||
|
||||
axi->axi_lpi_en = of_property_read_bool(np, "snps,lpi_en");
|
||||
axi->axi_xit_frm = of_property_read_bool(np, "snps,xit_frm");
|
||||
axi->axi_kbbe = of_property_read_bool(np, "snps,axi_kbbe");
|
||||
axi->axi_fb = of_property_read_bool(np, "snps,axi_fb");
|
||||
axi->axi_mb = of_property_read_bool(np, "snps,axi_mb");
|
||||
axi->axi_rb = of_property_read_bool(np, "snps,axi_rb");
|
||||
axi->axi_kbbe = of_property_read_bool(np, "snps,kbbe");
|
||||
axi->axi_fb = of_property_read_bool(np, "snps,fb");
|
||||
axi->axi_mb = of_property_read_bool(np, "snps,mb");
|
||||
axi->axi_rb = of_property_read_bool(np, "snps,rb");
|
||||
|
||||
if (of_property_read_u32(np, "snps,wr_osr_lmt", &axi->axi_wr_osr_lmt))
|
||||
axi->axi_wr_osr_lmt = 1;
|
||||
|
@ -1454,7 +1454,7 @@ static void am65_cpsw_nuss_mac_link_up(struct phylink_config *config, struct phy
|
||||
|
||||
if (speed == SPEED_1000)
|
||||
mac_control |= CPSW_SL_CTL_GIG;
|
||||
if (speed == SPEED_10 && interface == PHY_INTERFACE_MODE_RGMII)
|
||||
if (speed == SPEED_10 && phy_interface_mode_is_rgmii(interface))
|
||||
/* Can be used with in band mode only */
|
||||
mac_control |= CPSW_SL_CTL_EXT_EN;
|
||||
if (speed == SPEED_100 && interface == PHY_INTERFACE_MODE_RMII)
|
||||
|
@ -885,7 +885,7 @@ static int ca8210_spi_transfer(
|
||||
|
||||
dev_dbg(&spi->dev, "%s called\n", __func__);
|
||||
|
||||
cas_ctl = kmalloc(sizeof(*cas_ctl), GFP_ATOMIC);
|
||||
cas_ctl = kzalloc(sizeof(*cas_ctl), GFP_ATOMIC);
|
||||
if (!cas_ctl)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -970,7 +970,7 @@ static int cc2520_hw_init(struct cc2520_private *priv)
|
||||
|
||||
if (timeout-- <= 0) {
|
||||
dev_err(&priv->spi->dev, "oscillator start failed!\n");
|
||||
return ret;
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
udelay(1);
|
||||
} while (!(status & CC2520_STATUS_XOSC32M_STABLE));
|
||||
|
@ -3698,6 +3698,7 @@ static const struct nla_policy macsec_rtnl_policy[IFLA_MACSEC_MAX + 1] = {
|
||||
[IFLA_MACSEC_SCB] = { .type = NLA_U8 },
|
||||
[IFLA_MACSEC_REPLAY_PROTECT] = { .type = NLA_U8 },
|
||||
[IFLA_MACSEC_VALIDATION] = { .type = NLA_U8 },
|
||||
[IFLA_MACSEC_OFFLOAD] = { .type = NLA_U8 },
|
||||
};
|
||||
|
||||
static void macsec_free_netdev(struct net_device *dev)
|
||||
|
@ -98,6 +98,7 @@ int fwnode_mdiobus_phy_device_register(struct mii_bus *mdio,
|
||||
*/
|
||||
rc = phy_device_register(phy);
|
||||
if (rc) {
|
||||
device_set_node(&phy->mdio.dev, NULL);
|
||||
fwnode_handle_put(child);
|
||||
return rc;
|
||||
}
|
||||
@ -153,7 +154,8 @@ int fwnode_mdiobus_register_phy(struct mii_bus *bus,
|
||||
/* All data is now stored in the phy struct, so register it */
|
||||
rc = phy_device_register(phy);
|
||||
if (rc) {
|
||||
fwnode_handle_put(phy->mdio.dev.fwnode);
|
||||
phy->mdio.dev.fwnode = NULL;
|
||||
fwnode_handle_put(child);
|
||||
goto clean_phy;
|
||||
}
|
||||
} else if (is_of_node(child)) {
|
||||
|
@ -68,8 +68,9 @@ static int of_mdiobus_register_device(struct mii_bus *mdio,
|
||||
/* All data is now stored in the mdiodev struct; register it. */
|
||||
rc = mdio_device_register(mdiodev);
|
||||
if (rc) {
|
||||
device_set_node(&mdiodev->dev, NULL);
|
||||
fwnode_handle_put(fwnode);
|
||||
mdio_device_free(mdiodev);
|
||||
of_node_put(child);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/property.h>
|
||||
|
||||
void mdio_device_free(struct mdio_device *mdiodev)
|
||||
{
|
||||
@ -30,6 +31,7 @@ EXPORT_SYMBOL(mdio_device_free);
|
||||
|
||||
static void mdio_device_release(struct device *dev)
|
||||
{
|
||||
fwnode_handle_put(dev->fwnode);
|
||||
kfree(to_mdio_device(dev));
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/phy.h>
|
||||
#include <linux/polynomial.h>
|
||||
#include <linux/netdevice.h>
|
||||
@ -70,6 +71,14 @@
|
||||
#define VPSPEC1_TEMP_STA 0x0E
|
||||
#define VPSPEC1_TEMP_STA_DATA GENMASK(9, 0)
|
||||
|
||||
/* Mailbox */
|
||||
#define VSPEC1_MBOX_DATA 0x5
|
||||
#define VSPEC1_MBOX_ADDRLO 0x6
|
||||
#define VSPEC1_MBOX_CMD 0x7
|
||||
#define VSPEC1_MBOX_CMD_ADDRHI GENMASK(7, 0)
|
||||
#define VSPEC1_MBOX_CMD_RD (0 << 8)
|
||||
#define VSPEC1_MBOX_CMD_READY BIT(15)
|
||||
|
||||
/* WoL */
|
||||
#define VPSPEC2_WOL_CTL 0x0E06
|
||||
#define VPSPEC2_WOL_AD01 0x0E08
|
||||
@ -77,7 +86,13 @@
|
||||
#define VPSPEC2_WOL_AD45 0x0E0A
|
||||
#define WOL_EN BIT(0)
|
||||
|
||||
/* Internal registers, access via mbox */
|
||||
#define REG_GPIO0_OUT 0xd3ce00
|
||||
|
||||
struct gpy_priv {
|
||||
/* serialize mailbox acesses */
|
||||
struct mutex mbox_lock;
|
||||
|
||||
u8 fw_major;
|
||||
u8 fw_minor;
|
||||
};
|
||||
@ -187,6 +202,45 @@ static int gpy_hwmon_register(struct phy_device *phydev)
|
||||
}
|
||||
#endif
|
||||
|
||||
static int gpy_mbox_read(struct phy_device *phydev, u32 addr)
|
||||
{
|
||||
struct gpy_priv *priv = phydev->priv;
|
||||
int val, ret;
|
||||
u16 cmd;
|
||||
|
||||
mutex_lock(&priv->mbox_lock);
|
||||
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_ADDRLO,
|
||||
addr);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
cmd = VSPEC1_MBOX_CMD_RD;
|
||||
cmd |= FIELD_PREP(VSPEC1_MBOX_CMD_ADDRHI, addr >> 16);
|
||||
|
||||
ret = phy_write_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_CMD, cmd);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
/* The mbox read is used in the interrupt workaround. It was observed
|
||||
* that a read might take up to 2.5ms. This is also the time for which
|
||||
* the interrupt line is stuck low. To be on the safe side, poll the
|
||||
* ready bit for 10ms.
|
||||
*/
|
||||
ret = phy_read_mmd_poll_timeout(phydev, MDIO_MMD_VEND1,
|
||||
VSPEC1_MBOX_CMD, val,
|
||||
(val & VSPEC1_MBOX_CMD_READY),
|
||||
500, 10000, false);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = phy_read_mmd(phydev, MDIO_MMD_VEND1, VSPEC1_MBOX_DATA);
|
||||
|
||||
out:
|
||||
mutex_unlock(&priv->mbox_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int gpy_config_init(struct phy_device *phydev)
|
||||
{
|
||||
int ret;
|
||||
@ -201,6 +255,13 @@ static int gpy_config_init(struct phy_device *phydev)
|
||||
return ret < 0 ? ret : 0;
|
||||
}
|
||||
|
||||
static bool gpy_has_broken_mdint(struct phy_device *phydev)
|
||||
{
|
||||
/* At least these PHYs are known to have broken interrupt handling */
|
||||
return phydev->drv->phy_id == PHY_ID_GPY215B ||
|
||||
phydev->drv->phy_id == PHY_ID_GPY215C;
|
||||
}
|
||||
|
||||
static int gpy_probe(struct phy_device *phydev)
|
||||
{
|
||||
struct device *dev = &phydev->mdio.dev;
|
||||
@ -218,6 +279,7 @@ static int gpy_probe(struct phy_device *phydev)
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
phydev->priv = priv;
|
||||
mutex_init(&priv->mbox_lock);
|
||||
|
||||
fw_version = phy_read(phydev, PHY_FWV);
|
||||
if (fw_version < 0)
|
||||
@ -492,6 +554,29 @@ static irqreturn_t gpy_handle_interrupt(struct phy_device *phydev)
|
||||
if (!(reg & PHY_IMASK_MASK))
|
||||
return IRQ_NONE;
|
||||
|
||||
/* The PHY might leave the interrupt line asserted even after PHY_ISTAT
|
||||
* is read. To avoid interrupt storms, delay the interrupt handling as
|
||||
* long as the PHY drives the interrupt line. An internal bus read will
|
||||
* stall as long as the interrupt line is asserted, thus just read a
|
||||
* random register here.
|
||||
* Because we cannot access the internal bus at all while the interrupt
|
||||
* is driven by the PHY, there is no way to make the interrupt line
|
||||
* unstuck (e.g. by changing the pinmux to GPIO input) during that time
|
||||
* frame. Therefore, polling is the best we can do and won't do any more
|
||||
* harm.
|
||||
* It was observed that this bug happens on link state and link speed
|
||||
* changes on a GPY215B and GYP215C independent of the firmware version
|
||||
* (which doesn't mean that this list is exhaustive).
|
||||
*/
|
||||
if (gpy_has_broken_mdint(phydev) &&
|
||||
(reg & (PHY_IMASK_LSTC | PHY_IMASK_LSPC))) {
|
||||
reg = gpy_mbox_read(phydev, REG_GPIO0_OUT);
|
||||
if (reg < 0) {
|
||||
phy_error(phydev);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
phy_trigger_machine(phydev);
|
||||
|
||||
return IRQ_HANDLED;
|
||||
|
@ -450,12 +450,12 @@ plip_bh_timeout_error(struct net_device *dev, struct net_local *nl,
|
||||
}
|
||||
rcv->state = PLIP_PK_DONE;
|
||||
if (rcv->skb) {
|
||||
kfree_skb(rcv->skb);
|
||||
dev_kfree_skb_irq(rcv->skb);
|
||||
rcv->skb = NULL;
|
||||
}
|
||||
snd->state = PLIP_PK_DONE;
|
||||
if (snd->skb) {
|
||||
dev_kfree_skb(snd->skb);
|
||||
dev_consume_skb_irq(snd->skb);
|
||||
snd->skb = NULL;
|
||||
}
|
||||
spin_unlock_irq(&nl->lock);
|
||||
|
@ -914,6 +914,7 @@ static int tbnet_open(struct net_device *dev)
|
||||
eof_mask, tbnet_start_poll, net);
|
||||
if (!ring) {
|
||||
netdev_err(dev, "failed to allocate Rx ring\n");
|
||||
tb_xdomain_release_out_hopid(xd, hopid);
|
||||
tb_ring_free(net->tx_ring.ring);
|
||||
net->tx_ring.ring = NULL;
|
||||
return -ENOMEM;
|
||||
|
@ -75,8 +75,14 @@ vmxnet3_enable_all_intrs(struct vmxnet3_adapter *adapter)
|
||||
|
||||
for (i = 0; i < adapter->intr.num_intrs; i++)
|
||||
vmxnet3_enable_intr(adapter, i);
|
||||
adapter->shared->devRead.intrConf.intrCtrl &=
|
||||
if (!VMXNET3_VERSION_GE_6(adapter) ||
|
||||
!adapter->queuesExtEnabled) {
|
||||
adapter->shared->devRead.intrConf.intrCtrl &=
|
||||
cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
|
||||
} else {
|
||||
adapter->shared->devReadExt.intrConfExt.intrCtrl &=
|
||||
cpu_to_le32(~VMXNET3_IC_DISABLE_ALL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -85,8 +91,14 @@ vmxnet3_disable_all_intrs(struct vmxnet3_adapter *adapter)
|
||||
{
|
||||
int i;
|
||||
|
||||
adapter->shared->devRead.intrConf.intrCtrl |=
|
||||
if (!VMXNET3_VERSION_GE_6(adapter) ||
|
||||
!adapter->queuesExtEnabled) {
|
||||
adapter->shared->devRead.intrConf.intrCtrl |=
|
||||
cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
|
||||
} else {
|
||||
adapter->shared->devReadExt.intrConfExt.intrCtrl |=
|
||||
cpu_to_le32(VMXNET3_IC_DISABLE_ALL);
|
||||
}
|
||||
for (i = 0; i < adapter->intr.num_intrs; i++)
|
||||
vmxnet3_disable_intr(adapter, i);
|
||||
}
|
||||
@ -1396,6 +1408,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
||||
};
|
||||
u32 num_pkts = 0;
|
||||
bool skip_page_frags = false;
|
||||
bool encap_lro = false;
|
||||
struct Vmxnet3_RxCompDesc *rcd;
|
||||
struct vmxnet3_rx_ctx *ctx = &rq->rx_ctx;
|
||||
u16 segCnt = 0, mss = 0;
|
||||
@ -1556,13 +1569,18 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
||||
if (VMXNET3_VERSION_GE_2(adapter) &&
|
||||
rcd->type == VMXNET3_CDTYPE_RXCOMP_LRO) {
|
||||
struct Vmxnet3_RxCompDescExt *rcdlro;
|
||||
union Vmxnet3_GenericDesc *gdesc;
|
||||
|
||||
rcdlro = (struct Vmxnet3_RxCompDescExt *)rcd;
|
||||
gdesc = (union Vmxnet3_GenericDesc *)rcd;
|
||||
|
||||
segCnt = rcdlro->segCnt;
|
||||
WARN_ON_ONCE(segCnt == 0);
|
||||
mss = rcdlro->mss;
|
||||
if (unlikely(segCnt <= 1))
|
||||
segCnt = 0;
|
||||
encap_lro = (le32_to_cpu(gdesc->dword[0]) &
|
||||
(1UL << VMXNET3_RCD_HDR_INNER_SHIFT));
|
||||
} else {
|
||||
segCnt = 0;
|
||||
}
|
||||
@ -1630,7 +1648,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
||||
vmxnet3_rx_csum(adapter, skb,
|
||||
(union Vmxnet3_GenericDesc *)rcd);
|
||||
skb->protocol = eth_type_trans(skb, adapter->netdev);
|
||||
if (!rcd->tcp ||
|
||||
if ((!rcd->tcp && !encap_lro) ||
|
||||
!(adapter->netdev->features & NETIF_F_LRO))
|
||||
goto not_lro;
|
||||
|
||||
@ -1639,7 +1657,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
||||
SKB_GSO_TCPV4 : SKB_GSO_TCPV6;
|
||||
skb_shinfo(skb)->gso_size = mss;
|
||||
skb_shinfo(skb)->gso_segs = segCnt;
|
||||
} else if (segCnt != 0 || skb->len > mtu) {
|
||||
} else if ((segCnt != 0 || skb->len > mtu) && !encap_lro) {
|
||||
u32 hlen;
|
||||
|
||||
hlen = vmxnet3_get_hdr_len(adapter, skb,
|
||||
@ -1668,6 +1686,7 @@ vmxnet3_rq_rx_complete(struct vmxnet3_rx_queue *rq,
|
||||
napi_gro_receive(&rq->napi, skb);
|
||||
|
||||
ctx->skb = NULL;
|
||||
encap_lro = false;
|
||||
num_pkts++;
|
||||
}
|
||||
|
||||
|
@ -332,6 +332,7 @@ struct iosm_mux *ipc_mux_init(struct ipc_mux_config *mux_cfg,
|
||||
if (!ipc_mux->ul_adb.pp_qlt[i]) {
|
||||
for (j = i - 1; j >= 0; j--)
|
||||
kfree(ipc_mux->ul_adb.pp_qlt[j]);
|
||||
kfree(ipc_mux);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -1862,6 +1862,12 @@ static int netfront_resume(struct xenbus_device *dev)
|
||||
netif_tx_unlock_bh(info->netdev);
|
||||
|
||||
xennet_disconnect_backend(info);
|
||||
|
||||
rtnl_lock();
|
||||
if (info->queues)
|
||||
xennet_destroy_queues(info);
|
||||
rtnl_unlock();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -758,7 +758,6 @@ static void qeth_l2_br2dev_worker(struct work_struct *work)
|
||||
struct list_head *iter;
|
||||
int err = 0;
|
||||
|
||||
kfree(br2dev_event_work);
|
||||
QETH_CARD_TEXT_(card, 4, "b2dw%04lx", event);
|
||||
QETH_CARD_TEXT_(card, 4, "ma%012llx", ether_addr_to_u64(addr));
|
||||
|
||||
@ -815,6 +814,7 @@ static void qeth_l2_br2dev_worker(struct work_struct *work)
|
||||
dev_put(brdev);
|
||||
dev_put(lsyncdev);
|
||||
dev_put(dstdev);
|
||||
kfree(br2dev_event_work);
|
||||
}
|
||||
|
||||
static int qeth_l2_br2dev_queue_work(struct net_device *brdev,
|
||||
|
@ -228,6 +228,17 @@ enum {
|
||||
*/
|
||||
HCI_QUIRK_VALID_LE_STATES,
|
||||
|
||||
/* When this quirk is set, then erroneous data reporting
|
||||
* is ignored. This is mainly due to the fact that the HCI
|
||||
* Read Default Erroneous Data Reporting command is advertised,
|
||||
* but not supported; these controllers often reply with unknown
|
||||
* command and tend to lock up randomly. Needing a hard reset.
|
||||
*
|
||||
* This quirk can be set before hci_register_dev is called or
|
||||
* during the hdev->setup vendor callback.
|
||||
*/
|
||||
HCI_QUIRK_BROKEN_ERR_DATA_REPORTING,
|
||||
|
||||
/*
|
||||
* When this quirk is set, then the hci_suspend_notifier is not
|
||||
* registered. This is intended for devices which drop completely
|
||||
@ -1424,7 +1435,6 @@ struct hci_std_codecs_v2 {
|
||||
} __packed;
|
||||
|
||||
struct hci_vnd_codec_v2 {
|
||||
__u8 id;
|
||||
__le16 cid;
|
||||
__le16 vid;
|
||||
__u8 transport;
|
||||
|
@ -16,9 +16,6 @@
|
||||
#define PING_HTABLE_SIZE 64
|
||||
#define PING_HTABLE_MASK (PING_HTABLE_SIZE-1)
|
||||
|
||||
#define ping_portaddr_for_each_entry(__sk, node, list) \
|
||||
hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
|
||||
|
||||
/*
|
||||
* gid_t is either uint or ushort. We want to pass it to
|
||||
* proc_dointvec_minmax(), so it must not be larger than MAX_INT
|
||||
|
@ -972,6 +972,7 @@ static int get_l2cap_conn(char *buf, bdaddr_t *addr, u8 *addr_type,
|
||||
hci_dev_lock(hdev);
|
||||
hcon = hci_conn_hash_lookup_le(hdev, addr, *addr_type);
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
|
||||
if (!hcon)
|
||||
return -ENOENT;
|
||||
|
@ -737,7 +737,7 @@ static int __init bt_init(void)
|
||||
|
||||
err = bt_sysfs_init();
|
||||
if (err < 0)
|
||||
return err;
|
||||
goto cleanup_led;
|
||||
|
||||
err = sock_register(&bt_sock_family_ops);
|
||||
if (err)
|
||||
@ -773,6 +773,8 @@ static int __init bt_init(void)
|
||||
sock_unregister(PF_BLUETOOTH);
|
||||
cleanup_sysfs:
|
||||
bt_sysfs_cleanup();
|
||||
cleanup_led:
|
||||
bt_leds_cleanup();
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -72,9 +72,8 @@ static void hci_read_codec_capabilities(struct hci_dev *hdev, __u8 transport,
|
||||
continue;
|
||||
}
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
|
||||
sizeof(*cmd), cmd,
|
||||
HCI_CMD_TIMEOUT);
|
||||
skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODEC_CAPS,
|
||||
sizeof(*cmd), cmd, 0, HCI_CMD_TIMEOUT, NULL);
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Failed to read codec capabilities (%ld)",
|
||||
PTR_ERR(skb));
|
||||
@ -127,8 +126,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
|
||||
struct hci_op_read_local_codec_caps caps;
|
||||
__u8 i;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
|
||||
HCI_CMD_TIMEOUT);
|
||||
skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
|
||||
0, HCI_CMD_TIMEOUT, NULL);
|
||||
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
|
||||
@ -158,7 +157,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
|
||||
for (i = 0; i < std_codecs->num; i++) {
|
||||
caps.id = std_codecs->codec[i];
|
||||
caps.direction = 0x00;
|
||||
hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
|
||||
hci_read_codec_capabilities(hdev,
|
||||
LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
|
||||
}
|
||||
|
||||
skb_pull(skb, flex_array_size(std_codecs, codec, std_codecs->num)
|
||||
@ -178,7 +178,8 @@ void hci_read_supported_codecs(struct hci_dev *hdev)
|
||||
caps.cid = vnd_codecs->codec[i].cid;
|
||||
caps.vid = vnd_codecs->codec[i].vid;
|
||||
caps.direction = 0x00;
|
||||
hci_read_codec_capabilities(hdev, LOCAL_CODEC_ACL_MASK, &caps);
|
||||
hci_read_codec_capabilities(hdev,
|
||||
LOCAL_CODEC_ACL_MASK | LOCAL_CODEC_SCO_MASK, &caps);
|
||||
}
|
||||
|
||||
error:
|
||||
@ -194,8 +195,8 @@ void hci_read_supported_codecs_v2(struct hci_dev *hdev)
|
||||
struct hci_op_read_local_codec_caps caps;
|
||||
__u8 i;
|
||||
|
||||
skb = __hci_cmd_sync(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
|
||||
HCI_CMD_TIMEOUT);
|
||||
skb = __hci_cmd_sync_sk(hdev, HCI_OP_READ_LOCAL_CODECS_V2, 0, NULL,
|
||||
0, HCI_CMD_TIMEOUT, NULL);
|
||||
|
||||
if (IS_ERR(skb)) {
|
||||
bt_dev_err(hdev, "Failed to read local supported codecs (%ld)",
|
||||
|
@ -2764,7 +2764,8 @@ int hci_register_suspend_notifier(struct hci_dev *hdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
|
||||
if (!hdev->suspend_notifier.notifier_call &&
|
||||
!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks)) {
|
||||
hdev->suspend_notifier.notifier_call = hci_suspend_notifier;
|
||||
ret = register_pm_notifier(&hdev->suspend_notifier);
|
||||
}
|
||||
@ -2776,8 +2777,11 @@ int hci_unregister_suspend_notifier(struct hci_dev *hdev)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!test_bit(HCI_QUIRK_NO_SUSPEND_NOTIFIER, &hdev->quirks))
|
||||
if (hdev->suspend_notifier.notifier_call) {
|
||||
ret = unregister_pm_notifier(&hdev->suspend_notifier);
|
||||
if (!ret)
|
||||
hdev->suspend_notifier.notifier_call = NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
@ -269,7 +269,7 @@ void hci_req_add_ev(struct hci_request *req, u16 opcode, u32 plen,
|
||||
void hci_req_add(struct hci_request *req, u16 opcode, u32 plen,
|
||||
const void *param)
|
||||
{
|
||||
bt_dev_err(req->hdev, "HCI_REQ-0x%4.4x", opcode);
|
||||
bt_dev_dbg(req->hdev, "HCI_REQ-0x%4.4x", opcode);
|
||||
hci_req_add_ev(req, opcode, plen, param, 0);
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <net/bluetooth/mgmt.h>
|
||||
|
||||
#include "hci_request.h"
|
||||
#include "hci_codec.h"
|
||||
#include "hci_debugfs.h"
|
||||
#include "smp.h"
|
||||
#include "eir.h"
|
||||
@ -3780,7 +3781,8 @@ static int hci_read_page_scan_activity_sync(struct hci_dev *hdev)
|
||||
static int hci_read_def_err_data_reporting_sync(struct hci_dev *hdev)
|
||||
{
|
||||
if (!(hdev->commands[18] & 0x04) ||
|
||||
!(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
|
||||
!(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
|
||||
test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
|
||||
return 0;
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_READ_DEF_ERR_DATA_REPORTING,
|
||||
@ -4238,11 +4240,12 @@ static int hci_set_event_mask_page_2_sync(struct hci_dev *hdev)
|
||||
/* Read local codec list if the HCI command is supported */
|
||||
static int hci_read_local_codecs_sync(struct hci_dev *hdev)
|
||||
{
|
||||
if (!(hdev->commands[29] & 0x20))
|
||||
return 0;
|
||||
if (hdev->commands[45] & 0x04)
|
||||
hci_read_supported_codecs_v2(hdev);
|
||||
else if (hdev->commands[29] & 0x20)
|
||||
hci_read_supported_codecs(hdev);
|
||||
|
||||
return __hci_cmd_sync_status(hdev, HCI_OP_READ_LOCAL_CODECS, 0, NULL,
|
||||
HCI_CMD_TIMEOUT);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read local pairing options if the HCI command is supported */
|
||||
@ -4298,7 +4301,8 @@ static int hci_set_err_data_report_sync(struct hci_dev *hdev)
|
||||
bool enabled = hci_dev_test_flag(hdev, HCI_WIDEBAND_SPEECH_ENABLED);
|
||||
|
||||
if (!(hdev->commands[18] & 0x08) ||
|
||||
!(hdev->features[0][6] & LMP_ERR_DATA_REPORTING))
|
||||
!(hdev->features[0][6] & LMP_ERR_DATA_REPORTING) ||
|
||||
test_bit(HCI_QUIRK_BROKEN_ERR_DATA_REPORTING, &hdev->quirks))
|
||||
return 0;
|
||||
|
||||
if (enabled == hdev->err_data_reporting)
|
||||
@ -4457,6 +4461,9 @@ static const struct {
|
||||
HCI_QUIRK_BROKEN(STORED_LINK_KEY,
|
||||
"HCI Delete Stored Link Key command is advertised, "
|
||||
"but not supported."),
|
||||
HCI_QUIRK_BROKEN(ERR_DATA_REPORTING,
|
||||
"HCI Read Default Erroneous Data Reporting command is "
|
||||
"advertised, but not supported."),
|
||||
HCI_QUIRK_BROKEN(READ_TRANSMIT_POWER,
|
||||
"HCI Read Transmit Power Level command is advertised, "
|
||||
"but not supported."),
|
||||
|
@ -879,6 +879,7 @@ static int iso_listen_bis(struct sock *sk)
|
||||
iso_pi(sk)->bc_sid);
|
||||
|
||||
hci_dev_unlock(hdev);
|
||||
hci_dev_put(hdev);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -4453,7 +4453,8 @@ static inline int l2cap_config_req(struct l2cap_conn *conn,
|
||||
|
||||
chan->ident = cmd->ident;
|
||||
l2cap_send_cmd(conn, cmd->ident, L2CAP_CONF_RSP, len, rsp);
|
||||
chan->num_conf_rsp++;
|
||||
if (chan->num_conf_rsp < L2CAP_CONF_MAX_CONF_RSP)
|
||||
chan->num_conf_rsp++;
|
||||
|
||||
/* Reset config buffer. */
|
||||
chan->conf_len = 0;
|
||||
|
@ -677,7 +677,7 @@ static void can_receive(struct sk_buff *skb, struct net_device *dev)
|
||||
static int can_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
struct packet_type *pt, struct net_device *orig_dev)
|
||||
{
|
||||
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_can_skb(skb)))) {
|
||||
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_can_skb(skb))) {
|
||||
pr_warn_once("PF_CAN: dropped non conform CAN skbuff: dev type %d, len %d\n",
|
||||
dev->type, skb->len);
|
||||
|
||||
@ -692,7 +692,7 @@ static int can_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
struct packet_type *pt, struct net_device *orig_dev)
|
||||
{
|
||||
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_canfd_skb(skb)))) {
|
||||
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canfd_skb(skb))) {
|
||||
pr_warn_once("PF_CAN: dropped non conform CAN FD skbuff: dev type %d, len %d\n",
|
||||
dev->type, skb->len);
|
||||
|
||||
@ -707,7 +707,7 @@ static int canfd_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
static int canxl_rcv(struct sk_buff *skb, struct net_device *dev,
|
||||
struct packet_type *pt, struct net_device *orig_dev)
|
||||
{
|
||||
if (unlikely(dev->type != ARPHRD_CAN || (!can_is_canxl_skb(skb)))) {
|
||||
if (unlikely(dev->type != ARPHRD_CAN || !can_get_ml_priv(dev) || !can_is_canxl_skb(skb))) {
|
||||
pr_warn_once("PF_CAN: dropped non conform CAN XL skbuff: dev type %d, len %d\n",
|
||||
dev->type, skb->len);
|
||||
|
||||
|
@ -49,7 +49,8 @@ static struct sk_buff *hellcreek_rcv(struct sk_buff *skb,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN);
|
||||
if (pskb_trim_rcsum(skb, skb->len - HELLCREEK_TAG_LEN))
|
||||
return NULL;
|
||||
|
||||
dsa_default_offload_fwd_mark(skb);
|
||||
|
||||
|
@ -21,7 +21,8 @@ static struct sk_buff *ksz_common_rcv(struct sk_buff *skb,
|
||||
if (!skb->dev)
|
||||
return NULL;
|
||||
|
||||
pskb_trim_rcsum(skb, skb->len - len);
|
||||
if (pskb_trim_rcsum(skb, skb->len - len))
|
||||
return NULL;
|
||||
|
||||
dsa_default_offload_fwd_mark(skb);
|
||||
|
||||
|
@ -665,7 +665,8 @@ static struct sk_buff *sja1110_rcv_inband_control_extension(struct sk_buff *skb,
|
||||
* padding and trailer we need to account for the fact that
|
||||
* skb->data points to skb_mac_header(skb) + ETH_HLEN.
|
||||
*/
|
||||
pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN);
|
||||
if (pskb_trim_rcsum(skb, start_of_padding - ETH_HLEN))
|
||||
return NULL;
|
||||
/* Trap-to-host frame, no timestamp trailer */
|
||||
} else {
|
||||
*source_port = SJA1110_RX_HEADER_SRC_PORT(rx_header);
|
||||
|
@ -841,6 +841,9 @@ static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!cfg->fc_table)
|
||||
cfg->fc_table = RT_TABLE_MAIN;
|
||||
|
||||
return 0;
|
||||
errout:
|
||||
return err;
|
||||
|
@ -423,6 +423,7 @@ static struct fib_info *fib_find_info(struct fib_info *nfi)
|
||||
nfi->fib_prefsrc == fi->fib_prefsrc &&
|
||||
nfi->fib_priority == fi->fib_priority &&
|
||||
nfi->fib_type == fi->fib_type &&
|
||||
nfi->fib_tb_id == fi->fib_tb_id &&
|
||||
memcmp(nfi->fib_metrics, fi->fib_metrics,
|
||||
sizeof(u32) * RTAX_MAX) == 0 &&
|
||||
!((nfi->fib_flags ^ fi->fib_flags) & ~RTNH_COMPARE_MASK) &&
|
||||
|
@ -1492,24 +1492,6 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||
struct ip_tunnel_parm *p = &t->parms;
|
||||
__be16 o_flags = p->o_flags;
|
||||
|
||||
if (t->erspan_ver <= 2) {
|
||||
if (t->erspan_ver != 0 && !t->collect_md)
|
||||
o_flags |= TUNNEL_KEY;
|
||||
|
||||
if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (t->erspan_ver == 1) {
|
||||
if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
|
||||
goto nla_put_failure;
|
||||
} else if (t->erspan_ver == 2) {
|
||||
if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (nla_put_u32(skb, IFLA_GRE_LINK, p->link) ||
|
||||
nla_put_be16(skb, IFLA_GRE_IFLAGS,
|
||||
gre_tnl_flags_to_gre_flags(p->i_flags)) ||
|
||||
@ -1550,6 +1532,34 @@ static int ipgre_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static int erspan_fill_info(struct sk_buff *skb, const struct net_device *dev)
|
||||
{
|
||||
struct ip_tunnel *t = netdev_priv(dev);
|
||||
|
||||
if (t->erspan_ver <= 2) {
|
||||
if (t->erspan_ver != 0 && !t->collect_md)
|
||||
t->parms.o_flags |= TUNNEL_KEY;
|
||||
|
||||
if (nla_put_u8(skb, IFLA_GRE_ERSPAN_VER, t->erspan_ver))
|
||||
goto nla_put_failure;
|
||||
|
||||
if (t->erspan_ver == 1) {
|
||||
if (nla_put_u32(skb, IFLA_GRE_ERSPAN_INDEX, t->index))
|
||||
goto nla_put_failure;
|
||||
} else if (t->erspan_ver == 2) {
|
||||
if (nla_put_u8(skb, IFLA_GRE_ERSPAN_DIR, t->dir))
|
||||
goto nla_put_failure;
|
||||
if (nla_put_u16(skb, IFLA_GRE_ERSPAN_HWID, t->hwid))
|
||||
goto nla_put_failure;
|
||||
}
|
||||
}
|
||||
|
||||
return ipgre_fill_info(skb, dev);
|
||||
|
||||
nla_put_failure:
|
||||
return -EMSGSIZE;
|
||||
}
|
||||
|
||||
static void erspan_setup(struct net_device *dev)
|
||||
{
|
||||
struct ip_tunnel *t = netdev_priv(dev);
|
||||
@ -1628,7 +1638,7 @@ static struct rtnl_link_ops erspan_link_ops __read_mostly = {
|
||||
.changelink = erspan_changelink,
|
||||
.dellink = ip_tunnel_dellink,
|
||||
.get_size = ipgre_get_size,
|
||||
.fill_info = ipgre_fill_info,
|
||||
.fill_info = erspan_fill_info,
|
||||
.get_link_net = ip_tunnel_get_link_net,
|
||||
};
|
||||
|
||||
|
@ -49,6 +49,11 @@
|
||||
#include <net/transp_v6.h>
|
||||
#endif
|
||||
|
||||
#define ping_portaddr_for_each_entry(__sk, node, list) \
|
||||
hlist_nulls_for_each_entry(__sk, node, list, sk_nulls_node)
|
||||
#define ping_portaddr_for_each_entry_rcu(__sk, node, list) \
|
||||
hlist_nulls_for_each_entry_rcu(__sk, node, list, sk_nulls_node)
|
||||
|
||||
struct ping_table {
|
||||
struct hlist_nulls_head hash[PING_HTABLE_SIZE];
|
||||
spinlock_t lock;
|
||||
@ -192,7 +197,7 @@ static struct sock *ping_lookup(struct net *net, struct sk_buff *skb, u16 ident)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ping_portaddr_for_each_entry(sk, hnode, hslot) {
|
||||
ping_portaddr_for_each_entry_rcu(sk, hnode, hslot) {
|
||||
isk = inet_sk(sk);
|
||||
|
||||
pr_debug("iterate\n");
|
||||
|
@ -920,6 +920,9 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
/* We prevent @rt from being freed. */
|
||||
rcu_read_lock();
|
||||
|
||||
for (;;) {
|
||||
/* Prepare header of the next frame,
|
||||
* before previous one went down. */
|
||||
@ -943,6 +946,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
||||
if (err == 0) {
|
||||
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
||||
IPSTATS_MIB_FRAGOKS);
|
||||
rcu_read_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -950,6 +954,7 @@ int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
|
||||
|
||||
IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
|
||||
IPSTATS_MIB_FRAGFAILS);
|
||||
rcu_read_unlock();
|
||||
return err;
|
||||
|
||||
slow_path_clean:
|
||||
|
@ -662,6 +662,7 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
|
||||
sdata->dev = ndev;
|
||||
sdata->wpan_dev.wpan_phy = local->hw.phy;
|
||||
sdata->local = local;
|
||||
INIT_LIST_HEAD(&sdata->wpan_dev.list);
|
||||
|
||||
/* setup type-dependent data */
|
||||
ret = ieee802154_setup_sdata(sdata, type);
|
||||
|
@ -891,7 +891,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
|
||||
zone = nf_ct_zone(ct);
|
||||
|
||||
if (!nf_ct_ext_valid_pre(ct->ext)) {
|
||||
NF_CT_STAT_INC(net, insert_failed);
|
||||
NF_CT_STAT_INC_ATOMIC(net, insert_failed);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -938,7 +938,7 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
|
||||
|
||||
if (!nf_ct_ext_valid_post(ct->ext)) {
|
||||
nf_ct_kill(ct);
|
||||
NF_CT_STAT_INC(net, drop);
|
||||
NF_CT_STAT_INC_ATOMIC(net, drop);
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
@ -1275,7 +1275,7 @@ __nf_conntrack_confirm(struct sk_buff *skb)
|
||||
*/
|
||||
if (!nf_ct_ext_valid_post(ct->ext)) {
|
||||
nf_ct_kill(ct);
|
||||
NF_CT_STAT_INC(net, drop);
|
||||
NF_CT_STAT_INC_ATOMIC(net, drop);
|
||||
return NF_DROP;
|
||||
}
|
||||
|
||||
|
@ -328,8 +328,13 @@ ctnetlink_dump_timestamp(struct sk_buff *skb, const struct nf_conn *ct)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
static int ctnetlink_dump_mark(struct sk_buff *skb, u32 mark)
|
||||
static int ctnetlink_dump_mark(struct sk_buff *skb, const struct nf_conn *ct)
|
||||
{
|
||||
u32 mark = READ_ONCE(ct->mark);
|
||||
|
||||
if (!mark)
|
||||
return 0;
|
||||
|
||||
if (nla_put_be32(skb, CTA_MARK, htonl(mark)))
|
||||
goto nla_put_failure;
|
||||
return 0;
|
||||
@ -543,7 +548,7 @@ static int ctnetlink_dump_extinfo(struct sk_buff *skb,
|
||||
static int ctnetlink_dump_info(struct sk_buff *skb, struct nf_conn *ct)
|
||||
{
|
||||
if (ctnetlink_dump_status(skb, ct) < 0 ||
|
||||
ctnetlink_dump_mark(skb, READ_ONCE(ct->mark)) < 0 ||
|
||||
ctnetlink_dump_mark(skb, ct) < 0 ||
|
||||
ctnetlink_dump_secctx(skb, ct) < 0 ||
|
||||
ctnetlink_dump_id(skb, ct) < 0 ||
|
||||
ctnetlink_dump_use(skb, ct) < 0 ||
|
||||
@ -722,7 +727,6 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
|
||||
struct sk_buff *skb;
|
||||
unsigned int type;
|
||||
unsigned int flags = 0, group;
|
||||
u32 mark;
|
||||
int err;
|
||||
|
||||
if (events & (1 << IPCT_DESTROY)) {
|
||||
@ -827,9 +831,8 @@ ctnetlink_conntrack_event(unsigned int events, const struct nf_ct_event *item)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
mark = READ_ONCE(ct->mark);
|
||||
if ((events & (1 << IPCT_MARK) || mark) &&
|
||||
ctnetlink_dump_mark(skb, mark) < 0)
|
||||
if (events & (1 << IPCT_MARK) &&
|
||||
ctnetlink_dump_mark(skb, ct) < 0)
|
||||
goto nla_put_failure;
|
||||
#endif
|
||||
nlmsg_end(skb, nlh);
|
||||
@ -2671,7 +2674,6 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
|
||||
{
|
||||
const struct nf_conntrack_zone *zone;
|
||||
struct nlattr *nest_parms;
|
||||
u32 mark;
|
||||
|
||||
zone = nf_ct_zone(ct);
|
||||
|
||||
@ -2733,8 +2735,7 @@ static int __ctnetlink_glue_build(struct sk_buff *skb, struct nf_conn *ct)
|
||||
goto nla_put_failure;
|
||||
|
||||
#ifdef CONFIG_NF_CONNTRACK_MARK
|
||||
mark = READ_ONCE(ct->mark);
|
||||
if (mark && ctnetlink_dump_mark(skb, mark) < 0)
|
||||
if (ctnetlink_dump_mark(skb, ct) < 0)
|
||||
goto nla_put_failure;
|
||||
#endif
|
||||
if (ctnetlink_dump_labels(skb, ct) < 0)
|
||||
|
@ -997,13 +997,13 @@ static void flow_offload_queue_work(struct flow_offload_work *offload)
|
||||
struct net *net = read_pnet(&offload->flowtable->net);
|
||||
|
||||
if (offload->cmd == FLOW_CLS_REPLACE) {
|
||||
NF_FLOW_TABLE_STAT_INC(net, count_wq_add);
|
||||
NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_add);
|
||||
queue_work(nf_flow_offload_add_wq, &offload->work);
|
||||
} else if (offload->cmd == FLOW_CLS_DESTROY) {
|
||||
NF_FLOW_TABLE_STAT_INC(net, count_wq_del);
|
||||
NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_del);
|
||||
queue_work(nf_flow_offload_del_wq, &offload->work);
|
||||
} else {
|
||||
NF_FLOW_TABLE_STAT_INC(net, count_wq_stats);
|
||||
NF_FLOW_TABLE_STAT_INC_ATOMIC(net, count_wq_stats);
|
||||
queue_work(nf_flow_offload_stats_wq, &offload->work);
|
||||
}
|
||||
}
|
||||
|
@ -1162,6 +1162,7 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
|
||||
struct nft_pipapo_match *m = priv->clone;
|
||||
u8 genmask = nft_genmask_next(net);
|
||||
struct nft_pipapo_field *f;
|
||||
const u8 *start_p, *end_p;
|
||||
int i, bsize_max, err = 0;
|
||||
|
||||
if (nft_set_ext_exists(ext, NFT_SET_EXT_KEY_END))
|
||||
@ -1202,9 +1203,9 @@ static int nft_pipapo_insert(const struct net *net, const struct nft_set *set,
|
||||
}
|
||||
|
||||
/* Validate */
|
||||
start_p = start;
|
||||
end_p = end;
|
||||
nft_pipapo_for_each_field(f, i, m) {
|
||||
const u8 *start_p = start, *end_p = end;
|
||||
|
||||
if (f->rules >= (unsigned long)NFT_PIPAPO_RULE0_MAX)
|
||||
return -ENOSPC;
|
||||
|
||||
|
@ -240,6 +240,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
|
||||
target->sens_res = nfca_poll->sens_res;
|
||||
target->sel_res = nfca_poll->sel_res;
|
||||
target->nfcid1_len = nfca_poll->nfcid1_len;
|
||||
if (target->nfcid1_len > ARRAY_SIZE(target->nfcid1))
|
||||
return -EPROTO;
|
||||
if (target->nfcid1_len > 0) {
|
||||
memcpy(target->nfcid1, nfca_poll->nfcid1,
|
||||
target->nfcid1_len);
|
||||
@ -248,6 +250,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
|
||||
nfcb_poll = (struct rf_tech_specific_params_nfcb_poll *)params;
|
||||
|
||||
target->sensb_res_len = nfcb_poll->sensb_res_len;
|
||||
if (target->sensb_res_len > ARRAY_SIZE(target->sensb_res))
|
||||
return -EPROTO;
|
||||
if (target->sensb_res_len > 0) {
|
||||
memcpy(target->sensb_res, nfcb_poll->sensb_res,
|
||||
target->sensb_res_len);
|
||||
@ -256,6 +260,8 @@ static int nci_add_new_protocol(struct nci_dev *ndev,
|
||||
nfcf_poll = (struct rf_tech_specific_params_nfcf_poll *)params;
|
||||
|
||||
target->sensf_res_len = nfcf_poll->sensf_res_len;
|
||||
if (target->sensf_res_len > ARRAY_SIZE(target->sensf_res))
|
||||
return -EPROTO;
|
||||
if (target->sensf_res_len > 0) {
|
||||
memcpy(target->sensf_res, nfcf_poll->sensf_res,
|
||||
target->sensf_res_len);
|
||||
|
@ -2224,7 +2224,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,
|
||||
if (tipc_own_addr(l->net) > msg_prevnode(hdr))
|
||||
l->net_plane = msg_net_plane(hdr);
|
||||
|
||||
skb_linearize(skb);
|
||||
if (skb_linearize(skb))
|
||||
goto exit;
|
||||
|
||||
hdr = buf_msg(skb);
|
||||
data = msg_data(hdr);
|
||||
|
||||
|
@ -1689,6 +1689,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
|
||||
struct tipc_node *n;
|
||||
struct sk_buff_head xmitq;
|
||||
bool node_up = false;
|
||||
struct net *peer_net;
|
||||
int bearer_id;
|
||||
int rc;
|
||||
|
||||
@ -1705,18 +1706,23 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list,
|
||||
return -EHOSTUNREACH;
|
||||
}
|
||||
|
||||
rcu_read_lock();
|
||||
tipc_node_read_lock(n);
|
||||
node_up = node_is_up(n);
|
||||
if (node_up && n->peer_net && check_net(n->peer_net)) {
|
||||
peer_net = n->peer_net;
|
||||
tipc_node_read_unlock(n);
|
||||
if (node_up && peer_net && check_net(peer_net)) {
|
||||
/* xmit inner linux container */
|
||||
tipc_lxc_xmit(n->peer_net, list);
|
||||
tipc_lxc_xmit(peer_net, list);
|
||||
if (likely(skb_queue_empty(list))) {
|
||||
tipc_node_read_unlock(n);
|
||||
rcu_read_unlock();
|
||||
tipc_node_put(n);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
tipc_node_read_lock(n);
|
||||
bearer_id = n->active_links[selector & 1];
|
||||
if (unlikely(bearer_id == INVALID_BEARER_ID)) {
|
||||
tipc_node_read_unlock(n);
|
||||
|
@ -114,14 +114,16 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
|
||||
return nla_put(nlskb, UNIX_DIAG_RQLEN, sizeof(rql), &rql);
|
||||
}
|
||||
|
||||
static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb)
|
||||
static int sk_diag_dump_uid(struct sock *sk, struct sk_buff *nlskb,
|
||||
struct user_namespace *user_ns)
|
||||
{
|
||||
uid_t uid = from_kuid_munged(sk_user_ns(nlskb->sk), sock_i_uid(sk));
|
||||
uid_t uid = from_kuid_munged(user_ns, sock_i_uid(sk));
|
||||
return nla_put(nlskb, UNIX_DIAG_UID, sizeof(uid_t), &uid);
|
||||
}
|
||||
|
||||
static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
|
||||
u32 portid, u32 seq, u32 flags, int sk_ino)
|
||||
struct user_namespace *user_ns,
|
||||
u32 portid, u32 seq, u32 flags, int sk_ino)
|
||||
{
|
||||
struct nlmsghdr *nlh;
|
||||
struct unix_diag_msg *rep;
|
||||
@ -167,7 +169,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
|
||||
goto out_nlmsg_trim;
|
||||
|
||||
if ((req->udiag_show & UDIAG_SHOW_UID) &&
|
||||
sk_diag_dump_uid(sk, skb))
|
||||
sk_diag_dump_uid(sk, skb, user_ns))
|
||||
goto out_nlmsg_trim;
|
||||
|
||||
nlmsg_end(skb, nlh);
|
||||
@ -179,7 +181,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
|
||||
}
|
||||
|
||||
static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
|
||||
u32 portid, u32 seq, u32 flags)
|
||||
struct user_namespace *user_ns,
|
||||
u32 portid, u32 seq, u32 flags)
|
||||
{
|
||||
int sk_ino;
|
||||
|
||||
@ -190,7 +193,7 @@ static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
|
||||
if (!sk_ino)
|
||||
return 0;
|
||||
|
||||
return sk_diag_fill(sk, skb, req, portid, seq, flags, sk_ino);
|
||||
return sk_diag_fill(sk, skb, req, user_ns, portid, seq, flags, sk_ino);
|
||||
}
|
||||
|
||||
static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
@ -214,7 +217,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
|
||||
goto next;
|
||||
if (!(req->udiag_states & (1 << sk->sk_state)))
|
||||
goto next;
|
||||
if (sk_diag_dump(sk, skb, req,
|
||||
if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
|
||||
NETLINK_CB(cb->skb).portid,
|
||||
cb->nlh->nlmsg_seq,
|
||||
NLM_F_MULTI) < 0) {
|
||||
@ -282,7 +285,8 @@ static int unix_diag_get_exact(struct sk_buff *in_skb,
|
||||
if (!rep)
|
||||
goto out;
|
||||
|
||||
err = sk_diag_fill(sk, rep, req, NETLINK_CB(in_skb).portid,
|
||||
err = sk_diag_fill(sk, rep, req, sk_user_ns(NETLINK_CB(in_skb).sk),
|
||||
NETLINK_CB(in_skb).portid,
|
||||
nlh->nlmsg_seq, 0, req->udiag_ino);
|
||||
if (err < 0) {
|
||||
nlmsg_free(rep);
|
||||
|
1
tools/testing/selftests/net/.gitignore
vendored
1
tools/testing/selftests/net/.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
bind_bhash
|
||||
cmsg_sender
|
||||
diag_uid
|
||||
fin_ack_lat
|
||||
gro
|
||||
hwtstamp_config
|
||||
|
@ -1,3 +1,3 @@
|
||||
TEST_GEN_PROGS := test_unix_oob unix_connect
|
||||
TEST_GEN_PROGS := diag_uid test_unix_oob unix_connect
|
||||
|
||||
include ../../lib.mk
|
||||
|
178
tools/testing/selftests/net/af_unix/diag_uid.c
Normal file
178
tools/testing/selftests/net/af_unix/diag_uid.c
Normal file
@ -0,0 +1,178 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/* Copyright Amazon.com Inc. or its affiliates. */
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/sock_diag.h>
|
||||
#include <linux/unix_diag.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include "../../kselftest_harness.h"
|
||||
|
||||
FIXTURE(diag_uid)
|
||||
{
|
||||
int netlink_fd;
|
||||
int unix_fd;
|
||||
__u32 inode;
|
||||
__u64 cookie;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT(diag_uid)
|
||||
{
|
||||
int unshare;
|
||||
int udiag_show;
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(diag_uid, uid)
|
||||
{
|
||||
.unshare = 0,
|
||||
.udiag_show = UDIAG_SHOW_UID
|
||||
};
|
||||
|
||||
FIXTURE_VARIANT_ADD(diag_uid, uid_unshare)
|
||||
{
|
||||
.unshare = CLONE_NEWUSER,
|
||||
.udiag_show = UDIAG_SHOW_UID
|
||||
};
|
||||
|
||||
FIXTURE_SETUP(diag_uid)
|
||||
{
|
||||
struct stat file_stat;
|
||||
socklen_t optlen;
|
||||
int ret;
|
||||
|
||||
if (variant->unshare)
|
||||
ASSERT_EQ(unshare(variant->unshare), 0);
|
||||
|
||||
self->netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
|
||||
ASSERT_NE(self->netlink_fd, -1);
|
||||
|
||||
self->unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
ASSERT_NE(self->unix_fd, -1);
|
||||
|
||||
ret = fstat(self->unix_fd, &file_stat);
|
||||
ASSERT_EQ(ret, 0);
|
||||
|
||||
self->inode = file_stat.st_ino;
|
||||
|
||||
optlen = sizeof(self->cookie);
|
||||
ret = getsockopt(self->unix_fd, SOL_SOCKET, SO_COOKIE, &self->cookie, &optlen);
|
||||
ASSERT_EQ(ret, 0);
|
||||
}
|
||||
|
||||
FIXTURE_TEARDOWN(diag_uid)
|
||||
{
|
||||
close(self->netlink_fd);
|
||||
close(self->unix_fd);
|
||||
}
|
||||
|
||||
int send_request(struct __test_metadata *_metadata,
|
||||
FIXTURE_DATA(diag_uid) *self,
|
||||
const FIXTURE_VARIANT(diag_uid) *variant)
|
||||
{
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
struct unix_diag_req udr;
|
||||
} req = {
|
||||
.nlh = {
|
||||
.nlmsg_len = sizeof(req),
|
||||
.nlmsg_type = SOCK_DIAG_BY_FAMILY,
|
||||
.nlmsg_flags = NLM_F_REQUEST
|
||||
},
|
||||
.udr = {
|
||||
.sdiag_family = AF_UNIX,
|
||||
.udiag_ino = self->inode,
|
||||
.udiag_cookie = {
|
||||
(__u32)self->cookie,
|
||||
(__u32)(self->cookie >> 32)
|
||||
},
|
||||
.udiag_show = variant->udiag_show
|
||||
}
|
||||
};
|
||||
struct sockaddr_nl nladdr = {
|
||||
.nl_family = AF_NETLINK
|
||||
};
|
||||
struct iovec iov = {
|
||||
.iov_base = &req,
|
||||
.iov_len = sizeof(req)
|
||||
};
|
||||
struct msghdr msg = {
|
||||
.msg_name = &nladdr,
|
||||
.msg_namelen = sizeof(nladdr),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1
|
||||
};
|
||||
|
||||
return sendmsg(self->netlink_fd, &msg, 0);
|
||||
}
|
||||
|
||||
void render_response(struct __test_metadata *_metadata,
|
||||
struct unix_diag_req *udr, __u32 len)
|
||||
{
|
||||
unsigned int rta_len = len - NLMSG_LENGTH(sizeof(*udr));
|
||||
struct rtattr *attr;
|
||||
uid_t uid;
|
||||
|
||||
ASSERT_GT(len, sizeof(*udr));
|
||||
ASSERT_EQ(udr->sdiag_family, AF_UNIX);
|
||||
|
||||
attr = (struct rtattr *)(udr + 1);
|
||||
ASSERT_NE(RTA_OK(attr, rta_len), 0);
|
||||
ASSERT_EQ(attr->rta_type, UNIX_DIAG_UID);
|
||||
|
||||
uid = *(uid_t *)RTA_DATA(attr);
|
||||
ASSERT_EQ(uid, getuid());
|
||||
}
|
||||
|
||||
void receive_response(struct __test_metadata *_metadata,
|
||||
FIXTURE_DATA(diag_uid) *self)
|
||||
{
|
||||
long buf[8192 / sizeof(long)];
|
||||
struct sockaddr_nl nladdr = {
|
||||
.nl_family = AF_NETLINK
|
||||
};
|
||||
struct iovec iov = {
|
||||
.iov_base = buf,
|
||||
.iov_len = sizeof(buf)
|
||||
};
|
||||
struct msghdr msg = {
|
||||
.msg_name = &nladdr,
|
||||
.msg_namelen = sizeof(nladdr),
|
||||
.msg_iov = &iov,
|
||||
.msg_iovlen = 1
|
||||
};
|
||||
struct unix_diag_req *udr;
|
||||
struct nlmsghdr *nlh;
|
||||
int ret;
|
||||
|
||||
ret = recvmsg(self->netlink_fd, &msg, 0);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
nlh = (struct nlmsghdr *)buf;
|
||||
ASSERT_NE(NLMSG_OK(nlh, ret), 0);
|
||||
ASSERT_EQ(nlh->nlmsg_type, SOCK_DIAG_BY_FAMILY);
|
||||
|
||||
render_response(_metadata, NLMSG_DATA(nlh), nlh->nlmsg_len);
|
||||
|
||||
nlh = NLMSG_NEXT(nlh, ret);
|
||||
ASSERT_EQ(NLMSG_OK(nlh, ret), 0);
|
||||
}
|
||||
|
||||
TEST_F(diag_uid, 1)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = send_request(_metadata, self, variant);
|
||||
ASSERT_GT(ret, 0);
|
||||
|
||||
receive_response(_metadata, self);
|
||||
}
|
||||
|
||||
TEST_HARNESS_MAIN
|
@ -43,5 +43,5 @@ CONFIG_NET_ACT_TUNNEL_KEY=m
|
||||
CONFIG_NET_ACT_MIRRED=m
|
||||
CONFIG_BAREUDP=m
|
||||
CONFIG_IPV6_IOAM6_LWTUNNEL=y
|
||||
CONFIG_CRYPTO_SM4=y
|
||||
CONFIG_CRYPTO_SM4_GENERIC=y
|
||||
CONFIG_AMT=m
|
||||
|
@ -1711,13 +1711,21 @@ ipv4_del_addr_test()
|
||||
|
||||
$IP addr add dev dummy1 172.16.104.1/24
|
||||
$IP addr add dev dummy1 172.16.104.11/24
|
||||
$IP addr add dev dummy1 172.16.104.12/24
|
||||
$IP addr add dev dummy1 172.16.104.13/24
|
||||
$IP addr add dev dummy2 172.16.104.1/24
|
||||
$IP addr add dev dummy2 172.16.104.11/24
|
||||
$IP addr add dev dummy2 172.16.104.12/24
|
||||
$IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
|
||||
$IP route add 172.16.106.0/24 dev lo src 172.16.104.12
|
||||
$IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13
|
||||
$IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11
|
||||
$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
|
||||
set +e
|
||||
|
||||
# removing address from device in vrf should only remove route from vrf table
|
||||
echo " Regular FIB info"
|
||||
|
||||
$IP addr del dev dummy2 172.16.104.11/24
|
||||
$IP ro ls vrf red | grep -q 172.16.105.0/24
|
||||
log_test $? 1 "Route removed from VRF when source address deleted"
|
||||
@ -1735,6 +1743,35 @@ ipv4_del_addr_test()
|
||||
$IP ro ls vrf red | grep -q 172.16.105.0/24
|
||||
log_test $? 0 "Route in VRF is not removed by address delete"
|
||||
|
||||
# removing address from device in vrf should only remove route from vrf
|
||||
# table even when the associated fib info only differs in table ID
|
||||
echo " Identical FIB info with different table ID"
|
||||
|
||||
$IP addr del dev dummy2 172.16.104.12/24
|
||||
$IP ro ls vrf red | grep -q 172.16.106.0/24
|
||||
log_test $? 1 "Route removed from VRF when source address deleted"
|
||||
|
||||
$IP ro ls | grep -q 172.16.106.0/24
|
||||
log_test $? 0 "Route in default VRF not removed"
|
||||
|
||||
$IP addr add dev dummy2 172.16.104.12/24
|
||||
$IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12
|
||||
|
||||
$IP addr del dev dummy1 172.16.104.12/24
|
||||
$IP ro ls | grep -q 172.16.106.0/24
|
||||
log_test $? 1 "Route removed in default VRF when source address deleted"
|
||||
|
||||
$IP ro ls vrf red | grep -q 172.16.106.0/24
|
||||
log_test $? 0 "Route in VRF is not removed by address delete"
|
||||
|
||||
# removing address from device in default vrf should remove route from
|
||||
# the default vrf even when route was inserted with a table ID of 0.
|
||||
echo " Table ID 0"
|
||||
|
||||
$IP addr del dev dummy1 172.16.104.13/24
|
||||
$IP ro ls | grep -q 172.16.107.0/24
|
||||
log_test $? 1 "Route removed in default VRF when source address deleted"
|
||||
|
||||
$IP li del dummy1
|
||||
$IP li del dummy2
|
||||
cleanup
|
||||
|
@ -782,7 +782,7 @@ kci_test_ipsec_offload()
|
||||
tmpl proto esp src $srcip dst $dstip spi 9 \
|
||||
mode transport reqid 42
|
||||
check_err $?
|
||||
ip x p add dir out src $dstip/24 dst $srcip/24 \
|
||||
ip x p add dir in src $dstip/24 dst $srcip/24 \
|
||||
tmpl proto esp src $dstip dst $srcip spi 9 \
|
||||
mode transport reqid 42
|
||||
check_err $?
|
||||
|
@ -32,7 +32,7 @@ DEV="eth0"
|
||||
# This is determined by reading the RSS indirection table using ethtool.
|
||||
get_rss_cfg_num_rxqs() {
|
||||
echo $(ethtool -x "${DEV}" |
|
||||
egrep [[:space:]]+[0-9]+:[[:space:]]+ |
|
||||
grep -E [[:space:]]+[0-9]+:[[:space:]]+ |
|
||||
cut -d: -f2- |
|
||||
awk '{$1=$1};1' |
|
||||
tr ' ' '\n' |
|
||||
|
Loading…
Reference in New Issue
Block a user