Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net

Pull networking fixes from David Miller:
 "Nothing earth shattering here, lots of small fixes (f.e. missing RCU
  protection, bad ref counting, missing memset(), etc.) all over the
  place:

   1) Use get_file_rcu() in task_file iterator, from Yonghong Song.

   2) There are two ways to set remote source MAC addresses in macvlan
      driver, but only one of which validates things properly. Fix this.
      From Alvin Šipraga.

   3) Missing of_node_put() in gianfar probing, from Sumera
      Priyadarsini.

   4) Preserve device wanted feature bits across multiple netlink
      ethtool requests, from Maxim Mikityanskiy.

   5) Fix rcu_sched stall in task and task_file bpf iterators, from
      Yonghong Song.

   6) Avoid reset after device destroy in ena driver, from Shay
      Agroskin.

   7) Missing memset() in netlink policy export reallocation path, from
      Johannes Berg.

   8) Fix info leak in __smc_diag_dump(), from Peilin Ye.

   9) Decapsulate ECN properly for ipv6 in ipv4 tunnels, from Mark
      Tomlinson.

  10) Fix number of data stream negotiation in SCTP, from David Laight.

  11) Fix double free in connection tracker action module, from Alaa
      Hleihel.

  12) Don't allow empty NHA_GROUP attributes, from Nikolay Aleksandrov"

* git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (46 commits)
  net: nexthop: don't allow empty NHA_GROUP
  bpf: Fix two typos in uapi/linux/bpf.h
  net: dsa: b53: check for timeout
  tipc: call rcu_read_lock() in tipc_aead_encrypt_done()
  net/sched: act_ct: Fix skb double-free in tcf_ct_handle_fragments() error flow
  net: sctp: Fix negotiation of the number of data streams.
  dt-bindings: net: renesas, ether: Improve schema validation
  gre6: Fix reception with IP6_TNL_F_RCV_DSCP_COPY
  hv_netvsc: Fix the queue_mapping in netvsc_vf_xmit()
  hv_netvsc: Remove "unlikely" from netvsc_select_queue
  bpf: selftests: global_funcs: Check err_str before strstr
  bpf: xdp: Fix XDP mode when no mode flags specified
  selftests/bpf: Remove test_align leftovers
  tools/resolve_btfids: Fix sections with wrong alignment
  net/smc: Prevent kernel-infoleak in __smc_diag_dump()
  sfc: fix build warnings on 32-bit
  net: phy: mscc: Fix a couple of spelling mistakes "spcified" -> "specified"
  libbpf: Fix map index used in error message
  net: gemini: Fix missing free_netdev() in error path of gemini_ethernet_port_probe()
  net: atlantic: Use readx_poll_timeout() for large timeout
  ...
This commit is contained in:
Linus Torvalds 2020-08-23 10:52:33 -07:00
commit 9d045ed1eb
44 changed files with 310 additions and 163 deletions

View File

@ -59,9 +59,15 @@ properties:
clocks:
maxItems: 1
pinctrl-0: true
power-domains:
maxItems: 1
pinctrl-names: true
resets:
maxItems: 1
phy-mode: true
phy-handle: true
renesas,no-ether-link:
type: boolean
@ -74,6 +80,11 @@ properties:
specify when the Ether LINK signal is active-low instead of normal
active-high
patternProperties:
"^ethernet-phy@[0-9a-f]$":
type: object
$ref: ethernet-phy.yaml#
required:
- compatible
- reg
@ -83,7 +94,8 @@ required:
- '#address-cells'
- '#size-cells'
- clocks
- pinctrl-0
additionalProperties: false
examples:
# Lager board
@ -99,8 +111,6 @@ examples:
clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
phy-mode = "rmii";
phy-handle = <&phy1>;
pinctrl-0 = <&ether_pins>;
pinctrl-names = "default";
renesas,ether-link-active-low;
#address-cells = <1>;
#size-cells = <0>;
@ -109,7 +119,5 @@ examples:
reg = <1>;
interrupt-parent = <&irqc0>;
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
pinctrl-0 = <&phy1_pins>;
pinctrl-names = "default";
};
};

View File

@ -2948,6 +2948,9 @@ static int bond_ab_arp_inspect(struct bonding *bond)
if (bond_time_in_interval(bond, last_rx, 1)) {
bond_propose_link_state(slave, BOND_LINK_UP);
commit++;
} else if (slave->link == BOND_LINK_BACK) {
bond_propose_link_state(slave, BOND_LINK_FAIL);
commit++;
}
continue;
}
@ -3056,6 +3059,19 @@ static void bond_ab_arp_commit(struct bonding *bond)
continue;
case BOND_LINK_FAIL:
bond_set_slave_link_state(slave, BOND_LINK_FAIL,
BOND_SLAVE_NOTIFY_NOW);
bond_set_slave_inactive_flags(slave,
BOND_SLAVE_NOTIFY_NOW);
/* A slave has just been enslaved and has become
* the current active slave.
*/
if (rtnl_dereference(bond->curr_active_slave))
RCU_INIT_POINTER(bond->current_arp_slave, NULL);
continue;
default:
slave_err(bond->dev, slave->dev,
"impossible: link_new_state %d on slave\n",
@ -3106,8 +3122,6 @@ static bool bond_ab_arp_probe(struct bonding *bond)
return should_notify_rtnl;
}
bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER);
bond_for_each_slave_rcu(bond, slave, iter) {
if (!found && !before && bond_slave_is_up(slave))
before = slave;

View File

@ -1554,6 +1554,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
return ret;
switch (ret) {
case -ETIMEDOUT:
return ret;
case -ENOSPC:
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
addr, vid);

View File

@ -9,7 +9,7 @@ config NET_DSA_MSCC_FELIX
select NET_DSA_TAG_OCELOT
select FSL_ENETC_MDIO
help
This driver supports network switches from the the Vitesse /
This driver supports network switches from the Vitesse /
Microsemi / Microchip Ocelot family of switching cores that are
connected to their host CPU via Ethernet.
The following switches are supported:

View File

@ -2180,12 +2180,9 @@ static void ena_del_napi_in_range(struct ena_adapter *adapter,
int i;
for (i = first_index; i < first_index + count; i++) {
/* Check if napi was initialized before */
if (!ENA_IS_XDP_INDEX(adapter, i) ||
adapter->ena_napi[i].xdp_ring)
netif_napi_del(&adapter->ena_napi[i].napi);
else
WARN_ON(ENA_IS_XDP_INDEX(adapter, i) &&
WARN_ON(!ENA_IS_XDP_INDEX(adapter, i) &&
adapter->ena_napi[i].xdp_ring);
}
}
@ -3601,16 +3598,14 @@ static void ena_fw_reset_device(struct work_struct *work)
{
struct ena_adapter *adapter =
container_of(work, struct ena_adapter, reset_task);
struct pci_dev *pdev = adapter->pdev;
if (unlikely(!test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
dev_err(&pdev->dev,
"device reset schedule while reset bit is off\n");
return;
}
rtnl_lock();
if (likely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
ena_destroy_device(adapter, false);
ena_restore_device(adapter);
}
rtnl_unlock();
}
@ -3692,7 +3687,7 @@ static int check_missing_comp_in_tx_queue(struct ena_adapter *adapter,
}
u64_stats_update_begin(&tx_ring->syncp);
tx_ring->tx_stats.missed_tx = missed_tx;
tx_ring->tx_stats.missed_tx += missed_tx;
u64_stats_update_end(&tx_ring->syncp);
return rc;
@ -4389,8 +4384,11 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown)
netdev->rx_cpu_rmap = NULL;
}
#endif /* CONFIG_RFS_ACCEL */
del_timer_sync(&adapter->timer_service);
/* Make sure timer and reset routine won't be called after
* freeing device resources.
*/
del_timer_sync(&adapter->timer_service);
cancel_work_sync(&adapter->reset_task);
rtnl_lock(); /* lock released inside the below if-else block */
@ -4558,6 +4556,9 @@ static void ena_keep_alive_wd(void *adapter_data,
tx_drops = ((u64)desc->tx_drops_high << 32) | desc->tx_drops_low;
u64_stats_update_begin(&adapter->syncp);
/* These stats are accumulated by the device, so the counters indicate
* all drops since last reset.
*/
adapter->dev_stats.rx_drops = rx_drops;
adapter->dev_stats.tx_drops = tx_drops;
u64_stats_update_end(&adapter->syncp);

View File

@ -1631,8 +1631,8 @@ static int hw_atl_b0_get_mac_temp(struct aq_hw_s *self, u32 *temp)
hw_atl_ts_reset_set(self, 0);
}
err = readx_poll_timeout_atomic(hw_atl_b0_ts_ready_and_latch_high_get,
self, val, val == 1, 10000U, 500000U);
err = readx_poll_timeout(hw_atl_b0_ts_ready_and_latch_high_get, self,
val, val == 1, 10000U, 500000U);
if (err)
return err;

View File

@ -2553,19 +2553,22 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
pkt_len = ETH_HLEN + sizeof(CXGB4_SELFTEST_LB_STR);
flits = DIV_ROUND_UP(pkt_len + sizeof(struct cpl_tx_pkt) +
sizeof(*wr), sizeof(__be64));
flits = DIV_ROUND_UP(pkt_len + sizeof(*cpl) + sizeof(*wr),
sizeof(__be64));
ndesc = flits_to_desc(flits);
lb = &pi->ethtool_lb;
lb->loopback = 1;
q = &adap->sge.ethtxq[pi->first_qset];
__netif_tx_lock(q->txq, smp_processor_id());
reclaim_completed_tx(adap, &q->q, -1, true);
credits = txq_avail(&q->q) - ndesc;
if (unlikely(credits < 0))
if (unlikely(credits < 0)) {
__netif_tx_unlock(q->txq);
return -ENOMEM;
}
wr = (void *)&q->q.desc[q->q.pidx];
memset(wr, 0, sizeof(struct tx_desc));
@ -2598,6 +2601,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
init_completion(&lb->completion);
txq_advance(&q->q, ndesc);
cxgb4_ring_tx_db(adap, &q->q, ndesc);
__netif_tx_unlock(q->txq);
/* wait for the pkt to return */
ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);

View File

@ -2389,7 +2389,7 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev)
dev_info(dev, "probe %s ID %d\n", dev_name(dev), id);
netdev = alloc_etherdev_mq(sizeof(*port), TX_QUEUE_NUM);
netdev = devm_alloc_etherdev_mqs(dev, sizeof(*port), TX_QUEUE_NUM, TX_QUEUE_NUM);
if (!netdev) {
dev_err(dev, "Can't allocate ethernet device #%d\n", id);
return -ENOMEM;
@ -2521,7 +2521,6 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev)
}
port->netdev = NULL;
free_netdev(netdev);
return ret;
}
@ -2530,7 +2529,6 @@ static int gemini_ethernet_port_remove(struct platform_device *pdev)
struct gemini_ethernet_port *port = platform_get_drvdata(pdev);
gemini_port_remove(port);
free_netdev(port->netdev);
return 0;
}

View File

@ -750,9 +750,11 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
continue;
err = gfar_parse_group(child, priv, model);
if (err)
if (err) {
of_node_put(child);
goto err_grp_init;
}
}
} else { /* SQ_SG_MODE */
err = gfar_parse_group(np, priv, model);
if (err)

View File

@ -142,7 +142,7 @@ static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_locatio
/* Temporarily map new BAR. */
rc = efx_init_io(efx, bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
(dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
@ -160,7 +160,7 @@ static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_locatio
/* Put old BAR back. */
rc = efx_init_io(efx, previous_bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
(dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, previous_bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
@ -334,7 +334,7 @@ static int ef100_pci_parse_xilinx_cap(struct efx_nic *efx, int vndr_cap,
/* Temporarily map BAR. */
rc = efx_init_io(efx, bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
(dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, bar));
if (rc) {
netif_err(efx, probe, efx->net_dev,
@ -495,7 +495,7 @@ static int ef100_pci_probe(struct pci_dev *pci_dev,
/* Set up basic I/O (BAR mappings etc) */
rc = efx_init_io(efx, fcw.bar,
DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
(dma_addr_t)DMA_BIT_MASK(ESF_GZ_TX_SEND_ADDR_WIDTH),
pci_resource_len(efx->pci_dev, fcw.bar));
if (rc)
goto fail;

View File

@ -431,18 +431,18 @@ static int ef100_reset(struct efx_nic *efx, enum reset_type reset_type)
/* A RESET_TYPE_ALL will cause filters to be removed, so we remove filters
* and reprobe after reset to avoid removing filters twice
*/
down_read(&efx->filter_sem);
down_write(&efx->filter_sem);
ef100_filter_table_down(efx);
up_read(&efx->filter_sem);
up_write(&efx->filter_sem);
rc = efx_mcdi_reset(efx, reset_type);
if (rc)
return rc;
netif_device_attach(efx->net_dev);
down_read(&efx->filter_sem);
down_write(&efx->filter_sem);
rc = ef100_filter_table_up(efx);
up_read(&efx->filter_sem);
up_write(&efx->filter_sem);
if (rc)
return rc;
@ -739,6 +739,7 @@ const struct efx_nic_type ef100_pf_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = ef100_rx_write,
.rx_packet = __ef100_rx_packet,
.rx_buf_hash_valid = ef100_rx_buf_hash_valid,
.fini_dmaq = efx_fini_dmaq,
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
.filter_table_probe = ef100_filter_table_up,
@ -820,6 +821,7 @@ const struct efx_nic_type ef100_vf_nic_type = {
.rx_remove = efx_mcdi_rx_remove,
.rx_write = ef100_rx_write,
.rx_packet = __ef100_rx_packet,
.rx_buf_hash_valid = ef100_rx_buf_hash_valid,
.fini_dmaq = efx_fini_dmaq,
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
.filter_table_probe = ef100_filter_table_up,

View File

@ -846,6 +846,7 @@ struct efx_async_filter_insertion {
* @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
* @timer_max_ns: Interrupt timer maximum value, in nanoseconds
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
* @irqs_hooked: Channel interrupts are hooked
* @irq_rx_mod_step_us: Step size for IRQ moderation for RX event queues
* @irq_rx_moderation_us: IRQ moderation time for RX event queues
* @msg_enable: Log message enable flags
@ -1004,6 +1005,7 @@ struct efx_nic {
unsigned int timer_quantum_ns;
unsigned int timer_max_ns;
bool irq_rx_adaptive;
bool irqs_hooked;
unsigned int irq_mod_step_us;
unsigned int irq_rx_moderation_us;
u32 msg_enable;

View File

@ -129,6 +129,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
#endif
}
efx->irqs_hooked = true;
return 0;
fail2:
@ -154,6 +155,8 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
efx->net_dev->rx_cpu_rmap = NULL;
#endif
if (!efx->irqs_hooked)
return;
if (EFX_INT_MODE_USE_MSI(efx)) {
/* Disable MSI/MSI-X interrupts */
efx_for_each_channel(channel, efx)
@ -163,6 +166,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
/* Disable legacy interrupt */
free_irq(efx->legacy_irq, efx);
}
efx->irqs_hooked = false;
}
/* Register dump */

View File

@ -849,6 +849,7 @@ void efx_remove_filters(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
cancel_delayed_work_sync(&channel->filter_work);
kfree(channel->rps_flow_id);
channel->rps_flow_id = NULL;
}
#endif
down_write(&efx->filter_sem);

View File

@ -367,7 +367,7 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
}
rcu_read_unlock();
while (unlikely(txq >= ndev->real_num_tx_queues))
while (txq >= ndev->real_num_tx_queues)
txq -= ndev->real_num_tx_queues;
return txq;
@ -502,7 +502,7 @@ static int netvsc_vf_xmit(struct net_device *net, struct net_device *vf_netdev,
int rc;
skb->dev = vf_netdev;
skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping;
skb_record_rx_queue(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping);
rc = dev_queue_xmit(skb);
if (likely(rc == NET_XMIT_SUCCESS || rc == NET_XMIT_CN)) {

View File

@ -1269,6 +1269,9 @@ static void macvlan_port_destroy(struct net_device *dev)
static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack)
{
struct nlattr *nla, *head;
int rem, len;
if (tb[IFLA_ADDRESS]) {
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
return -EINVAL;
@ -1316,6 +1319,20 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
return -EADDRNOTAVAIL;
}
if (data[IFLA_MACVLAN_MACADDR_DATA]) {
head = nla_data(data[IFLA_MACVLAN_MACADDR_DATA]);
len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
nla_for_each_attr(nla, head, len, rem) {
if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
nla_len(nla) != ETH_ALEN)
return -EINVAL;
if (!is_valid_ether_addr(nla_data(nla)))
return -EADDRNOTAVAIL;
}
}
if (data[IFLA_MACVLAN_MACADDR_COUNT])
return -EINVAL;
@ -1372,10 +1389,6 @@ static int macvlan_changelink_sources(struct macvlan_dev *vlan, u32 mode,
len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
nla_for_each_attr(nla, head, len, rem) {
if (nla_type(nla) != IFLA_MACVLAN_MACADDR ||
nla_len(nla) != ETH_ALEN)
continue;
addr = nla_data(nla);
ret = macvlan_hash_add_source(vlan, addr);
if (ret)

View File

@ -1738,13 +1738,13 @@ static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
return 0;
}
/* Trigger a read to the spcified MCB */
/* Trigger a read to the specified MCB */
static int phy_update_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
{
return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_READ);
}
/* Trigger a write to the spcified MCB */
/* Trigger a write to the specified MCB */
static int phy_commit_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb)
{
return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);

View File

@ -142,16 +142,15 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
return result;
}
static int idtcm_xfer(struct idtcm *idtcm,
static int idtcm_xfer_read(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
u16 count,
bool write)
u16 count)
{
struct i2c_client *client = idtcm->client;
struct i2c_msg msg[2];
int cnt;
char *fmt = "i2c_transfer failed at %d in %s for %s, at addr: %04X!\n";
char *fmt = "i2c_transfer failed at %d in %s, at addr: %04X!\n";
msg[0].addr = client->addr;
msg[0].flags = 0;
@ -159,7 +158,7 @@ static int idtcm_xfer(struct idtcm *idtcm,
msg[0].buf = &regaddr;
msg[1].addr = client->addr;
msg[1].flags = write ? 0 : I2C_M_RD;
msg[1].flags = I2C_M_RD;
msg[1].len = count;
msg[1].buf = buf;
@ -170,7 +169,6 @@ static int idtcm_xfer(struct idtcm *idtcm,
fmt,
__LINE__,
__func__,
write ? "write" : "read",
regaddr);
return cnt;
} else if (cnt != 2) {
@ -182,6 +180,37 @@ static int idtcm_xfer(struct idtcm *idtcm,
return 0;
}
static int idtcm_xfer_write(struct idtcm *idtcm,
u8 regaddr,
u8 *buf,
u16 count)
{
struct i2c_client *client = idtcm->client;
/* we add 1 byte for device register */
u8 msg[IDTCM_MAX_WRITE_COUNT + 1];
int cnt;
char *fmt = "i2c_master_send failed at %d in %s, at addr: %04X!\n";
if (count > IDTCM_MAX_WRITE_COUNT)
return -EINVAL;
msg[0] = regaddr;
memcpy(&msg[1], buf, count);
cnt = i2c_master_send(client, msg, count + 1);
if (cnt < 0) {
dev_err(&client->dev,
fmt,
__LINE__,
__func__,
regaddr);
return cnt;
}
return 0;
}
static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
{
u8 buf[4];
@ -195,7 +224,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
buf[2] = 0x10;
buf[3] = 0x20;
err = idtcm_xfer(idtcm, PAGE_ADDR, buf, sizeof(buf), 1);
err = idtcm_xfer_write(idtcm, PAGE_ADDR, buf, sizeof(buf));
if (err) {
idtcm->page_offset = 0xff;
@ -223,11 +252,12 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
err = idtcm_page_offset(idtcm, hi);
if (err)
goto out;
err = idtcm_xfer(idtcm, lo, buf, count, write);
out:
return err;
if (write)
return idtcm_xfer_write(idtcm, lo, buf, count);
return idtcm_xfer_read(idtcm, lo, buf, count);
}
static int idtcm_read(struct idtcm *idtcm,

View File

@ -55,6 +55,8 @@
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
#define IDTCM_MAX_WRITE_COUNT (512)
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
enum pll_mode {
PLL_MODE_MIN = 0,

View File

@ -97,7 +97,8 @@ bool ipv6_chk_custom_prefix(const struct in6_addr *addr,
int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev);
struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr);
struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr,
struct net_device *dev);
struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
const struct in6_addr *addr,

View File

@ -767,7 +767,7 @@ union bpf_attr {
*
* Also, note that **bpf_trace_printk**\ () is slow, and should
* only be used for debugging purposes. For this reason, a notice
* bloc (spanning several lines) is printed to kernel logs and
* block (spanning several lines) is printed to kernel logs and
* states that the helper should not be used "for production use"
* the first time this helper is used (or more precisely, when
* **trace_printk**\ () buffers are allocated). For passing values
@ -1147,7 +1147,7 @@ union bpf_attr {
* Description
* Retrieve the realm or the route, that is to say the
* **tclassid** field of the destination for the *skb*. The
* indentifier retrieved is a user-provided tag, similar to the
* identifier retrieved is a user-provided tag, similar to the
* one used with the net_cls cgroup (see description for
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
* held by a route (a destination entry), not by a task.

View File

@ -67,6 +67,9 @@ static void bpf_iter_done_stop(struct seq_file *seq)
iter_priv->done_stop = true;
}
/* maximum visited objects before bailing out */
#define MAX_ITER_OBJECTS 1000000
/* bpf_seq_read, a customized and simpler version for bpf iterator.
* no_llseek is assumed for this file.
* The following are differences from seq_read():
@ -79,7 +82,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
{
struct seq_file *seq = file->private_data;
size_t n, offs, copied = 0;
int err = 0;
int err = 0, num_objs = 0;
void *p;
mutex_lock(&seq->lock);
@ -135,6 +138,7 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
while (1) {
loff_t pos = seq->index;
num_objs++;
offs = seq->count;
p = seq->op->next(seq, p, &seq->index);
if (pos == seq->index) {
@ -153,6 +157,15 @@ static ssize_t bpf_seq_read(struct file *file, char __user *buf, size_t size,
if (seq->count >= size)
break;
if (num_objs >= MAX_ITER_OBJECTS) {
if (offs == 0) {
err = -EAGAIN;
seq->op->stop(seq, p);
goto done;
}
break;
}
err = seq->op->show(seq, p);
if (err > 0) {
bpf_iter_dec_seq_num(seq);

View File

@ -29,8 +29,9 @@ static struct task_struct *task_seq_get_next(struct pid_namespace *ns,
rcu_read_lock();
retry:
pid = idr_get_next(&ns->idr, tid);
pid = find_ge_pid(*tid, ns);
if (pid) {
*tid = pid_nr_ns(pid, ns);
task = get_pid_task(pid, PIDTYPE_PID);
if (!task) {
++*tid;
@ -178,10 +179,11 @@ again:
f = fcheck_files(curr_files, curr_fd);
if (!f)
continue;
if (!get_file_rcu(f))
continue;
/* set info->fd */
info->fd = curr_fd;
get_file(f);
rcu_read_unlock();
return f;
}

View File

@ -8742,13 +8742,15 @@ struct bpf_xdp_link {
int flags;
};
static enum bpf_xdp_mode dev_xdp_mode(u32 flags)
static enum bpf_xdp_mode dev_xdp_mode(struct net_device *dev, u32 flags)
{
if (flags & XDP_FLAGS_HW_MODE)
return XDP_MODE_HW;
if (flags & XDP_FLAGS_DRV_MODE)
return XDP_MODE_DRV;
if (flags & XDP_FLAGS_SKB_MODE)
return XDP_MODE_SKB;
return dev->netdev_ops->ndo_bpf ? XDP_MODE_DRV : XDP_MODE_SKB;
}
static bpf_op_t dev_xdp_bpf_op(struct net_device *dev, enum bpf_xdp_mode mode)
@ -8896,7 +8898,7 @@ static int dev_xdp_attach(struct net_device *dev, struct netlink_ext_ack *extack
return -EINVAL;
}
mode = dev_xdp_mode(flags);
mode = dev_xdp_mode(dev, flags);
/* can't replace attached link */
if (dev_xdp_link(dev, mode)) {
NL_SET_ERR_MSG(extack, "Can't replace active BPF XDP link");
@ -8984,7 +8986,7 @@ static int dev_xdp_detach_link(struct net_device *dev,
ASSERT_RTNL();
mode = dev_xdp_mode(link->flags);
mode = dev_xdp_mode(dev, link->flags);
if (dev_xdp_link(dev, mode) != link)
return -EINVAL;
@ -9080,7 +9082,7 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
goto out_unlock;
}
mode = dev_xdp_mode(xdp_link->flags);
mode = dev_xdp_mode(xdp_link->dev, xdp_link->flags);
bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
xdp_link->flags, new_prog);
@ -9164,7 +9166,7 @@ out_put_dev:
int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
int fd, int expected_fd, u32 flags)
{
enum bpf_xdp_mode mode = dev_xdp_mode(flags);
enum bpf_xdp_mode mode = dev_xdp_mode(dev, flags);
struct bpf_prog *new_prog = NULL, *old_prog = NULL;
int err;

View File

@ -5987,9 +5987,13 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
if (skb_has_frag_list(skb))
skb_clone_fraglist(skb);
if (k == 0) {
/* split line is in frag list */
pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask);
if (k == 0 && pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask)) {
/* skb_frag_unref() is not needed here as shinfo->nr_frags = 0. */
if (skb_has_frag_list(skb))
kfree_skb_list(skb_shinfo(skb)->frag_list);
kfree(data);
return -ENOMEM;
}
skb_release_data(skb);

View File

@ -224,7 +224,9 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
DECLARE_BITMAP(wanted_diff_mask, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(old_active, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(old_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(new_active, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(new_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1];
@ -250,6 +252,7 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
rtnl_lock();
ethnl_features_to_bitmap(old_active, dev->features);
ethnl_features_to_bitmap(old_wanted, dev->wanted_features);
ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
tb[ETHTOOL_A_FEATURES_WANTED],
netdev_features_strings, info->extack);
@ -261,17 +264,15 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
goto out_rtnl;
}
/* set req_wanted bits not in req_mask from old_active */
/* set req_wanted bits not in req_mask from old_wanted */
bitmap_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT);
bitmap_andnot(new_active, old_active, req_mask, NETDEV_FEATURE_COUNT);
bitmap_or(req_wanted, new_active, req_wanted, NETDEV_FEATURE_COUNT);
if (bitmap_equal(req_wanted, old_active, NETDEV_FEATURE_COUNT)) {
ret = 0;
goto out_rtnl;
}
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
dev->wanted_features &= ~dev->hw_features;
dev->wanted_features |= ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
__netdev_update_features(dev);
}
ethnl_features_to_bitmap(new_active, dev->features);
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);

View File

@ -661,13 +661,13 @@ config TCP_CONG_BBR
BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to
maximize network utilization and minimize queues. It builds an explicit
model of the the bottleneck delivery rate and path round-trip
propagation delay. It tolerates packet loss and delay unrelated to
congestion. It can operate over LAN, WAN, cellular, wifi, or cable
modem links. It can coexist with flows that use loss-based congestion
control, and can operate with shallow buffers, deep buffers,
bufferbloat, policers, or AQM schemes that do not provide a delay
signal. It requires the fq ("Fair Queue") pacing packet scheduler.
model of the bottleneck delivery rate and path round-trip propagation
delay. It tolerates packet loss and delay unrelated to congestion. It
can operate over LAN, WAN, cellular, wifi, or cable modem links. It can
coexist with flows that use loss-based congestion control, and can
operate with shallow buffers, deep buffers, bufferbloat, policers, or
AQM schemes that do not provide a delay signal. It requires the fq
("Fair Queue") pacing packet scheduler.
choice
prompt "Default TCP congestion control"

View File

@ -446,7 +446,7 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[],
unsigned int i, j;
u8 nhg_fdb = 0;
if (len & (sizeof(struct nexthop_grp) - 1)) {
if (!len || len & (sizeof(struct nexthop_grp) - 1)) {
NL_SET_ERR_MSG(extack,
"Invalid length for nexthop group attribute");
return -EINVAL;
@ -1187,6 +1187,9 @@ static struct nexthop *nexthop_create_group(struct net *net,
struct nexthop *nh;
int i;
if (WARN_ON(!num_nh))
return ERR_PTR(-EINVAL);
nh = nexthop_alloc();
if (!nh)
return ERR_PTR(-ENOMEM);

View File

@ -1893,12 +1893,13 @@ EXPORT_SYMBOL(ipv6_chk_addr);
* 2. does the address exist on the specific device
* (skip_dev_check = false)
*/
int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
static struct net_device *
__ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, bool skip_dev_check,
int strict, u32 banned_flags)
{
unsigned int hash = inet6_addr_hash(net, addr);
const struct net_device *l3mdev;
struct net_device *l3mdev, *ndev;
struct inet6_ifaddr *ifp;
u32 ifp_flags;
@ -1909,10 +1910,11 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
dev = NULL;
hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
if (!net_eq(dev_net(ifp->idev->dev), net))
ndev = ifp->idev->dev;
if (!net_eq(dev_net(ndev), net))
continue;
if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
if (l3mdev_master_dev_rcu(ndev) != l3mdev)
continue;
/* Decouple optimistic from tentative for evaluation here.
@ -1923,15 +1925,23 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
: ifp->flags;
if (ipv6_addr_equal(&ifp->addr, addr) &&
!(ifp_flags&banned_flags) &&
(!dev || ifp->idev->dev == dev ||
(!dev || ndev == dev ||
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
rcu_read_unlock();
return 1;
return ndev;
}
}
rcu_read_unlock();
return 0;
return NULL;
}
int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
const struct net_device *dev, bool skip_dev_check,
int strict, u32 banned_flags)
{
return __ipv6_chk_addr_and_flags(net, addr, dev, skip_dev_check,
strict, banned_flags) ? 1 : 0;
}
EXPORT_SYMBOL(ipv6_chk_addr_and_flags);
@ -1990,35 +2000,11 @@ EXPORT_SYMBOL(ipv6_chk_prefix);
*
* The caller should be protected by RCU, or RTNL.
*/
struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr)
struct net_device *ipv6_dev_find(struct net *net, const struct in6_addr *addr,
struct net_device *dev)
{
unsigned int hash = inet6_addr_hash(net, addr);
struct inet6_ifaddr *ifp, *result = NULL;
struct net_device *dev = NULL;
rcu_read_lock();
hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
if (net_eq(dev_net(ifp->idev->dev), net) &&
ipv6_addr_equal(&ifp->addr, addr)) {
result = ifp;
break;
}
}
if (!result) {
struct rt6_info *rt;
rt = rt6_lookup(net, addr, NULL, 0, NULL, 0);
if (rt) {
dev = rt->dst.dev;
ip6_rt_put(rt);
}
} else {
dev = result->idev->dev;
}
rcu_read_unlock();
return dev;
return __ipv6_chk_addr_and_flags(net, addr, dev, !dev, 1,
IFA_F_TENTATIVE);
}
EXPORT_SYMBOL(ipv6_dev_find);

View File

@ -915,7 +915,15 @@ int ip6_tnl_rcv(struct ip6_tnl *t, struct sk_buff *skb,
struct metadata_dst *tun_dst,
bool log_ecn_err)
{
return __ip6_tnl_rcv(t, skb, tpi, tun_dst, ip6ip6_dscp_ecn_decapsulate,
int (*dscp_ecn_decapsulate)(const struct ip6_tnl *t,
const struct ipv6hdr *ipv6h,
struct sk_buff *skb);
dscp_ecn_decapsulate = ip6ip6_dscp_ecn_decapsulate;
if (tpi->proto == htons(ETH_P_IP))
dscp_ecn_decapsulate = ip4ip6_dscp_ecn_decapsulate;
return __ip6_tnl_rcv(t, skb, tpi, tun_dst, dscp_ecn_decapsulate,
log_ecn_err);
}
EXPORT_SYMBOL(ip6_tnl_rcv);

View File

@ -51,6 +51,9 @@ static int add_policy(struct nl_policy_dump **statep,
if (!state)
return -ENOMEM;
memset(&state->policies[state->n_alloc], 0,
flex_array_size(state, policies, n_alloc - state->n_alloc));
state->policies[state->n_alloc].policy = policy;
state->policies[state->n_alloc].maxtype = maxtype;
state->n_alloc = n_alloc;

View File

@ -704,7 +704,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
err = ip_defrag(net, skb, user);
local_bh_enable();
if (err && err != -EINPROGRESS)
goto out_free;
return err;
if (!err) {
*defrag = true;

View File

@ -88,12 +88,13 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
int ret;
if (outcnt <= stream->outcnt)
return 0;
goto out;
ret = genradix_prealloc(&stream->out, outcnt, gfp);
if (ret)
return ret;
out:
stream->outcnt = outcnt;
return 0;
}
@ -104,12 +105,13 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt,
int ret;
if (incnt <= stream->incnt)
return 0;
goto out;
ret = genradix_prealloc(&stream->in, incnt, gfp);
if (ret)
return ret;
out:
stream->incnt = incnt;
return 0;
}

View File

@ -170,13 +170,15 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
(req->diag_ext & (1 << (SMC_DIAG_DMBINFO - 1))) &&
!list_empty(&smc->conn.lgr->list)) {
struct smc_connection *conn = &smc->conn;
struct smcd_diag_dmbinfo dinfo = {
.linkid = *((u32 *)conn->lgr->id),
.peer_gid = conn->lgr->peer_gid,
.my_gid = conn->lgr->smcd->local_gid,
.token = conn->rmb_desc->token,
.peer_token = conn->peer_token
};
struct smcd_diag_dmbinfo dinfo;
memset(&dinfo, 0, sizeof(dinfo));
dinfo.linkid = *((u32 *)conn->lgr->id);
dinfo.peer_gid = conn->lgr->peer_gid;
dinfo.my_gid = conn->lgr->smcd->local_gid;
dinfo.token = conn->rmb_desc->token;
dinfo.peer_token = conn->peer_token;
if (nla_put(skb, SMC_DIAG_DMBINFO, sizeof(dinfo), &dinfo) < 0)
goto errout;

View File

@ -757,10 +757,12 @@ static void tipc_aead_encrypt_done(struct crypto_async_request *base, int err)
switch (err) {
case 0:
this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]);
rcu_read_lock();
if (likely(test_bit(0, &b->up)))
b->media->send_msg(net, skb, b, &tx_ctx->dst);
else
kfree_skb(skb);
rcu_read_unlock();
break;
case -EINPROGRESS:
return;

View File

@ -660,6 +660,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
struct udp_tunnel_sock_cfg tuncfg = {NULL};
struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
u8 node_id[NODE_ID_LEN] = {0,};
struct net_device *dev;
int rmcast = 0;
ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
@ -714,8 +715,6 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
rcu_assign_pointer(ub->bearer, b);
tipc_udp_media_addr_set(&b->addr, &local);
if (local.proto == htons(ETH_P_IP)) {
struct net_device *dev;
dev = __ip_dev_find(net, local.ipv4.s_addr, false);
if (!dev) {
err = -ENODEV;
@ -738,9 +737,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
b->mtu = b->media->mtu;
#if IS_ENABLED(CONFIG_IPV6)
} else if (local.proto == htons(ETH_P_IPV6)) {
struct net_device *dev;
dev = ipv6_dev_find(net, &local.ipv6);
dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
dev = ipv6_dev_find(net, &local.ipv6, dev);
if (!dev) {
err = -ENODEV;
goto err;

View File

@ -134,6 +134,8 @@ int build_obj_refs_table(struct obj_refs_table *table, enum bpf_obj_type type)
while (true) {
ret = read(fd, buf, sizeof(buf));
if (ret < 0) {
if (errno == EAGAIN)
continue;
err = -errno;
p_err("failed to read PID iterator output: %d", err);
goto out;

View File

@ -233,6 +233,39 @@ static struct btf_id *add_symbol(struct rb_root *root, char *name, size_t size)
return btf_id__add(root, id, false);
}
/*
* The data of compressed section should be aligned to 4
* (for 32bit) or 8 (for 64 bit) bytes. The binutils ld
* sets sh_addralign to 1, which makes libelf fail with
* misaligned section error during the update:
* FAILED elf_update(WRITE): invalid section alignment
*
* While waiting for ld fix, we fix the compressed sections
* sh_addralign value manualy.
*/
static int compressed_section_fix(Elf *elf, Elf_Scn *scn, GElf_Shdr *sh)
{
int expected = gelf_getclass(elf) == ELFCLASS32 ? 4 : 8;
if (!(sh->sh_flags & SHF_COMPRESSED))
return 0;
if (sh->sh_addralign == expected)
return 0;
pr_debug2(" - fixing wrong alignment sh_addralign %u, expected %u\n",
sh->sh_addralign, expected);
sh->sh_addralign = expected;
if (gelf_update_shdr(scn, sh) == 0) {
printf("FAILED cannot update section header: %s\n",
elf_errmsg(-1));
return -1;
}
return 0;
}
static int elf_collect(struct object *obj)
{
Elf_Scn *scn = NULL;
@ -309,6 +342,9 @@ static int elf_collect(struct object *obj)
obj->efile.idlist_shndx = idx;
obj->efile.idlist_addr = sh.sh_addr;
}
if (compressed_section_fix(elf, scn, &sh))
return -1;
}
return 0;

View File

@ -767,7 +767,7 @@ union bpf_attr {
*
* Also, note that **bpf_trace_printk**\ () is slow, and should
* only be used for debugging purposes. For this reason, a notice
* bloc (spanning several lines) is printed to kernel logs and
* block (spanning several lines) is printed to kernel logs and
* states that the helper should not be used "for production use"
* the first time this helper is used (or more precisely, when
* **trace_printk**\ () buffers are allocated). For passing values
@ -1147,7 +1147,7 @@ union bpf_attr {
* Description
* Retrieve the realm or the route, that is to say the
* **tclassid** field of the destination for the *skb*. The
* indentifier retrieved is a user-provided tag, similar to the
* identifier retrieved is a user-provided tag, similar to the
* one used with the net_cls cgroup (see description for
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
* held by a route (a destination entry), not by a task.

View File

@ -879,7 +879,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
btf_dump_printf(d, ": %d", m_sz);
off = m_off + m_sz;
} else {
m_sz = max(0LL, btf__resolve_size(d->btf, m->type));
m_sz = max((__s64)0, btf__resolve_size(d->btf, m->type));
off = m_off + m_sz * 8;
}
btf_dump_printf(d, ";");

View File

@ -2264,7 +2264,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,
data = elf_getdata(scn, NULL);
if (!scn || !data) {
pr_warn("failed to get Elf_Data from map section %d (%s)\n",
obj->efile.maps_shndx, MAPS_ELF_SEC);
obj->efile.btf_maps_shndx, MAPS_ELF_SEC);
return -EINVAL;
}

View File

@ -6,7 +6,6 @@ test_lpm_map
test_tag
FEATURE-DUMP.libbpf
fixdep
test_align
test_dev_cgroup
/test_progs*
test_tcpbpf_user

View File

@ -32,7 +32,7 @@ LDLIBS += -lcap -lelf -lz -lrt -lpthread
# Order correspond to 'make run_tests' order
TEST_GEN_PROGS = test_verifier test_tag test_maps test_lru_map test_lpm_map test_progs \
test_align test_verifier_log test_dev_cgroup test_tcpbpf_user \
test_verifier_log test_dev_cgroup test_tcpbpf_user \
test_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
test_cgroup_storage \
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl \

View File

@ -19,7 +19,7 @@ static int libbpf_debug_print(enum libbpf_print_level level,
log_buf = va_arg(args, char *);
if (!log_buf)
goto out;
if (strstr(log_buf, err_str) == 0)
if (err_str && strstr(log_buf, err_str) == 0)
found = true;
out:
printf(format, log_buf);