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:
commit
9d045ed1eb
|
@ -59,9 +59,15 @@ properties:
|
||||||
clocks:
|
clocks:
|
||||||
maxItems: 1
|
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:
|
renesas,no-ether-link:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
@ -74,6 +80,11 @@ properties:
|
||||||
specify when the Ether LINK signal is active-low instead of normal
|
specify when the Ether LINK signal is active-low instead of normal
|
||||||
active-high
|
active-high
|
||||||
|
|
||||||
|
patternProperties:
|
||||||
|
"^ethernet-phy@[0-9a-f]$":
|
||||||
|
type: object
|
||||||
|
$ref: ethernet-phy.yaml#
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
|
@ -83,7 +94,8 @@ required:
|
||||||
- '#address-cells'
|
- '#address-cells'
|
||||||
- '#size-cells'
|
- '#size-cells'
|
||||||
- clocks
|
- clocks
|
||||||
- pinctrl-0
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
# Lager board
|
# Lager board
|
||||||
|
@ -99,8 +111,6 @@ examples:
|
||||||
clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
|
clocks = <&mstp8_clks R8A7790_CLK_ETHER>;
|
||||||
phy-mode = "rmii";
|
phy-mode = "rmii";
|
||||||
phy-handle = <&phy1>;
|
phy-handle = <&phy1>;
|
||||||
pinctrl-0 = <ðer_pins>;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
renesas,ether-link-active-low;
|
renesas,ether-link-active-low;
|
||||||
#address-cells = <1>;
|
#address-cells = <1>;
|
||||||
#size-cells = <0>;
|
#size-cells = <0>;
|
||||||
|
@ -109,7 +119,5 @@ examples:
|
||||||
reg = <1>;
|
reg = <1>;
|
||||||
interrupt-parent = <&irqc0>;
|
interrupt-parent = <&irqc0>;
|
||||||
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
interrupts = <0 IRQ_TYPE_LEVEL_LOW>;
|
||||||
pinctrl-0 = <&phy1_pins>;
|
|
||||||
pinctrl-names = "default";
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -2948,6 +2948,9 @@ static int bond_ab_arp_inspect(struct bonding *bond)
|
||||||
if (bond_time_in_interval(bond, last_rx, 1)) {
|
if (bond_time_in_interval(bond, last_rx, 1)) {
|
||||||
bond_propose_link_state(slave, BOND_LINK_UP);
|
bond_propose_link_state(slave, BOND_LINK_UP);
|
||||||
commit++;
|
commit++;
|
||||||
|
} else if (slave->link == BOND_LINK_BACK) {
|
||||||
|
bond_propose_link_state(slave, BOND_LINK_FAIL);
|
||||||
|
commit++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -3056,6 +3059,19 @@ static void bond_ab_arp_commit(struct bonding *bond)
|
||||||
|
|
||||||
continue;
|
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:
|
default:
|
||||||
slave_err(bond->dev, slave->dev,
|
slave_err(bond->dev, slave->dev,
|
||||||
"impossible: link_new_state %d on slave\n",
|
"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;
|
return should_notify_rtnl;
|
||||||
}
|
}
|
||||||
|
|
||||||
bond_set_slave_inactive_flags(curr_arp_slave, BOND_SLAVE_NOTIFY_LATER);
|
|
||||||
|
|
||||||
bond_for_each_slave_rcu(bond, slave, iter) {
|
bond_for_each_slave_rcu(bond, slave, iter) {
|
||||||
if (!found && !before && bond_slave_is_up(slave))
|
if (!found && !before && bond_slave_is_up(slave))
|
||||||
before = slave;
|
before = slave;
|
||||||
|
|
|
@ -1554,6 +1554,8 @@ static int b53_arl_op(struct b53_device *dev, int op, int port,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
|
case -ETIMEDOUT:
|
||||||
|
return ret;
|
||||||
case -ENOSPC:
|
case -ENOSPC:
|
||||||
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
|
dev_dbg(dev->dev, "{%pM,%.4d} no space left in ARL\n",
|
||||||
addr, vid);
|
addr, vid);
|
||||||
|
|
|
@ -9,7 +9,7 @@ config NET_DSA_MSCC_FELIX
|
||||||
select NET_DSA_TAG_OCELOT
|
select NET_DSA_TAG_OCELOT
|
||||||
select FSL_ENETC_MDIO
|
select FSL_ENETC_MDIO
|
||||||
help
|
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
|
Microsemi / Microchip Ocelot family of switching cores that are
|
||||||
connected to their host CPU via Ethernet.
|
connected to their host CPU via Ethernet.
|
||||||
The following switches are supported:
|
The following switches are supported:
|
||||||
|
|
|
@ -2180,13 +2180,10 @@ static void ena_del_napi_in_range(struct ena_adapter *adapter,
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = first_index; i < first_index + count; i++) {
|
for (i = first_index; i < first_index + count; i++) {
|
||||||
/* Check if napi was initialized before */
|
netif_napi_del(&adapter->ena_napi[i].napi);
|
||||||
if (!ENA_IS_XDP_INDEX(adapter, i) ||
|
|
||||||
adapter->ena_napi[i].xdp_ring)
|
WARN_ON(!ENA_IS_XDP_INDEX(adapter, i) &&
|
||||||
netif_napi_del(&adapter->ena_napi[i].napi);
|
adapter->ena_napi[i].xdp_ring);
|
||||||
else
|
|
||||||
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 =
|
struct ena_adapter *adapter =
|
||||||
container_of(work, struct ena_adapter, reset_task);
|
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();
|
rtnl_lock();
|
||||||
ena_destroy_device(adapter, false);
|
|
||||||
ena_restore_device(adapter);
|
if (likely(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags))) {
|
||||||
|
ena_destroy_device(adapter, false);
|
||||||
|
ena_restore_device(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
rtnl_unlock();
|
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);
|
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);
|
u64_stats_update_end(&tx_ring->syncp);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -4389,8 +4384,11 @@ static void __ena_shutoff(struct pci_dev *pdev, bool shutdown)
|
||||||
netdev->rx_cpu_rmap = NULL;
|
netdev->rx_cpu_rmap = NULL;
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_RFS_ACCEL */
|
#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);
|
cancel_work_sync(&adapter->reset_task);
|
||||||
|
|
||||||
rtnl_lock(); /* lock released inside the below if-else block */
|
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;
|
tx_drops = ((u64)desc->tx_drops_high << 32) | desc->tx_drops_low;
|
||||||
|
|
||||||
u64_stats_update_begin(&adapter->syncp);
|
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.rx_drops = rx_drops;
|
||||||
adapter->dev_stats.tx_drops = tx_drops;
|
adapter->dev_stats.tx_drops = tx_drops;
|
||||||
u64_stats_update_end(&adapter->syncp);
|
u64_stats_update_end(&adapter->syncp);
|
||||||
|
|
|
@ -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);
|
hw_atl_ts_reset_set(self, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
err = readx_poll_timeout_atomic(hw_atl_b0_ts_ready_and_latch_high_get,
|
err = readx_poll_timeout(hw_atl_b0_ts_ready_and_latch_high_get, self,
|
||||||
self, val, val == 1, 10000U, 500000U);
|
val, val == 1, 10000U, 500000U);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
|
@ -2553,19 +2553,22 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
|
||||||
|
|
||||||
pkt_len = ETH_HLEN + sizeof(CXGB4_SELFTEST_LB_STR);
|
pkt_len = ETH_HLEN + sizeof(CXGB4_SELFTEST_LB_STR);
|
||||||
|
|
||||||
flits = DIV_ROUND_UP(pkt_len + sizeof(struct cpl_tx_pkt) +
|
flits = DIV_ROUND_UP(pkt_len + sizeof(*cpl) + sizeof(*wr),
|
||||||
sizeof(*wr), sizeof(__be64));
|
sizeof(__be64));
|
||||||
ndesc = flits_to_desc(flits);
|
ndesc = flits_to_desc(flits);
|
||||||
|
|
||||||
lb = &pi->ethtool_lb;
|
lb = &pi->ethtool_lb;
|
||||||
lb->loopback = 1;
|
lb->loopback = 1;
|
||||||
|
|
||||||
q = &adap->sge.ethtxq[pi->first_qset];
|
q = &adap->sge.ethtxq[pi->first_qset];
|
||||||
|
__netif_tx_lock(q->txq, smp_processor_id());
|
||||||
|
|
||||||
reclaim_completed_tx(adap, &q->q, -1, true);
|
reclaim_completed_tx(adap, &q->q, -1, true);
|
||||||
credits = txq_avail(&q->q) - ndesc;
|
credits = txq_avail(&q->q) - ndesc;
|
||||||
if (unlikely(credits < 0))
|
if (unlikely(credits < 0)) {
|
||||||
|
__netif_tx_unlock(q->txq);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
wr = (void *)&q->q.desc[q->q.pidx];
|
wr = (void *)&q->q.desc[q->q.pidx];
|
||||||
memset(wr, 0, sizeof(struct tx_desc));
|
memset(wr, 0, sizeof(struct tx_desc));
|
||||||
|
@ -2598,6 +2601,7 @@ int cxgb4_selftest_lb_pkt(struct net_device *netdev)
|
||||||
init_completion(&lb->completion);
|
init_completion(&lb->completion);
|
||||||
txq_advance(&q->q, ndesc);
|
txq_advance(&q->q, ndesc);
|
||||||
cxgb4_ring_tx_db(adap, &q->q, ndesc);
|
cxgb4_ring_tx_db(adap, &q->q, ndesc);
|
||||||
|
__netif_tx_unlock(q->txq);
|
||||||
|
|
||||||
/* wait for the pkt to return */
|
/* wait for the pkt to return */
|
||||||
ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
|
ret = wait_for_completion_timeout(&lb->completion, 10 * HZ);
|
||||||
|
|
|
@ -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);
|
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) {
|
if (!netdev) {
|
||||||
dev_err(dev, "Can't allocate ethernet device #%d\n", id);
|
dev_err(dev, "Can't allocate ethernet device #%d\n", id);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -2521,7 +2521,6 @@ static int gemini_ethernet_port_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
port->netdev = NULL;
|
port->netdev = NULL;
|
||||||
free_netdev(netdev);
|
|
||||||
return ret;
|
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);
|
struct gemini_ethernet_port *port = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
gemini_port_remove(port);
|
gemini_port_remove(port);
|
||||||
free_netdev(port->netdev);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -750,8 +750,10 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
err = gfar_parse_group(child, priv, model);
|
err = gfar_parse_group(child, priv, model);
|
||||||
if (err)
|
if (err) {
|
||||||
|
of_node_put(child);
|
||||||
goto err_grp_init;
|
goto err_grp_init;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else { /* SQ_SG_MODE */
|
} else { /* SQ_SG_MODE */
|
||||||
err = gfar_parse_group(np, priv, model);
|
err = gfar_parse_group(np, priv, model);
|
||||||
|
|
|
@ -142,7 +142,7 @@ static int ef100_pci_parse_continue_entry(struct efx_nic *efx, int entry_locatio
|
||||||
|
|
||||||
/* Temporarily map new BAR. */
|
/* Temporarily map new BAR. */
|
||||||
rc = efx_init_io(efx, 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));
|
pci_resource_len(efx->pci_dev, bar));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netif_err(efx, probe, efx->net_dev,
|
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. */
|
/* Put old BAR back. */
|
||||||
rc = efx_init_io(efx, previous_bar,
|
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));
|
pci_resource_len(efx->pci_dev, previous_bar));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netif_err(efx, probe, efx->net_dev,
|
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. */
|
/* Temporarily map BAR. */
|
||||||
rc = efx_init_io(efx, 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));
|
pci_resource_len(efx->pci_dev, bar));
|
||||||
if (rc) {
|
if (rc) {
|
||||||
netif_err(efx, probe, efx->net_dev,
|
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) */
|
/* Set up basic I/O (BAR mappings etc) */
|
||||||
rc = efx_init_io(efx, fcw.bar,
|
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));
|
pci_resource_len(efx->pci_dev, fcw.bar));
|
||||||
if (rc)
|
if (rc)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
|
@ -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
|
/* A RESET_TYPE_ALL will cause filters to be removed, so we remove filters
|
||||||
* and reprobe after reset to avoid removing filters twice
|
* and reprobe after reset to avoid removing filters twice
|
||||||
*/
|
*/
|
||||||
down_read(&efx->filter_sem);
|
down_write(&efx->filter_sem);
|
||||||
ef100_filter_table_down(efx);
|
ef100_filter_table_down(efx);
|
||||||
up_read(&efx->filter_sem);
|
up_write(&efx->filter_sem);
|
||||||
rc = efx_mcdi_reset(efx, reset_type);
|
rc = efx_mcdi_reset(efx, reset_type);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
netif_device_attach(efx->net_dev);
|
netif_device_attach(efx->net_dev);
|
||||||
|
|
||||||
down_read(&efx->filter_sem);
|
down_write(&efx->filter_sem);
|
||||||
rc = ef100_filter_table_up(efx);
|
rc = ef100_filter_table_up(efx);
|
||||||
up_read(&efx->filter_sem);
|
up_write(&efx->filter_sem);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
@ -739,6 +739,7 @@ const struct efx_nic_type ef100_pf_nic_type = {
|
||||||
.rx_remove = efx_mcdi_rx_remove,
|
.rx_remove = efx_mcdi_rx_remove,
|
||||||
.rx_write = ef100_rx_write,
|
.rx_write = ef100_rx_write,
|
||||||
.rx_packet = __ef100_rx_packet,
|
.rx_packet = __ef100_rx_packet,
|
||||||
|
.rx_buf_hash_valid = ef100_rx_buf_hash_valid,
|
||||||
.fini_dmaq = efx_fini_dmaq,
|
.fini_dmaq = efx_fini_dmaq,
|
||||||
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
|
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
|
||||||
.filter_table_probe = ef100_filter_table_up,
|
.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_remove = efx_mcdi_rx_remove,
|
||||||
.rx_write = ef100_rx_write,
|
.rx_write = ef100_rx_write,
|
||||||
.rx_packet = __ef100_rx_packet,
|
.rx_packet = __ef100_rx_packet,
|
||||||
|
.rx_buf_hash_valid = ef100_rx_buf_hash_valid,
|
||||||
.fini_dmaq = efx_fini_dmaq,
|
.fini_dmaq = efx_fini_dmaq,
|
||||||
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
|
.max_rx_ip_filters = EFX_MCDI_FILTER_TBL_ROWS,
|
||||||
.filter_table_probe = ef100_filter_table_up,
|
.filter_table_probe = ef100_filter_table_up,
|
||||||
|
|
|
@ -846,6 +846,7 @@ struct efx_async_filter_insertion {
|
||||||
* @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
|
* @timer_quantum_ns: Interrupt timer quantum, in nanoseconds
|
||||||
* @timer_max_ns: Interrupt timer maximum value, in nanoseconds
|
* @timer_max_ns: Interrupt timer maximum value, in nanoseconds
|
||||||
* @irq_rx_adaptive: Adaptive IRQ moderation enabled for RX event queues
|
* @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_mod_step_us: Step size for IRQ moderation for RX event queues
|
||||||
* @irq_rx_moderation_us: IRQ moderation time for RX event queues
|
* @irq_rx_moderation_us: IRQ moderation time for RX event queues
|
||||||
* @msg_enable: Log message enable flags
|
* @msg_enable: Log message enable flags
|
||||||
|
@ -1004,6 +1005,7 @@ struct efx_nic {
|
||||||
unsigned int timer_quantum_ns;
|
unsigned int timer_quantum_ns;
|
||||||
unsigned int timer_max_ns;
|
unsigned int timer_max_ns;
|
||||||
bool irq_rx_adaptive;
|
bool irq_rx_adaptive;
|
||||||
|
bool irqs_hooked;
|
||||||
unsigned int irq_mod_step_us;
|
unsigned int irq_mod_step_us;
|
||||||
unsigned int irq_rx_moderation_us;
|
unsigned int irq_rx_moderation_us;
|
||||||
u32 msg_enable;
|
u32 msg_enable;
|
||||||
|
|
|
@ -129,6 +129,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
efx->irqs_hooked = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail2:
|
fail2:
|
||||||
|
@ -154,6 +155,8 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
|
||||||
efx->net_dev->rx_cpu_rmap = NULL;
|
efx->net_dev->rx_cpu_rmap = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!efx->irqs_hooked)
|
||||||
|
return;
|
||||||
if (EFX_INT_MODE_USE_MSI(efx)) {
|
if (EFX_INT_MODE_USE_MSI(efx)) {
|
||||||
/* Disable MSI/MSI-X interrupts */
|
/* Disable MSI/MSI-X interrupts */
|
||||||
efx_for_each_channel(channel, efx)
|
efx_for_each_channel(channel, efx)
|
||||||
|
@ -163,6 +166,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
|
||||||
/* Disable legacy interrupt */
|
/* Disable legacy interrupt */
|
||||||
free_irq(efx->legacy_irq, efx);
|
free_irq(efx->legacy_irq, efx);
|
||||||
}
|
}
|
||||||
|
efx->irqs_hooked = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Register dump */
|
/* Register dump */
|
||||||
|
|
|
@ -849,6 +849,7 @@ void efx_remove_filters(struct efx_nic *efx)
|
||||||
efx_for_each_channel(channel, efx) {
|
efx_for_each_channel(channel, efx) {
|
||||||
cancel_delayed_work_sync(&channel->filter_work);
|
cancel_delayed_work_sync(&channel->filter_work);
|
||||||
kfree(channel->rps_flow_id);
|
kfree(channel->rps_flow_id);
|
||||||
|
channel->rps_flow_id = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
down_write(&efx->filter_sem);
|
down_write(&efx->filter_sem);
|
||||||
|
|
|
@ -367,7 +367,7 @@ static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
|
||||||
}
|
}
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
while (unlikely(txq >= ndev->real_num_tx_queues))
|
while (txq >= ndev->real_num_tx_queues)
|
||||||
txq -= ndev->real_num_tx_queues;
|
txq -= ndev->real_num_tx_queues;
|
||||||
|
|
||||||
return txq;
|
return txq;
|
||||||
|
@ -502,7 +502,7 @@ static int netvsc_vf_xmit(struct net_device *net, struct net_device *vf_netdev,
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
skb->dev = vf_netdev;
|
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);
|
rc = dev_queue_xmit(skb);
|
||||||
if (likely(rc == NET_XMIT_SUCCESS || rc == NET_XMIT_CN)) {
|
if (likely(rc == NET_XMIT_SUCCESS || rc == NET_XMIT_CN)) {
|
||||||
|
|
|
@ -1269,6 +1269,9 @@ static void macvlan_port_destroy(struct net_device *dev)
|
||||||
static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
|
static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
|
struct nlattr *nla, *head;
|
||||||
|
int rem, len;
|
||||||
|
|
||||||
if (tb[IFLA_ADDRESS]) {
|
if (tb[IFLA_ADDRESS]) {
|
||||||
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
|
if (nla_len(tb[IFLA_ADDRESS]) != ETH_ALEN)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1316,6 +1319,20 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[],
|
||||||
return -EADDRNOTAVAIL;
|
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])
|
if (data[IFLA_MACVLAN_MACADDR_COUNT])
|
||||||
return -EINVAL;
|
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]);
|
len = nla_len(data[IFLA_MACVLAN_MACADDR_DATA]);
|
||||||
|
|
||||||
nla_for_each_attr(nla, head, len, rem) {
|
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);
|
addr = nla_data(nla);
|
||||||
ret = macvlan_hash_add_source(vlan, addr);
|
ret = macvlan_hash_add_source(vlan, addr);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -1738,13 +1738,13 @@ static int __phy_write_mcb_s6g(struct phy_device *phydev, u32 reg, u8 mcb,
|
||||||
return 0;
|
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)
|
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);
|
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)
|
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);
|
return __phy_write_mcb_s6g(phydev, reg, mcb, PHY_MCB_S6G_WRITE);
|
||||||
|
|
|
@ -142,16 +142,15 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idtcm_xfer(struct idtcm *idtcm,
|
static int idtcm_xfer_read(struct idtcm *idtcm,
|
||||||
u8 regaddr,
|
u8 regaddr,
|
||||||
u8 *buf,
|
u8 *buf,
|
||||||
u16 count,
|
u16 count)
|
||||||
bool write)
|
|
||||||
{
|
{
|
||||||
struct i2c_client *client = idtcm->client;
|
struct i2c_client *client = idtcm->client;
|
||||||
struct i2c_msg msg[2];
|
struct i2c_msg msg[2];
|
||||||
int cnt;
|
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].addr = client->addr;
|
||||||
msg[0].flags = 0;
|
msg[0].flags = 0;
|
||||||
|
@ -159,7 +158,7 @@ static int idtcm_xfer(struct idtcm *idtcm,
|
||||||
msg[0].buf = ®addr;
|
msg[0].buf = ®addr;
|
||||||
|
|
||||||
msg[1].addr = client->addr;
|
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].len = count;
|
||||||
msg[1].buf = buf;
|
msg[1].buf = buf;
|
||||||
|
|
||||||
|
@ -170,7 +169,6 @@ static int idtcm_xfer(struct idtcm *idtcm,
|
||||||
fmt,
|
fmt,
|
||||||
__LINE__,
|
__LINE__,
|
||||||
__func__,
|
__func__,
|
||||||
write ? "write" : "read",
|
|
||||||
regaddr);
|
regaddr);
|
||||||
return cnt;
|
return cnt;
|
||||||
} else if (cnt != 2) {
|
} else if (cnt != 2) {
|
||||||
|
@ -182,6 +180,37 @@ static int idtcm_xfer(struct idtcm *idtcm,
|
||||||
return 0;
|
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)
|
static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
|
||||||
{
|
{
|
||||||
u8 buf[4];
|
u8 buf[4];
|
||||||
|
@ -195,7 +224,7 @@ static int idtcm_page_offset(struct idtcm *idtcm, u8 val)
|
||||||
buf[2] = 0x10;
|
buf[2] = 0x10;
|
||||||
buf[3] = 0x20;
|
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) {
|
if (err) {
|
||||||
idtcm->page_offset = 0xff;
|
idtcm->page_offset = 0xff;
|
||||||
|
@ -223,11 +252,12 @@ static int _idtcm_rdwr(struct idtcm *idtcm,
|
||||||
err = idtcm_page_offset(idtcm, hi);
|
err = idtcm_page_offset(idtcm, hi);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto out;
|
return err;
|
||||||
|
|
||||||
err = idtcm_xfer(idtcm, lo, buf, count, write);
|
if (write)
|
||||||
out:
|
return idtcm_xfer_write(idtcm, lo, buf, count);
|
||||||
return err;
|
|
||||||
|
return idtcm_xfer_read(idtcm, lo, buf, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int idtcm_read(struct idtcm *idtcm,
|
static int idtcm_read(struct idtcm *idtcm,
|
||||||
|
|
|
@ -55,6 +55,8 @@
|
||||||
|
|
||||||
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
|
#define PEROUT_ENABLE_OUTPUT_MASK (0xdeadbeef)
|
||||||
|
|
||||||
|
#define IDTCM_MAX_WRITE_COUNT (512)
|
||||||
|
|
||||||
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
|
/* Values of DPLL_N.DPLL_MODE.PLL_MODE */
|
||||||
enum pll_mode {
|
enum pll_mode {
|
||||||
PLL_MODE_MIN = 0,
|
PLL_MODE_MIN = 0,
|
||||||
|
|
|
@ -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);
|
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,
|
struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
|
||||||
const struct in6_addr *addr,
|
const struct in6_addr *addr,
|
||||||
|
|
|
@ -767,7 +767,7 @@ union bpf_attr {
|
||||||
*
|
*
|
||||||
* Also, note that **bpf_trace_printk**\ () is slow, and should
|
* Also, note that **bpf_trace_printk**\ () is slow, and should
|
||||||
* only be used for debugging purposes. For this reason, a notice
|
* 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"
|
* states that the helper should not be used "for production use"
|
||||||
* the first time this helper is used (or more precisely, when
|
* the first time this helper is used (or more precisely, when
|
||||||
* **trace_printk**\ () buffers are allocated). For passing values
|
* **trace_printk**\ () buffers are allocated). For passing values
|
||||||
|
@ -1033,14 +1033,14 @@ union bpf_attr {
|
||||||
*
|
*
|
||||||
* int ret;
|
* int ret;
|
||||||
* struct bpf_tunnel_key key = {};
|
* struct bpf_tunnel_key key = {};
|
||||||
*
|
*
|
||||||
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||||
* if (ret < 0)
|
* if (ret < 0)
|
||||||
* return TC_ACT_SHOT; // drop packet
|
* return TC_ACT_SHOT; // drop packet
|
||||||
*
|
*
|
||||||
* if (key.remote_ipv4 != 0x0a000001)
|
* if (key.remote_ipv4 != 0x0a000001)
|
||||||
* return TC_ACT_SHOT; // drop packet
|
* return TC_ACT_SHOT; // drop packet
|
||||||
*
|
*
|
||||||
* return TC_ACT_OK; // accept packet
|
* return TC_ACT_OK; // accept packet
|
||||||
*
|
*
|
||||||
* This interface can also be used with all encapsulation devices
|
* This interface can also be used with all encapsulation devices
|
||||||
|
@ -1147,7 +1147,7 @@ union bpf_attr {
|
||||||
* Description
|
* Description
|
||||||
* Retrieve the realm or the route, that is to say the
|
* Retrieve the realm or the route, that is to say the
|
||||||
* **tclassid** field of the destination for the *skb*. 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
|
* one used with the net_cls cgroup (see description for
|
||||||
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
|
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
|
||||||
* held by a route (a destination entry), not by a task.
|
* held by a route (a destination entry), not by a task.
|
||||||
|
|
|
@ -67,6 +67,9 @@ static void bpf_iter_done_stop(struct seq_file *seq)
|
||||||
iter_priv->done_stop = true;
|
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.
|
/* bpf_seq_read, a customized and simpler version for bpf iterator.
|
||||||
* no_llseek is assumed for this file.
|
* no_llseek is assumed for this file.
|
||||||
* The following are differences from seq_read():
|
* 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;
|
struct seq_file *seq = file->private_data;
|
||||||
size_t n, offs, copied = 0;
|
size_t n, offs, copied = 0;
|
||||||
int err = 0;
|
int err = 0, num_objs = 0;
|
||||||
void *p;
|
void *p;
|
||||||
|
|
||||||
mutex_lock(&seq->lock);
|
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) {
|
while (1) {
|
||||||
loff_t pos = seq->index;
|
loff_t pos = seq->index;
|
||||||
|
|
||||||
|
num_objs++;
|
||||||
offs = seq->count;
|
offs = seq->count;
|
||||||
p = seq->op->next(seq, p, &seq->index);
|
p = seq->op->next(seq, p, &seq->index);
|
||||||
if (pos == 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)
|
if (seq->count >= size)
|
||||||
break;
|
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);
|
err = seq->op->show(seq, p);
|
||||||
if (err > 0) {
|
if (err > 0) {
|
||||||
bpf_iter_dec_seq_num(seq);
|
bpf_iter_dec_seq_num(seq);
|
||||||
|
|
|
@ -29,8 +29,9 @@ static struct task_struct *task_seq_get_next(struct pid_namespace *ns,
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
retry:
|
retry:
|
||||||
pid = idr_get_next(&ns->idr, tid);
|
pid = find_ge_pid(*tid, ns);
|
||||||
if (pid) {
|
if (pid) {
|
||||||
|
*tid = pid_nr_ns(pid, ns);
|
||||||
task = get_pid_task(pid, PIDTYPE_PID);
|
task = get_pid_task(pid, PIDTYPE_PID);
|
||||||
if (!task) {
|
if (!task) {
|
||||||
++*tid;
|
++*tid;
|
||||||
|
@ -178,10 +179,11 @@ task_file_seq_get_next(struct bpf_iter_seq_task_file_info *info,
|
||||||
f = fcheck_files(curr_files, curr_fd);
|
f = fcheck_files(curr_files, curr_fd);
|
||||||
if (!f)
|
if (!f)
|
||||||
continue;
|
continue;
|
||||||
|
if (!get_file_rcu(f))
|
||||||
|
continue;
|
||||||
|
|
||||||
/* set info->fd */
|
/* set info->fd */
|
||||||
info->fd = curr_fd;
|
info->fd = curr_fd;
|
||||||
get_file(f);
|
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8742,13 +8742,15 @@ struct bpf_xdp_link {
|
||||||
int flags;
|
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)
|
if (flags & XDP_FLAGS_HW_MODE)
|
||||||
return XDP_MODE_HW;
|
return XDP_MODE_HW;
|
||||||
if (flags & XDP_FLAGS_DRV_MODE)
|
if (flags & XDP_FLAGS_DRV_MODE)
|
||||||
return XDP_MODE_DRV;
|
return XDP_MODE_DRV;
|
||||||
return XDP_MODE_SKB;
|
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)
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = dev_xdp_mode(flags);
|
mode = dev_xdp_mode(dev, flags);
|
||||||
/* can't replace attached link */
|
/* can't replace attached link */
|
||||||
if (dev_xdp_link(dev, mode)) {
|
if (dev_xdp_link(dev, mode)) {
|
||||||
NL_SET_ERR_MSG(extack, "Can't replace active BPF XDP link");
|
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();
|
ASSERT_RTNL();
|
||||||
|
|
||||||
mode = dev_xdp_mode(link->flags);
|
mode = dev_xdp_mode(dev, link->flags);
|
||||||
if (dev_xdp_link(dev, mode) != link)
|
if (dev_xdp_link(dev, mode) != link)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -9080,7 +9082,7 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog,
|
||||||
goto out_unlock;
|
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);
|
bpf_op = dev_xdp_bpf_op(xdp_link->dev, mode);
|
||||||
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
|
err = dev_xdp_install(xdp_link->dev, mode, bpf_op, NULL,
|
||||||
xdp_link->flags, new_prog);
|
xdp_link->flags, new_prog);
|
||||||
|
@ -9164,7 +9166,7 @@ int bpf_xdp_link_attach(const union bpf_attr *attr, struct bpf_prog *prog)
|
||||||
int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
|
int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
|
||||||
int fd, int expected_fd, u32 flags)
|
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;
|
struct bpf_prog *new_prog = NULL, *old_prog = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
|
@ -5987,9 +5987,13 @@ static int pskb_carve_inside_nonlinear(struct sk_buff *skb, const u32 off,
|
||||||
if (skb_has_frag_list(skb))
|
if (skb_has_frag_list(skb))
|
||||||
skb_clone_fraglist(skb);
|
skb_clone_fraglist(skb);
|
||||||
|
|
||||||
if (k == 0) {
|
/* split line is in frag list */
|
||||||
/* split line is in frag list */
|
if (k == 0 && pskb_carve_frag_list(skb, shinfo, off - pos, gfp_mask)) {
|
||||||
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);
|
skb_release_data(skb);
|
||||||
|
|
||||||
|
|
|
@ -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(wanted_diff_mask, NETDEV_FEATURE_COUNT);
|
||||||
DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
|
DECLARE_BITMAP(active_diff_mask, NETDEV_FEATURE_COUNT);
|
||||||
DECLARE_BITMAP(old_active, 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_active, NETDEV_FEATURE_COUNT);
|
||||||
|
DECLARE_BITMAP(new_wanted, NETDEV_FEATURE_COUNT);
|
||||||
DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
|
DECLARE_BITMAP(req_wanted, NETDEV_FEATURE_COUNT);
|
||||||
DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
|
DECLARE_BITMAP(req_mask, NETDEV_FEATURE_COUNT);
|
||||||
struct nlattr *tb[ETHTOOL_A_FEATURES_MAX + 1];
|
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();
|
rtnl_lock();
|
||||||
ethnl_features_to_bitmap(old_active, dev->features);
|
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,
|
ret = ethnl_parse_bitset(req_wanted, req_mask, NETDEV_FEATURE_COUNT,
|
||||||
tb[ETHTOOL_A_FEATURES_WANTED],
|
tb[ETHTOOL_A_FEATURES_WANTED],
|
||||||
netdev_features_strings, info->extack);
|
netdev_features_strings, info->extack);
|
||||||
|
@ -261,17 +264,15 @@ int ethnl_set_features(struct sk_buff *skb, struct genl_info *info)
|
||||||
goto out_rtnl;
|
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_and(req_wanted, req_wanted, req_mask, NETDEV_FEATURE_COUNT);
|
||||||
bitmap_andnot(new_active, old_active, req_mask, NETDEV_FEATURE_COUNT);
|
bitmap_andnot(new_wanted, old_wanted, req_mask, NETDEV_FEATURE_COUNT);
|
||||||
bitmap_or(req_wanted, new_active, req_wanted, NETDEV_FEATURE_COUNT);
|
bitmap_or(req_wanted, new_wanted, req_wanted, NETDEV_FEATURE_COUNT);
|
||||||
if (bitmap_equal(req_wanted, old_active, NETDEV_FEATURE_COUNT)) {
|
if (!bitmap_equal(req_wanted, old_wanted, NETDEV_FEATURE_COUNT)) {
|
||||||
ret = 0;
|
dev->wanted_features &= ~dev->hw_features;
|
||||||
goto out_rtnl;
|
dev->wanted_features |= ethnl_bitmap_to_features(req_wanted) & dev->hw_features;
|
||||||
|
__netdev_update_features(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
|
|
||||||
__netdev_update_features(dev);
|
|
||||||
ethnl_features_to_bitmap(new_active, dev->features);
|
ethnl_features_to_bitmap(new_active, dev->features);
|
||||||
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
|
mod = !bitmap_equal(old_active, new_active, NETDEV_FEATURE_COUNT);
|
||||||
|
|
||||||
|
|
|
@ -661,13 +661,13 @@ config TCP_CONG_BBR
|
||||||
|
|
||||||
BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to
|
BBR (Bottleneck Bandwidth and RTT) TCP congestion control aims to
|
||||||
maximize network utilization and minimize queues. It builds an explicit
|
maximize network utilization and minimize queues. It builds an explicit
|
||||||
model of the the bottleneck delivery rate and path round-trip
|
model of the bottleneck delivery rate and path round-trip propagation
|
||||||
propagation delay. It tolerates packet loss and delay unrelated to
|
delay. It tolerates packet loss and delay unrelated to congestion. It
|
||||||
congestion. It can operate over LAN, WAN, cellular, wifi, or cable
|
can operate over LAN, WAN, cellular, wifi, or cable modem links. It can
|
||||||
modem links. It can coexist with flows that use loss-based congestion
|
coexist with flows that use loss-based congestion control, and can
|
||||||
control, and can operate with shallow buffers, deep buffers,
|
operate with shallow buffers, deep buffers, bufferbloat, policers, or
|
||||||
bufferbloat, policers, or AQM schemes that do not provide a delay
|
AQM schemes that do not provide a delay signal. It requires the fq
|
||||||
signal. It requires the fq ("Fair Queue") pacing packet scheduler.
|
("Fair Queue") pacing packet scheduler.
|
||||||
|
|
||||||
choice
|
choice
|
||||||
prompt "Default TCP congestion control"
|
prompt "Default TCP congestion control"
|
||||||
|
|
|
@ -446,7 +446,7 @@ static int nh_check_attr_group(struct net *net, struct nlattr *tb[],
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
u8 nhg_fdb = 0;
|
u8 nhg_fdb = 0;
|
||||||
|
|
||||||
if (len & (sizeof(struct nexthop_grp) - 1)) {
|
if (!len || len & (sizeof(struct nexthop_grp) - 1)) {
|
||||||
NL_SET_ERR_MSG(extack,
|
NL_SET_ERR_MSG(extack,
|
||||||
"Invalid length for nexthop group attribute");
|
"Invalid length for nexthop group attribute");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1187,6 +1187,9 @@ static struct nexthop *nexthop_create_group(struct net *net,
|
||||||
struct nexthop *nh;
|
struct nexthop *nh;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (WARN_ON(!num_nh))
|
||||||
|
return ERR_PTR(-EINVAL);
|
||||||
|
|
||||||
nh = nexthop_alloc();
|
nh = nexthop_alloc();
|
||||||
if (!nh)
|
if (!nh)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
|
@ -1893,12 +1893,13 @@ EXPORT_SYMBOL(ipv6_chk_addr);
|
||||||
* 2. does the address exist on the specific device
|
* 2. does the address exist on the specific device
|
||||||
* (skip_dev_check = false)
|
* (skip_dev_check = false)
|
||||||
*/
|
*/
|
||||||
int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
|
static struct net_device *
|
||||||
const struct net_device *dev, bool skip_dev_check,
|
__ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
|
||||||
int strict, u32 banned_flags)
|
const struct net_device *dev, bool skip_dev_check,
|
||||||
|
int strict, u32 banned_flags)
|
||||||
{
|
{
|
||||||
unsigned int hash = inet6_addr_hash(net, addr);
|
unsigned int hash = inet6_addr_hash(net, addr);
|
||||||
const struct net_device *l3mdev;
|
struct net_device *l3mdev, *ndev;
|
||||||
struct inet6_ifaddr *ifp;
|
struct inet6_ifaddr *ifp;
|
||||||
u32 ifp_flags;
|
u32 ifp_flags;
|
||||||
|
|
||||||
|
@ -1909,10 +1910,11 @@ int ipv6_chk_addr_and_flags(struct net *net, const struct in6_addr *addr,
|
||||||
dev = NULL;
|
dev = NULL;
|
||||||
|
|
||||||
hlist_for_each_entry_rcu(ifp, &inet6_addr_lst[hash], addr_lst) {
|
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;
|
continue;
|
||||||
|
|
||||||
if (l3mdev_master_dev_rcu(ifp->idev->dev) != l3mdev)
|
if (l3mdev_master_dev_rcu(ndev) != l3mdev)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Decouple optimistic from tentative for evaluation here.
|
/* 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;
|
: ifp->flags;
|
||||||
if (ipv6_addr_equal(&ifp->addr, addr) &&
|
if (ipv6_addr_equal(&ifp->addr, addr) &&
|
||||||
!(ifp_flags&banned_flags) &&
|
!(ifp_flags&banned_flags) &&
|
||||||
(!dev || ifp->idev->dev == dev ||
|
(!dev || ndev == dev ||
|
||||||
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
|
!(ifp->scope&(IFA_LINK|IFA_HOST) || strict))) {
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
return 1;
|
return ndev;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rcu_read_unlock();
|
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);
|
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.
|
* 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);
|
return __ipv6_chk_addr_and_flags(net, addr, dev, !dev, 1,
|
||||||
struct inet6_ifaddr *ifp, *result = NULL;
|
IFA_F_TENTATIVE);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ipv6_dev_find);
|
EXPORT_SYMBOL(ipv6_dev_find);
|
||||||
|
|
||||||
|
|
|
@ -915,7 +915,15 @@ int ip6_tnl_rcv(struct ip6_tnl *t, struct sk_buff *skb,
|
||||||
struct metadata_dst *tun_dst,
|
struct metadata_dst *tun_dst,
|
||||||
bool log_ecn_err)
|
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);
|
log_ecn_err);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ip6_tnl_rcv);
|
EXPORT_SYMBOL(ip6_tnl_rcv);
|
||||||
|
|
|
@ -51,6 +51,9 @@ static int add_policy(struct nl_policy_dump **statep,
|
||||||
if (!state)
|
if (!state)
|
||||||
return -ENOMEM;
|
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].policy = policy;
|
||||||
state->policies[state->n_alloc].maxtype = maxtype;
|
state->policies[state->n_alloc].maxtype = maxtype;
|
||||||
state->n_alloc = n_alloc;
|
state->n_alloc = n_alloc;
|
||||||
|
|
|
@ -704,7 +704,7 @@ static int tcf_ct_handle_fragments(struct net *net, struct sk_buff *skb,
|
||||||
err = ip_defrag(net, skb, user);
|
err = ip_defrag(net, skb, user);
|
||||||
local_bh_enable();
|
local_bh_enable();
|
||||||
if (err && err != -EINPROGRESS)
|
if (err && err != -EINPROGRESS)
|
||||||
goto out_free;
|
return err;
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
*defrag = true;
|
*defrag = true;
|
||||||
|
|
|
@ -88,12 +88,13 @@ static int sctp_stream_alloc_out(struct sctp_stream *stream, __u16 outcnt,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (outcnt <= stream->outcnt)
|
if (outcnt <= stream->outcnt)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
ret = genradix_prealloc(&stream->out, outcnt, gfp);
|
ret = genradix_prealloc(&stream->out, outcnt, gfp);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
out:
|
||||||
stream->outcnt = outcnt;
|
stream->outcnt = outcnt;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -104,12 +105,13 @@ static int sctp_stream_alloc_in(struct sctp_stream *stream, __u16 incnt,
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (incnt <= stream->incnt)
|
if (incnt <= stream->incnt)
|
||||||
return 0;
|
goto out;
|
||||||
|
|
||||||
ret = genradix_prealloc(&stream->in, incnt, gfp);
|
ret = genradix_prealloc(&stream->in, incnt, gfp);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
out:
|
||||||
stream->incnt = incnt;
|
stream->incnt = incnt;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,13 +170,15 @@ static int __smc_diag_dump(struct sock *sk, struct sk_buff *skb,
|
||||||
(req->diag_ext & (1 << (SMC_DIAG_DMBINFO - 1))) &&
|
(req->diag_ext & (1 << (SMC_DIAG_DMBINFO - 1))) &&
|
||||||
!list_empty(&smc->conn.lgr->list)) {
|
!list_empty(&smc->conn.lgr->list)) {
|
||||||
struct smc_connection *conn = &smc->conn;
|
struct smc_connection *conn = &smc->conn;
|
||||||
struct smcd_diag_dmbinfo dinfo = {
|
struct smcd_diag_dmbinfo dinfo;
|
||||||
.linkid = *((u32 *)conn->lgr->id),
|
|
||||||
.peer_gid = conn->lgr->peer_gid,
|
memset(&dinfo, 0, sizeof(dinfo));
|
||||||
.my_gid = conn->lgr->smcd->local_gid,
|
|
||||||
.token = conn->rmb_desc->token,
|
dinfo.linkid = *((u32 *)conn->lgr->id);
|
||||||
.peer_token = conn->peer_token
|
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)
|
if (nla_put(skb, SMC_DIAG_DMBINFO, sizeof(dinfo), &dinfo) < 0)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
|
|
@ -757,10 +757,12 @@ static void tipc_aead_encrypt_done(struct crypto_async_request *base, int err)
|
||||||
switch (err) {
|
switch (err) {
|
||||||
case 0:
|
case 0:
|
||||||
this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]);
|
this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]);
|
||||||
|
rcu_read_lock();
|
||||||
if (likely(test_bit(0, &b->up)))
|
if (likely(test_bit(0, &b->up)))
|
||||||
b->media->send_msg(net, skb, b, &tx_ctx->dst);
|
b->media->send_msg(net, skb, b, &tx_ctx->dst);
|
||||||
else
|
else
|
||||||
kfree_skb(skb);
|
kfree_skb(skb);
|
||||||
|
rcu_read_unlock();
|
||||||
break;
|
break;
|
||||||
case -EINPROGRESS:
|
case -EINPROGRESS:
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -660,6 +660,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
|
||||||
struct udp_tunnel_sock_cfg tuncfg = {NULL};
|
struct udp_tunnel_sock_cfg tuncfg = {NULL};
|
||||||
struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
|
struct nlattr *opts[TIPC_NLA_UDP_MAX + 1];
|
||||||
u8 node_id[NODE_ID_LEN] = {0,};
|
u8 node_id[NODE_ID_LEN] = {0,};
|
||||||
|
struct net_device *dev;
|
||||||
int rmcast = 0;
|
int rmcast = 0;
|
||||||
|
|
||||||
ub = kzalloc(sizeof(*ub), GFP_ATOMIC);
|
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);
|
rcu_assign_pointer(ub->bearer, b);
|
||||||
tipc_udp_media_addr_set(&b->addr, &local);
|
tipc_udp_media_addr_set(&b->addr, &local);
|
||||||
if (local.proto == htons(ETH_P_IP)) {
|
if (local.proto == htons(ETH_P_IP)) {
|
||||||
struct net_device *dev;
|
|
||||||
|
|
||||||
dev = __ip_dev_find(net, local.ipv4.s_addr, false);
|
dev = __ip_dev_find(net, local.ipv4.s_addr, false);
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
|
@ -738,9 +737,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,
|
||||||
b->mtu = b->media->mtu;
|
b->mtu = b->media->mtu;
|
||||||
#if IS_ENABLED(CONFIG_IPV6)
|
#if IS_ENABLED(CONFIG_IPV6)
|
||||||
} else if (local.proto == htons(ETH_P_IPV6)) {
|
} else if (local.proto == htons(ETH_P_IPV6)) {
|
||||||
struct net_device *dev;
|
dev = ub->ifindex ? __dev_get_by_index(net, ub->ifindex) : NULL;
|
||||||
|
dev = ipv6_dev_find(net, &local.ipv6, dev);
|
||||||
dev = ipv6_dev_find(net, &local.ipv6);
|
|
||||||
if (!dev) {
|
if (!dev) {
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -134,6 +134,8 @@ int build_obj_refs_table(struct obj_refs_table *table, enum bpf_obj_type type)
|
||||||
while (true) {
|
while (true) {
|
||||||
ret = read(fd, buf, sizeof(buf));
|
ret = read(fd, buf, sizeof(buf));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
if (errno == EAGAIN)
|
||||||
|
continue;
|
||||||
err = -errno;
|
err = -errno;
|
||||||
p_err("failed to read PID iterator output: %d", err);
|
p_err("failed to read PID iterator output: %d", err);
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -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);
|
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)
|
static int elf_collect(struct object *obj)
|
||||||
{
|
{
|
||||||
Elf_Scn *scn = NULL;
|
Elf_Scn *scn = NULL;
|
||||||
|
@ -309,6 +342,9 @@ static int elf_collect(struct object *obj)
|
||||||
obj->efile.idlist_shndx = idx;
|
obj->efile.idlist_shndx = idx;
|
||||||
obj->efile.idlist_addr = sh.sh_addr;
|
obj->efile.idlist_addr = sh.sh_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (compressed_section_fix(elf, scn, &sh))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -767,7 +767,7 @@ union bpf_attr {
|
||||||
*
|
*
|
||||||
* Also, note that **bpf_trace_printk**\ () is slow, and should
|
* Also, note that **bpf_trace_printk**\ () is slow, and should
|
||||||
* only be used for debugging purposes. For this reason, a notice
|
* 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"
|
* states that the helper should not be used "for production use"
|
||||||
* the first time this helper is used (or more precisely, when
|
* the first time this helper is used (or more precisely, when
|
||||||
* **trace_printk**\ () buffers are allocated). For passing values
|
* **trace_printk**\ () buffers are allocated). For passing values
|
||||||
|
@ -1033,14 +1033,14 @@ union bpf_attr {
|
||||||
*
|
*
|
||||||
* int ret;
|
* int ret;
|
||||||
* struct bpf_tunnel_key key = {};
|
* struct bpf_tunnel_key key = {};
|
||||||
*
|
*
|
||||||
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||||
* if (ret < 0)
|
* if (ret < 0)
|
||||||
* return TC_ACT_SHOT; // drop packet
|
* return TC_ACT_SHOT; // drop packet
|
||||||
*
|
*
|
||||||
* if (key.remote_ipv4 != 0x0a000001)
|
* if (key.remote_ipv4 != 0x0a000001)
|
||||||
* return TC_ACT_SHOT; // drop packet
|
* return TC_ACT_SHOT; // drop packet
|
||||||
*
|
*
|
||||||
* return TC_ACT_OK; // accept packet
|
* return TC_ACT_OK; // accept packet
|
||||||
*
|
*
|
||||||
* This interface can also be used with all encapsulation devices
|
* This interface can also be used with all encapsulation devices
|
||||||
|
@ -1147,7 +1147,7 @@ union bpf_attr {
|
||||||
* Description
|
* Description
|
||||||
* Retrieve the realm or the route, that is to say the
|
* Retrieve the realm or the route, that is to say the
|
||||||
* **tclassid** field of the destination for the *skb*. 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
|
* one used with the net_cls cgroup (see description for
|
||||||
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
|
* **bpf_get_cgroup_classid**\ () helper), but here this tag is
|
||||||
* held by a route (a destination entry), not by a task.
|
* held by a route (a destination entry), not by a task.
|
||||||
|
|
|
@ -879,7 +879,7 @@ static void btf_dump_emit_struct_def(struct btf_dump *d,
|
||||||
btf_dump_printf(d, ": %d", m_sz);
|
btf_dump_printf(d, ": %d", m_sz);
|
||||||
off = m_off + m_sz;
|
off = m_off + m_sz;
|
||||||
} else {
|
} 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;
|
off = m_off + m_sz * 8;
|
||||||
}
|
}
|
||||||
btf_dump_printf(d, ";");
|
btf_dump_printf(d, ";");
|
||||||
|
|
|
@ -2264,7 +2264,7 @@ static int bpf_object__init_user_btf_maps(struct bpf_object *obj, bool strict,
|
||||||
data = elf_getdata(scn, NULL);
|
data = elf_getdata(scn, NULL);
|
||||||
if (!scn || !data) {
|
if (!scn || !data) {
|
||||||
pr_warn("failed to get Elf_Data from map section %d (%s)\n",
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ test_lpm_map
|
||||||
test_tag
|
test_tag
|
||||||
FEATURE-DUMP.libbpf
|
FEATURE-DUMP.libbpf
|
||||||
fixdep
|
fixdep
|
||||||
test_align
|
|
||||||
test_dev_cgroup
|
test_dev_cgroup
|
||||||
/test_progs*
|
/test_progs*
|
||||||
test_tcpbpf_user
|
test_tcpbpf_user
|
||||||
|
|
|
@ -32,7 +32,7 @@ LDLIBS += -lcap -lelf -lz -lrt -lpthread
|
||||||
|
|
||||||
# Order correspond to 'make run_tests' order
|
# 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_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_sock test_btf test_sockmap get_cgroup_id_user test_socket_cookie \
|
||||||
test_cgroup_storage \
|
test_cgroup_storage \
|
||||||
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl \
|
test_netcnt test_tcpnotify_user test_sock_fields test_sysctl \
|
||||||
|
|
|
@ -19,7 +19,7 @@ static int libbpf_debug_print(enum libbpf_print_level level,
|
||||||
log_buf = va_arg(args, char *);
|
log_buf = va_arg(args, char *);
|
||||||
if (!log_buf)
|
if (!log_buf)
|
||||||
goto out;
|
goto out;
|
||||||
if (strstr(log_buf, err_str) == 0)
|
if (err_str && strstr(log_buf, err_str) == 0)
|
||||||
found = true;
|
found = true;
|
||||||
out:
|
out:
|
||||||
printf(format, log_buf);
|
printf(format, log_buf);
|
||||||
|
|
Loading…
Reference in New Issue