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
44 changed files with 310 additions and 163 deletions
|
@ -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 = <ðer_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";
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -2180,13 +2180,10 @@ 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) &&
|
||||
adapter->ena_napi[i].xdp_ring);
|
||||
netif_napi_del(&adapter->ena_napi[i].napi);
|
||||
|
||||
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();
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -750,8 +750,10 @@ 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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -142,16 +142,15 @@ static int idtcm_strverscmp(const char *ver1, const char *ver2)
|
|||
return result;
|
||||
}
|
||||
|
||||
static int idtcm_xfer(struct idtcm *idtcm,
|
||||
u8 regaddr,
|
||||
u8 *buf,
|
||||
u16 count,
|
||||
bool write)
|
||||
static int idtcm_xfer_read(struct idtcm *idtcm,
|
||||
u8 regaddr,
|
||||
u8 *buf,
|
||||
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 = ®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].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;
|
||||
return err;
|
||||
|
||||
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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
@ -1033,14 +1033,14 @@ union bpf_attr {
|
|||
*
|
||||
* int ret;
|
||||
* struct bpf_tunnel_key key = {};
|
||||
*
|
||||
*
|
||||
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
* if (ret < 0)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* if (key.remote_ipv4 != 0x0a000001)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* return TC_ACT_OK; // accept packet
|
||||
*
|
||||
* This interface can also be used with all encapsulation devices
|
||||
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
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)
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
/* split line is in frag list */
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
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);
|
||||
}
|
||||
|
||||
dev->wanted_features = ethnl_bitmap_to_features(req_wanted);
|
||||
__netdev_update_features(dev);
|
||||
ethnl_features_to_bitmap(new_active, dev->features);
|
||||
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
|
||||
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"
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
const struct net_device *dev, bool skip_dev_check,
|
||||
int strict, u32 banned_flags)
|
||||
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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -1033,14 +1033,14 @@ union bpf_attr {
|
|||
*
|
||||
* int ret;
|
||||
* struct bpf_tunnel_key key = {};
|
||||
*
|
||||
*
|
||||
* ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
|
||||
* if (ret < 0)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* if (key.remote_ipv4 != 0x0a000001)
|
||||
* return TC_ACT_SHOT; // drop packet
|
||||
*
|
||||
*
|
||||
* return TC_ACT_OK; // accept packet
|
||||
*
|
||||
* This interface can also be used with all encapsulation devices
|
||||
|
@ -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.
|
||||
|
|
|
@ -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, ";");
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
1
tools/testing/selftests/bpf/.gitignore
vendored
1
tools/testing/selftests/bpf/.gitignore
vendored
|
@ -6,7 +6,6 @@ test_lpm_map
|
|||
test_tag
|
||||
FEATURE-DUMP.libbpf
|
||||
fixdep
|
||||
test_align
|
||||
test_dev_cgroup
|
||||
/test_progs*
|
||||
test_tcpbpf_user
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue