mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 20:24:12 +08:00
Networking fixes for 6.1-rc2, including fixes from netfilter
Current release - regressions: - revert "net: fix cpu_max_bits_warn() usage in netif_attrmask_next{,_and}" - revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" - dsa: uninitialized variable in dsa_slave_netdevice_event() - eth: sunhme: uninitialized variable in happy_meal_init() Current release - new code bugs: - eth: octeontx2: fix resource not freed after malloc Previous releases - regressions: - sched: fix return value of qdisc ingress handling on success - sched: fix race condition in qdisc_graft() - udp: update reuse->has_conns under reuseport_lock. - tls: strp: make sure the TCP skbs do not have overlapping data - hsr: avoid possible NULL deref in skb_clone() - tipc: fix an information leak in tipc_topsrv_kern_subscr - phylink: add mac_managed_pm in phylink_config structure - eth: i40e: fix DMA mappings leak - eth: hyperv: fix a RX-path warning - eth: mtk: fix memory leaks Previous releases - always broken: - sched: cake: fix null pointer access issue when cake_init() fails -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEg1AjqC77wbdLX2LbKSR5jcyPE6QFAmNRKdcSHHBhYmVuaUBy ZWRoYXQuY29tAAoJECkkeY3MjxOkYn8P/31xjE9/BRQKVGQOMxj78vhQvVHEZYXJ OJcaLcjxUCqj6hu3pEcuf88PeTicyfEqN32zzH1k+SS8jGQCmoVtXUfbZ7pDR6Tc rsAqVhLD6JnYkGEgtzm3i+8EfSeBoCy9kT4JZzRxQmOfZr1rBmtoMHOB4cGk9g1K lSF3KJcKT1GDacB/gVei+ms0Y+Q9WULOg3OFuyLSeltAkhZKaTfx/qqsLLEHFqZc u6eR31GwG28Y4GVurLQSOdaWrFOKqmPFOpzvjmeKC2RBqS6hVl4/YKZTmTV53Lee brm6kuVlU7CJVZEN2qF8G2+/SqLgcB0o26JVnml1kT8n0GlFAbyFf5akawjT8/Je G/zgz6k6wUAI2g3nSPNmgqVtobsypthzWL/bOpWfGfJFXxGOgLG3pbZYIl816Tha KnibZqQOBHxfPaUzh0xCLhidoi5G0T8ip9o9tyKlnmvbKY/EWk6HiIjCWlxnkPiO GRdHkyF7KMxqo/QuE9AK3LnD/AsLeWcuqzMveiaTbYLkMjGDW1yz3otL7KXW5l8U zYoUn1HQLkNqDE17+PjRo28awOMyN6ujXggKBK/hfXVnPpdW3yWPUoslqQdVn5KC 3PLeSNM1v4UQSMWx1alRx1PvA+zYDX4GQpSSXbQgYGVim8LMwZQ1xui2qWF8xEau k9ZKfMSUNGEr =y2As -----END PGP SIGNATURE----- Merge tag 'net-6.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net Pull networking fixes from Paolo Abeni: "Including fixes from netfilter. Current release - regressions: - revert "net: fix cpu_max_bits_warn() usage in netif_attrmask_next{,_and}" - revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" - dsa: uninitialized variable in dsa_slave_netdevice_event() - eth: sunhme: uninitialized variable in happy_meal_init() Current release - new code bugs: - eth: octeontx2: fix resource not freed after malloc Previous releases - regressions: - sched: fix return value of qdisc ingress handling on success - sched: fix race condition in qdisc_graft() - udp: update reuse->has_conns under reuseport_lock. - tls: strp: make sure the TCP skbs do not have overlapping data - hsr: avoid possible NULL deref in skb_clone() - tipc: fix an information leak in tipc_topsrv_kern_subscr - phylink: add mac_managed_pm in phylink_config structure - eth: i40e: fix DMA mappings leak - eth: hyperv: fix a RX-path warning - eth: mtk: fix memory leaks Previous releases - always broken: - sched: cake: fix null pointer access issue when cake_init() fails" * tag 'net-6.1-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net: (43 commits) net: phy: dp83822: disable MDI crossover status change interrupt net: sched: fix race condition in qdisc_graft() net: hns: fix possible memory leak in hnae_ae_register() wwan_hwsim: fix possible memory leak in wwan_hwsim_dev_new() sfc: include vport_id in filter spec hash and equal() genetlink: fix kdoc warnings selftests: add selftest for chaining of tc ingress handling to egress net: Fix return value of qdisc ingress handling on success net: sched: sfb: fix null pointer access issue when sfb_init() fails Revert "net: sched: fq_codel: remove redundant resource cleanup in fq_codel_init()" net: sched: cake: fix null pointer access issue when cake_init() fails ethernet: marvell: octeontx2 Fix resource not freed after malloc netfilter: nf_tables: relax NFTA_SET_ELEM_KEY_END set flags requirements netfilter: rpfilter/fib: Set ->flowic_uid correctly for user namespaces. ionic: catch NULL pointer issue on reconfig net: hsr: avoid possible NULL deref in skb_clone() bnxt_en: fix memory leak in bnxt_nvm_test() ip6mr: fix UAF issue in ip6mr_sk_done() when addrconf_init_net() failed udp: Update reuse->has_conns under reuseport_lock. net: ethernet: mediatek: ppe: Remove the unused function mtk_foe_entry_usable() ...
This commit is contained in:
commit
6d36c728bc
@ -8,7 +8,6 @@ title: Samsung S3FWRN5 NCI NFC Controller
|
||||
|
||||
maintainers:
|
||||
- Krzysztof Kozlowski <krzk@kernel.org>
|
||||
- Krzysztof Opasiak <k.opasiak@samsung.com>
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
@ -18215,7 +18215,6 @@ F: include/media/drv-intf/s3c_camif.h
|
||||
|
||||
SAMSUNG S3FWRN5 NFC DRIVER
|
||||
M: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||
M: Krzysztof Opasiak <k.opasiak@samsung.com>
|
||||
L: linux-nfc@lists.01.org (subscribers-only)
|
||||
S: Maintained
|
||||
F: Documentation/devicetree/bindings/net/nfc/samsung,s3fwrn5.yaml
|
||||
@ -21297,7 +21296,7 @@ L: linux-usb@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://github.com/petkan/pegasus
|
||||
T: git git://github.com/petkan/pegasus.git
|
||||
T: git https://github.com/petkan/pegasus.git
|
||||
F: drivers/net/usb/pegasus.*
|
||||
|
||||
USB PHY LAYER
|
||||
@ -21334,7 +21333,7 @@ L: linux-usb@vger.kernel.org
|
||||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: https://github.com/petkan/rtl8150
|
||||
T: git git://github.com/petkan/rtl8150.git
|
||||
T: git https://github.com/petkan/rtl8150.git
|
||||
F: drivers/net/usb/rtl8150.c
|
||||
|
||||
USB SERIAL SUBSYSTEM
|
||||
|
@ -137,27 +137,42 @@ static void qca8k_rw_reg_ack_handler(struct dsa_switch *ds, struct sk_buff *skb)
|
||||
struct qca8k_mgmt_eth_data *mgmt_eth_data;
|
||||
struct qca8k_priv *priv = ds->priv;
|
||||
struct qca_mgmt_ethhdr *mgmt_ethhdr;
|
||||
u32 command;
|
||||
u8 len, cmd;
|
||||
int i;
|
||||
|
||||
mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb_mac_header(skb);
|
||||
mgmt_eth_data = &priv->mgmt_eth_data;
|
||||
|
||||
cmd = FIELD_GET(QCA_HDR_MGMT_CMD, mgmt_ethhdr->command);
|
||||
len = FIELD_GET(QCA_HDR_MGMT_LENGTH, mgmt_ethhdr->command);
|
||||
command = get_unaligned_le32(&mgmt_ethhdr->command);
|
||||
cmd = FIELD_GET(QCA_HDR_MGMT_CMD, command);
|
||||
len = FIELD_GET(QCA_HDR_MGMT_LENGTH, command);
|
||||
|
||||
/* Make sure the seq match the requested packet */
|
||||
if (mgmt_ethhdr->seq == mgmt_eth_data->seq)
|
||||
if (get_unaligned_le32(&mgmt_ethhdr->seq) == mgmt_eth_data->seq)
|
||||
mgmt_eth_data->ack = true;
|
||||
|
||||
if (cmd == MDIO_READ) {
|
||||
mgmt_eth_data->data[0] = mgmt_ethhdr->mdio_data;
|
||||
u32 *val = mgmt_eth_data->data;
|
||||
|
||||
*val = get_unaligned_le32(&mgmt_ethhdr->mdio_data);
|
||||
|
||||
/* Get the rest of the 12 byte of data.
|
||||
* The read/write function will extract the requested data.
|
||||
*/
|
||||
if (len > QCA_HDR_MGMT_DATA1_LEN)
|
||||
memcpy(mgmt_eth_data->data + 1, skb->data,
|
||||
QCA_HDR_MGMT_DATA2_LEN);
|
||||
if (len > QCA_HDR_MGMT_DATA1_LEN) {
|
||||
__le32 *data2 = (__le32 *)skb->data;
|
||||
int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
|
||||
len - QCA_HDR_MGMT_DATA1_LEN);
|
||||
|
||||
val++;
|
||||
|
||||
for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
|
||||
*val = get_unaligned_le32(data2);
|
||||
val++;
|
||||
data2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
complete(&mgmt_eth_data->rw_done);
|
||||
@ -169,8 +184,10 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
|
||||
struct qca_mgmt_ethhdr *mgmt_ethhdr;
|
||||
unsigned int real_len;
|
||||
struct sk_buff *skb;
|
||||
u32 *data2;
|
||||
__le32 *data2;
|
||||
u32 command;
|
||||
u16 hdr;
|
||||
int i;
|
||||
|
||||
skb = dev_alloc_skb(QCA_HDR_MGMT_PKT_LEN);
|
||||
if (!skb)
|
||||
@ -199,20 +216,32 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
|
||||
hdr |= FIELD_PREP(QCA_HDR_XMIT_DP_BIT, BIT(0));
|
||||
hdr |= FIELD_PREP(QCA_HDR_XMIT_CONTROL, QCA_HDR_XMIT_TYPE_RW_REG);
|
||||
|
||||
mgmt_ethhdr->command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
|
||||
mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
|
||||
mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
|
||||
mgmt_ethhdr->command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
|
||||
command = FIELD_PREP(QCA_HDR_MGMT_ADDR, reg);
|
||||
command |= FIELD_PREP(QCA_HDR_MGMT_LENGTH, real_len);
|
||||
command |= FIELD_PREP(QCA_HDR_MGMT_CMD, cmd);
|
||||
command |= FIELD_PREP(QCA_HDR_MGMT_CHECK_CODE,
|
||||
QCA_HDR_MGMT_CHECK_CODE_VAL);
|
||||
|
||||
put_unaligned_le32(command, &mgmt_ethhdr->command);
|
||||
|
||||
if (cmd == MDIO_WRITE)
|
||||
mgmt_ethhdr->mdio_data = *val;
|
||||
put_unaligned_le32(*val, &mgmt_ethhdr->mdio_data);
|
||||
|
||||
mgmt_ethhdr->hdr = htons(hdr);
|
||||
|
||||
data2 = skb_put_zero(skb, QCA_HDR_MGMT_DATA2_LEN + QCA_HDR_MGMT_PADDING_LEN);
|
||||
if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN)
|
||||
memcpy(data2, val + 1, len - QCA_HDR_MGMT_DATA1_LEN);
|
||||
if (cmd == MDIO_WRITE && len > QCA_HDR_MGMT_DATA1_LEN) {
|
||||
int data_len = min_t(int, QCA_HDR_MGMT_DATA2_LEN,
|
||||
len - QCA_HDR_MGMT_DATA1_LEN);
|
||||
|
||||
val++;
|
||||
|
||||
for (i = sizeof(u32); i <= data_len; i += sizeof(u32)) {
|
||||
put_unaligned_le32(*val, data2);
|
||||
data2++;
|
||||
val++;
|
||||
}
|
||||
}
|
||||
|
||||
return skb;
|
||||
}
|
||||
@ -220,9 +249,11 @@ static struct sk_buff *qca8k_alloc_mdio_header(enum mdio_cmd cmd, u32 reg, u32 *
|
||||
static void qca8k_mdio_header_fill_seq_num(struct sk_buff *skb, u32 seq_num)
|
||||
{
|
||||
struct qca_mgmt_ethhdr *mgmt_ethhdr;
|
||||
u32 seq;
|
||||
|
||||
seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
|
||||
mgmt_ethhdr = (struct qca_mgmt_ethhdr *)skb->data;
|
||||
mgmt_ethhdr->seq = FIELD_PREP(QCA_HDR_MGMT_SEQ_NUM, seq_num);
|
||||
put_unaligned_le32(seq, &mgmt_ethhdr->seq);
|
||||
}
|
||||
|
||||
static int qca8k_read_eth(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
|
||||
@ -1487,9 +1518,9 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
|
||||
struct qca8k_priv *priv = ds->priv;
|
||||
const struct qca8k_mib_desc *mib;
|
||||
struct mib_ethhdr *mib_ethhdr;
|
||||
int i, mib_len, offset = 0;
|
||||
u64 *data;
|
||||
__le32 *data2;
|
||||
u8 port;
|
||||
int i;
|
||||
|
||||
mib_ethhdr = (struct mib_ethhdr *)skb_mac_header(skb);
|
||||
mib_eth_data = &priv->mib_eth_data;
|
||||
@ -1501,28 +1532,24 @@ static void qca8k_mib_autocast_handler(struct dsa_switch *ds, struct sk_buff *sk
|
||||
if (port != mib_eth_data->req_port)
|
||||
goto exit;
|
||||
|
||||
data = mib_eth_data->data;
|
||||
data2 = (__le32 *)skb->data;
|
||||
|
||||
for (i = 0; i < priv->info->mib_count; i++) {
|
||||
mib = &ar8327_mib[i];
|
||||
|
||||
/* First 3 mib are present in the skb head */
|
||||
if (i < 3) {
|
||||
data[i] = mib_ethhdr->data[i];
|
||||
mib_eth_data->data[i] = get_unaligned_le32(mib_ethhdr->data + i);
|
||||
continue;
|
||||
}
|
||||
|
||||
mib_len = sizeof(uint32_t);
|
||||
|
||||
/* Some mib are 64 bit wide */
|
||||
if (mib->size == 2)
|
||||
mib_len = sizeof(uint64_t);
|
||||
mib_eth_data->data[i] = get_unaligned_le64((__le64 *)data2);
|
||||
else
|
||||
mib_eth_data->data[i] = get_unaligned_le32(data2);
|
||||
|
||||
/* Copy the mib value from packet to the */
|
||||
memcpy(data + i, skb->data + offset, mib_len);
|
||||
|
||||
/* Set the offset for the next mib */
|
||||
offset += mib_len;
|
||||
data2 += mib->size;
|
||||
}
|
||||
|
||||
exit:
|
||||
|
@ -613,6 +613,7 @@ static int bnxt_dl_reload_up(struct devlink *dl, enum devlink_reload_action acti
|
||||
|
||||
static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
|
||||
{
|
||||
bool rc = false;
|
||||
u32 datalen;
|
||||
u16 index;
|
||||
u8 *buf;
|
||||
@ -632,20 +633,20 @@ static bool bnxt_nvm_test(struct bnxt *bp, struct netlink_ext_ack *extack)
|
||||
|
||||
if (bnxt_get_nvram_item(bp->dev, index, 0, datalen, buf)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "nvm test vpd read error");
|
||||
goto err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (bnxt_flash_nvram(bp->dev, BNX_DIR_TYPE_VPD, BNX_DIR_ORDINAL_FIRST,
|
||||
BNX_DIR_EXT_NONE, 0, 0, buf, datalen)) {
|
||||
NL_SET_ERR_MSG_MOD(extack, "nvm test vpd write error");
|
||||
goto err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
return true;
|
||||
rc = true;
|
||||
|
||||
err:
|
||||
done:
|
||||
kfree(buf);
|
||||
return false;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static bool bnxt_dl_selftest_check(struct devlink *dl, unsigned int id,
|
||||
|
@ -419,8 +419,10 @@ int hnae_ae_register(struct hnae_ae_dev *hdev, struct module *owner)
|
||||
hdev->cls_dev.release = hnae_release;
|
||||
(void)dev_set_name(&hdev->cls_dev, "hnae%d", hdev->id);
|
||||
ret = device_register(&hdev->cls_dev);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
put_device(&hdev->cls_dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
__module_get(THIS_MODULE);
|
||||
|
||||
|
@ -2181,9 +2181,6 @@ static int i40e_set_ringparam(struct net_device *netdev,
|
||||
*/
|
||||
rx_rings[i].tail = hw->hw_addr + I40E_PRTGEN_STATUS;
|
||||
err = i40e_setup_rx_descriptors(&rx_rings[i]);
|
||||
if (err)
|
||||
goto rx_unwind;
|
||||
err = i40e_alloc_rx_bi(&rx_rings[i]);
|
||||
if (err)
|
||||
goto rx_unwind;
|
||||
|
||||
|
@ -3566,12 +3566,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
|
||||
if (ring->vsi->type == I40E_VSI_MAIN)
|
||||
xdp_rxq_info_unreg_mem_model(&ring->xdp_rxq);
|
||||
|
||||
kfree(ring->rx_bi);
|
||||
ring->xsk_pool = i40e_xsk_pool(ring);
|
||||
if (ring->xsk_pool) {
|
||||
ret = i40e_alloc_rx_bi_zc(ring);
|
||||
if (ret)
|
||||
return ret;
|
||||
ring->rx_buf_len =
|
||||
xsk_pool_get_rx_frame_size(ring->xsk_pool);
|
||||
/* For AF_XDP ZC, we disallow packets to span on
|
||||
@ -3589,9 +3585,6 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
|
||||
ring->queue_index);
|
||||
|
||||
} else {
|
||||
ret = i40e_alloc_rx_bi(ring);
|
||||
if (ret)
|
||||
return ret;
|
||||
ring->rx_buf_len = vsi->rx_buf_len;
|
||||
if (ring->vsi->type == I40E_VSI_MAIN) {
|
||||
ret = xdp_rxq_info_reg_mem_model(&ring->xdp_rxq,
|
||||
@ -13296,6 +13289,14 @@ static int i40e_xdp_setup(struct i40e_vsi *vsi, struct bpf_prog *prog,
|
||||
i40e_reset_and_rebuild(pf, true, true);
|
||||
}
|
||||
|
||||
if (!i40e_enabled_xdp_vsi(vsi) && prog) {
|
||||
if (i40e_realloc_rx_bi_zc(vsi, true))
|
||||
return -ENOMEM;
|
||||
} else if (i40e_enabled_xdp_vsi(vsi) && !prog) {
|
||||
if (i40e_realloc_rx_bi_zc(vsi, false))
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
for (i = 0; i < vsi->num_queue_pairs; i++)
|
||||
WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
|
||||
|
||||
@ -13528,6 +13529,7 @@ int i40e_queue_pair_disable(struct i40e_vsi *vsi, int queue_pair)
|
||||
|
||||
i40e_queue_pair_disable_irq(vsi, queue_pair);
|
||||
err = i40e_queue_pair_toggle_rings(vsi, queue_pair, false /* off */);
|
||||
i40e_clean_rx_ring(vsi->rx_rings[queue_pair]);
|
||||
i40e_queue_pair_toggle_napi(vsi, queue_pair, false /* off */);
|
||||
i40e_queue_pair_clean_rings(vsi, queue_pair);
|
||||
i40e_queue_pair_reset_stats(vsi, queue_pair);
|
||||
|
@ -1457,14 +1457,6 @@ err:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
int i40e_alloc_rx_bi(struct i40e_ring *rx_ring)
|
||||
{
|
||||
unsigned long sz = sizeof(*rx_ring->rx_bi) * rx_ring->count;
|
||||
|
||||
rx_ring->rx_bi = kzalloc(sz, GFP_KERNEL);
|
||||
return rx_ring->rx_bi ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
static void i40e_clear_rx_bi(struct i40e_ring *rx_ring)
|
||||
{
|
||||
memset(rx_ring->rx_bi, 0, sizeof(*rx_ring->rx_bi) * rx_ring->count);
|
||||
@ -1593,6 +1585,11 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
|
||||
|
||||
rx_ring->xdp_prog = rx_ring->vsi->xdp_prog;
|
||||
|
||||
rx_ring->rx_bi =
|
||||
kcalloc(rx_ring->count, sizeof(*rx_ring->rx_bi), GFP_KERNEL);
|
||||
if (!rx_ring->rx_bi)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -469,7 +469,6 @@ int __i40e_maybe_stop_tx(struct i40e_ring *tx_ring, int size);
|
||||
bool __i40e_chk_linearize(struct sk_buff *skb);
|
||||
int i40e_xdp_xmit(struct net_device *dev, int n, struct xdp_frame **frames,
|
||||
u32 flags);
|
||||
int i40e_alloc_rx_bi(struct i40e_ring *rx_ring);
|
||||
|
||||
/**
|
||||
* i40e_get_head - Retrieve head from head writeback
|
||||
|
@ -10,14 +10,6 @@
|
||||
#include "i40e_txrx_common.h"
|
||||
#include "i40e_xsk.h"
|
||||
|
||||
int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring)
|
||||
{
|
||||
unsigned long sz = sizeof(*rx_ring->rx_bi_zc) * rx_ring->count;
|
||||
|
||||
rx_ring->rx_bi_zc = kzalloc(sz, GFP_KERNEL);
|
||||
return rx_ring->rx_bi_zc ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring)
|
||||
{
|
||||
memset(rx_ring->rx_bi_zc, 0,
|
||||
@ -29,6 +21,58 @@ static struct xdp_buff **i40e_rx_bi(struct i40e_ring *rx_ring, u32 idx)
|
||||
return &rx_ring->rx_bi_zc[idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_realloc_rx_xdp_bi - reallocate SW ring for either XSK or normal buffer
|
||||
* @rx_ring: Current rx ring
|
||||
* @pool_present: is pool for XSK present
|
||||
*
|
||||
* Try allocating memory and return ENOMEM, if failed to allocate.
|
||||
* If allocation was successful, substitute buffer with allocated one.
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
static int i40e_realloc_rx_xdp_bi(struct i40e_ring *rx_ring, bool pool_present)
|
||||
{
|
||||
size_t elem_size = pool_present ? sizeof(*rx_ring->rx_bi_zc) :
|
||||
sizeof(*rx_ring->rx_bi);
|
||||
void *sw_ring = kcalloc(rx_ring->count, elem_size, GFP_KERNEL);
|
||||
|
||||
if (!sw_ring)
|
||||
return -ENOMEM;
|
||||
|
||||
if (pool_present) {
|
||||
kfree(rx_ring->rx_bi);
|
||||
rx_ring->rx_bi = NULL;
|
||||
rx_ring->rx_bi_zc = sw_ring;
|
||||
} else {
|
||||
kfree(rx_ring->rx_bi_zc);
|
||||
rx_ring->rx_bi_zc = NULL;
|
||||
rx_ring->rx_bi = sw_ring;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_realloc_rx_bi_zc - reallocate rx SW rings
|
||||
* @vsi: Current VSI
|
||||
* @zc: is zero copy set
|
||||
*
|
||||
* Reallocate buffer for rx_rings that might be used by XSK.
|
||||
* XDP requires more memory, than rx_buf provides.
|
||||
* Returns 0 on success, negative on failure
|
||||
*/
|
||||
int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc)
|
||||
{
|
||||
struct i40e_ring *rx_ring;
|
||||
unsigned long q;
|
||||
|
||||
for_each_set_bit(q, vsi->af_xdp_zc_qps, vsi->alloc_queue_pairs) {
|
||||
rx_ring = vsi->rx_rings[q];
|
||||
if (i40e_realloc_rx_xdp_bi(rx_ring, zc))
|
||||
return -ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_xsk_pool_enable - Enable/associate an AF_XDP buffer pool to a
|
||||
* certain ring/qid
|
||||
@ -69,6 +113,10 @@ static int i40e_xsk_pool_enable(struct i40e_vsi *vsi,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], true);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = i40e_queue_pair_enable(vsi, qid);
|
||||
if (err)
|
||||
return err;
|
||||
@ -113,6 +161,9 @@ static int i40e_xsk_pool_disable(struct i40e_vsi *vsi, u16 qid)
|
||||
xsk_pool_dma_unmap(pool, I40E_RX_DMA_ATTR);
|
||||
|
||||
if (if_running) {
|
||||
err = i40e_realloc_rx_xdp_bi(vsi->rx_rings[qid], false);
|
||||
if (err)
|
||||
return err;
|
||||
err = i40e_queue_pair_enable(vsi, qid);
|
||||
if (err)
|
||||
return err;
|
||||
|
@ -32,7 +32,7 @@ int i40e_clean_rx_irq_zc(struct i40e_ring *rx_ring, int budget);
|
||||
|
||||
bool i40e_clean_xdp_tx_irq(struct i40e_vsi *vsi, struct i40e_ring *tx_ring);
|
||||
int i40e_xsk_wakeup(struct net_device *dev, u32 queue_id, u32 flags);
|
||||
int i40e_alloc_rx_bi_zc(struct i40e_ring *rx_ring);
|
||||
int i40e_realloc_rx_bi_zc(struct i40e_vsi *vsi, bool zc);
|
||||
void i40e_clear_rx_bi_zc(struct i40e_ring *rx_ring);
|
||||
|
||||
#endif /* _I40E_XSK_H_ */
|
||||
|
@ -815,6 +815,7 @@ free_flowid:
|
||||
cn10k_mcs_free_rsrc(pfvf, MCS_TX, MCS_RSRC_TYPE_FLOWID,
|
||||
txsc->hw_flow_id, false);
|
||||
fail:
|
||||
kfree(txsc);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
@ -870,6 +871,7 @@ free_flowid:
|
||||
cn10k_mcs_free_rsrc(pfvf, MCS_RX, MCS_RSRC_TYPE_FLOWID,
|
||||
rxsc->hw_flow_id, false);
|
||||
fail:
|
||||
kfree(rxsc);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
|
@ -4060,19 +4060,23 @@ static int mtk_probe(struct platform_device *pdev)
|
||||
eth->irq[i] = platform_get_irq(pdev, i);
|
||||
if (eth->irq[i] < 0) {
|
||||
dev_err(&pdev->dev, "no IRQ%d resource found\n", i);
|
||||
return -ENXIO;
|
||||
err = -ENXIO;
|
||||
goto err_wed_exit;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(eth->clks); i++) {
|
||||
eth->clks[i] = devm_clk_get(eth->dev,
|
||||
mtk_clks_source_name[i]);
|
||||
if (IS_ERR(eth->clks[i])) {
|
||||
if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER)
|
||||
return -EPROBE_DEFER;
|
||||
if (PTR_ERR(eth->clks[i]) == -EPROBE_DEFER) {
|
||||
err = -EPROBE_DEFER;
|
||||
goto err_wed_exit;
|
||||
}
|
||||
if (eth->soc->required_clks & BIT(i)) {
|
||||
dev_err(&pdev->dev, "clock %s not found\n",
|
||||
mtk_clks_source_name[i]);
|
||||
return -EINVAL;
|
||||
err = -EINVAL;
|
||||
goto err_wed_exit;
|
||||
}
|
||||
eth->clks[i] = NULL;
|
||||
}
|
||||
@ -4083,7 +4087,7 @@ static int mtk_probe(struct platform_device *pdev)
|
||||
|
||||
err = mtk_hw_init(eth);
|
||||
if (err)
|
||||
return err;
|
||||
goto err_wed_exit;
|
||||
|
||||
eth->hwlro = MTK_HAS_CAPS(eth->soc->caps, MTK_HWLRO);
|
||||
|
||||
@ -4179,6 +4183,8 @@ err_free_dev:
|
||||
mtk_free_dev(eth);
|
||||
err_deinit_hw:
|
||||
mtk_hw_deinit(eth);
|
||||
err_wed_exit:
|
||||
mtk_wed_exit();
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -4198,6 +4204,7 @@ static int mtk_remove(struct platform_device *pdev)
|
||||
phylink_disconnect_phy(mac->phylink);
|
||||
}
|
||||
|
||||
mtk_wed_exit();
|
||||
mtk_hw_deinit(eth);
|
||||
|
||||
netif_napi_del(ð->tx_napi);
|
||||
|
@ -397,12 +397,6 @@ int mtk_foe_entry_set_wdma(struct mtk_eth *eth, struct mtk_foe_entry *entry,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline bool mtk_foe_entry_usable(struct mtk_foe_entry *entry)
|
||||
{
|
||||
return !(entry->ib1 & MTK_FOE_IB1_STATIC) &&
|
||||
FIELD_GET(MTK_FOE_IB1_STATE, entry->ib1) != MTK_FOE_STATE_BIND;
|
||||
}
|
||||
|
||||
static bool
|
||||
mtk_flow_entry_match(struct mtk_eth *eth, struct mtk_flow_entry *entry,
|
||||
struct mtk_foe_entry *data)
|
||||
|
@ -1072,16 +1072,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
|
||||
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev)
|
||||
return;
|
||||
goto err_of_node_put;
|
||||
|
||||
get_device(&pdev->dev);
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq < 0)
|
||||
return;
|
||||
goto err_put_device;
|
||||
|
||||
regs = syscon_regmap_lookup_by_phandle(np, NULL);
|
||||
if (IS_ERR(regs))
|
||||
return;
|
||||
goto err_put_device;
|
||||
|
||||
rcu_assign_pointer(mtk_soc_wed_ops, &wed_ops);
|
||||
|
||||
@ -1124,8 +1124,16 @@ void mtk_wed_add_hw(struct device_node *np, struct mtk_eth *eth,
|
||||
|
||||
hw_list[index] = hw;
|
||||
|
||||
mutex_unlock(&hw_lock);
|
||||
|
||||
return;
|
||||
|
||||
unlock:
|
||||
mutex_unlock(&hw_lock);
|
||||
err_put_device:
|
||||
put_device(&pdev->dev);
|
||||
err_of_node_put:
|
||||
of_node_put(np);
|
||||
}
|
||||
|
||||
void mtk_wed_exit(void)
|
||||
@ -1146,6 +1154,7 @@ void mtk_wed_exit(void)
|
||||
hw_list[i] = NULL;
|
||||
debugfs_remove(hw->debugfs_dir);
|
||||
put_device(hw->dev);
|
||||
of_node_put(hw->node);
|
||||
kfree(hw);
|
||||
}
|
||||
}
|
||||
|
@ -2817,11 +2817,15 @@ err_out:
|
||||
* than the full array, but leave the qcq shells in place
|
||||
*/
|
||||
for (i = lif->nxqs; i < lif->ionic->ntxqs_per_lif; i++) {
|
||||
lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->txqcqs[i]);
|
||||
if (lif->txqcqs && lif->txqcqs[i]) {
|
||||
lif->txqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->txqcqs[i]);
|
||||
}
|
||||
|
||||
lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->rxqcqs[i]);
|
||||
if (lif->rxqcqs && lif->rxqcqs[i]) {
|
||||
lif->rxqcqs[i]->flags &= ~IONIC_QCQ_F_INTR;
|
||||
ionic_qcq_free(lif, lif->rxqcqs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (err)
|
||||
|
@ -3277,6 +3277,30 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
|
||||
bool was_enabled = efx->port_enabled;
|
||||
int rc;
|
||||
|
||||
#ifdef CONFIG_SFC_SRIOV
|
||||
/* If this function is a VF and we have access to the parent PF,
|
||||
* then use the PF control path to attempt to change the VF MAC address.
|
||||
*/
|
||||
if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
|
||||
struct efx_nic *efx_pf = pci_get_drvdata(efx->pci_dev->physfn);
|
||||
struct efx_ef10_nic_data *nic_data = efx->nic_data;
|
||||
u8 mac[ETH_ALEN];
|
||||
|
||||
/* net_dev->dev_addr can be zeroed by efx_net_stop in
|
||||
* efx_ef10_sriov_set_vf_mac, so pass in a copy.
|
||||
*/
|
||||
ether_addr_copy(mac, efx->net_dev->dev_addr);
|
||||
|
||||
rc = efx_ef10_sriov_set_vf_mac(efx_pf, nic_data->vf_index, mac);
|
||||
if (!rc)
|
||||
return 0;
|
||||
|
||||
netif_dbg(efx, drv, efx->net_dev,
|
||||
"Updating VF mac via PF failed (%d), setting directly\n",
|
||||
rc);
|
||||
}
|
||||
#endif
|
||||
|
||||
efx_device_detach_sync(efx);
|
||||
efx_net_stop(efx->net_dev);
|
||||
|
||||
@ -3297,40 +3321,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
|
||||
efx_net_open(efx->net_dev);
|
||||
efx_device_attach_if_not_resetting(efx);
|
||||
|
||||
#ifdef CONFIG_SFC_SRIOV
|
||||
if (efx->pci_dev->is_virtfn && efx->pci_dev->physfn) {
|
||||
struct efx_ef10_nic_data *nic_data = efx->nic_data;
|
||||
struct pci_dev *pci_dev_pf = efx->pci_dev->physfn;
|
||||
|
||||
if (rc == -EPERM) {
|
||||
struct efx_nic *efx_pf;
|
||||
|
||||
/* Switch to PF and change MAC address on vport */
|
||||
efx_pf = pci_get_drvdata(pci_dev_pf);
|
||||
|
||||
rc = efx_ef10_sriov_set_vf_mac(efx_pf,
|
||||
nic_data->vf_index,
|
||||
efx->net_dev->dev_addr);
|
||||
} else if (!rc) {
|
||||
struct efx_nic *efx_pf = pci_get_drvdata(pci_dev_pf);
|
||||
struct efx_ef10_nic_data *nic_data = efx_pf->nic_data;
|
||||
unsigned int i;
|
||||
|
||||
/* MAC address successfully changed by VF (with MAC
|
||||
* spoofing) so update the parent PF if possible.
|
||||
*/
|
||||
for (i = 0; i < efx_pf->vf_count; ++i) {
|
||||
struct ef10_vf *vf = nic_data->vf + i;
|
||||
|
||||
if (vf->efx == efx) {
|
||||
ether_addr_copy(vf->mac,
|
||||
efx->net_dev->dev_addr);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
if (rc == -EPERM) {
|
||||
netif_err(efx, drv, efx->net_dev,
|
||||
"Cannot change MAC address; use sfboot to enable"
|
||||
|
@ -162,9 +162,9 @@ struct efx_filter_spec {
|
||||
u32 priority:2;
|
||||
u32 flags:6;
|
||||
u32 dmaq_id:12;
|
||||
u32 vport_id;
|
||||
u32 rss_context;
|
||||
__be16 outer_vid __aligned(4); /* allow jhash2() of match values */
|
||||
u32 vport_id;
|
||||
__be16 outer_vid;
|
||||
__be16 inner_vid;
|
||||
u8 loc_mac[ETH_ALEN];
|
||||
u8 rem_mac[ETH_ALEN];
|
||||
|
@ -660,17 +660,17 @@ bool efx_filter_spec_equal(const struct efx_filter_spec *left,
|
||||
(EFX_FILTER_FLAG_RX | EFX_FILTER_FLAG_TX)))
|
||||
return false;
|
||||
|
||||
return memcmp(&left->outer_vid, &right->outer_vid,
|
||||
return memcmp(&left->vport_id, &right->vport_id,
|
||||
sizeof(struct efx_filter_spec) -
|
||||
offsetof(struct efx_filter_spec, outer_vid)) == 0;
|
||||
offsetof(struct efx_filter_spec, vport_id)) == 0;
|
||||
}
|
||||
|
||||
u32 efx_filter_spec_hash(const struct efx_filter_spec *spec)
|
||||
{
|
||||
BUILD_BUG_ON(offsetof(struct efx_filter_spec, outer_vid) & 3);
|
||||
return jhash2((const u32 *)&spec->outer_vid,
|
||||
BUILD_BUG_ON(offsetof(struct efx_filter_spec, vport_id) & 3);
|
||||
return jhash2((const u32 *)&spec->vport_id,
|
||||
(sizeof(struct efx_filter_spec) -
|
||||
offsetof(struct efx_filter_spec, outer_vid)) / 4,
|
||||
offsetof(struct efx_filter_spec, vport_id)) / 4,
|
||||
0);
|
||||
}
|
||||
|
||||
|
@ -1214,6 +1214,7 @@ static int stmmac_phy_setup(struct stmmac_priv *priv)
|
||||
if (priv->plat->tx_queues_to_use > 1)
|
||||
priv->phylink_config.mac_capabilities &=
|
||||
~(MAC_10HD | MAC_100HD | MAC_1000HD);
|
||||
priv->phylink_config.mac_managed_pm = true;
|
||||
|
||||
phylink = phylink_create(&priv->phylink_config, fwnode,
|
||||
mode, &stmmac_phylink_mac_ops);
|
||||
|
@ -1328,7 +1328,7 @@ static int happy_meal_init(struct happy_meal *hp)
|
||||
void __iomem *erxregs = hp->erxregs;
|
||||
void __iomem *bregs = hp->bigmacregs;
|
||||
void __iomem *tregs = hp->tcvregs;
|
||||
const char *bursts;
|
||||
const char *bursts = "64";
|
||||
u32 regtmp, rxcfg;
|
||||
|
||||
/* If auto-negotiation timer is running, kill it. */
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <linux/vmalloc.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/ucs2_string.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "hyperv_net.h"
|
||||
#include "netvsc_trace.h"
|
||||
@ -335,9 +336,10 @@ static void rndis_filter_receive_response(struct net_device *ndev,
|
||||
if (resp->msg_len <=
|
||||
sizeof(struct rndis_message) + RNDIS_EXT_LEN) {
|
||||
memcpy(&request->response_msg, resp, RNDIS_HEADER_SIZE + sizeof(*req_id));
|
||||
memcpy((void *)&request->response_msg + RNDIS_HEADER_SIZE + sizeof(*req_id),
|
||||
unsafe_memcpy((void *)&request->response_msg + RNDIS_HEADER_SIZE + sizeof(*req_id),
|
||||
data + RNDIS_HEADER_SIZE + sizeof(*req_id),
|
||||
resp->msg_len - RNDIS_HEADER_SIZE - sizeof(*req_id));
|
||||
resp->msg_len - RNDIS_HEADER_SIZE - sizeof(*req_id),
|
||||
"request->response_msg is followed by a padding of RNDIS_EXT_LEN inside rndis_request");
|
||||
if (request->request_msg.ndis_msg_type ==
|
||||
RNDIS_MSG_QUERY && request->request_msg.msg.
|
||||
query_req.oid == RNDIS_OID_GEN_MEDIA_CONNECT_STATUS)
|
||||
|
@ -361,7 +361,7 @@ static void macvlan_broadcast_enqueue(struct macvlan_port *port,
|
||||
}
|
||||
spin_unlock(&port->bc_queue.lock);
|
||||
|
||||
schedule_work(&port->bc_work);
|
||||
queue_work(system_unbound_wq, &port->bc_work);
|
||||
|
||||
if (err)
|
||||
goto free_nskb;
|
||||
|
@ -254,8 +254,7 @@ static int dp83822_config_intr(struct phy_device *phydev)
|
||||
DP83822_EEE_ERROR_CHANGE_INT_EN);
|
||||
|
||||
if (!dp83822->fx_enabled)
|
||||
misr_status |= DP83822_MDI_XOVER_INT_EN |
|
||||
DP83822_ANEG_ERR_INT_EN |
|
||||
misr_status |= DP83822_ANEG_ERR_INT_EN |
|
||||
DP83822_WOL_PKT_INT_EN;
|
||||
|
||||
err = phy_write(phydev, MII_DP83822_MISR2, misr_status);
|
||||
|
@ -853,6 +853,14 @@ static int dp83867_config_init(struct phy_device *phydev)
|
||||
else
|
||||
val &= ~DP83867_SGMII_TYPE;
|
||||
phy_write_mmd(phydev, DP83867_DEVADDR, DP83867_SGMIICTL, val);
|
||||
|
||||
/* This is a SW workaround for link instability if RX_CTRL is
|
||||
* not strapped to mode 3 or 4 in HW. This is required for SGMII
|
||||
* in addition to clearing bit 7, handled above.
|
||||
*/
|
||||
if (dp83867->rxctrl_strap_quirk)
|
||||
phy_set_bits_mmd(phydev, DP83867_DEVADDR, DP83867_CFG4,
|
||||
BIT(8));
|
||||
}
|
||||
|
||||
val = phy_read(phydev, DP83867_CFG3);
|
||||
|
@ -1661,6 +1661,9 @@ static int phylink_bringup_phy(struct phylink *pl, struct phy_device *phy,
|
||||
if (phy_interrupt_is_valid(phy))
|
||||
phy_request_interrupt(phy);
|
||||
|
||||
if (pl->config->mac_managed_pm)
|
||||
phy->mac_managed_pm = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ err_unreg_dev:
|
||||
return ERR_PTR(err);
|
||||
|
||||
err_free_dev:
|
||||
kfree(dev);
|
||||
put_device(&dev->dev);
|
||||
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ struct sk_buff;
|
||||
|
||||
/* Special struct emulating a Ethernet header */
|
||||
struct qca_mgmt_ethhdr {
|
||||
u32 command; /* command bit 31:0 */
|
||||
u32 seq; /* seq 63:32 */
|
||||
u32 mdio_data; /* first 4byte mdio */
|
||||
__le32 command; /* command bit 31:0 */
|
||||
__le32 seq; /* seq 63:32 */
|
||||
__le32 mdio_data; /* first 4byte mdio */
|
||||
__be16 hdr; /* qca hdr */
|
||||
} __packed;
|
||||
|
||||
@ -73,7 +73,7 @@ enum mdio_cmd {
|
||||
};
|
||||
|
||||
struct mib_ethhdr {
|
||||
u32 data[3]; /* first 3 mib counter */
|
||||
__le32 data[3]; /* first 3 mib counter */
|
||||
__be16 hdr; /* qca hdr */
|
||||
} __packed;
|
||||
|
||||
|
@ -3663,8 +3663,9 @@ static inline bool netif_attr_test_online(unsigned long j,
|
||||
static inline unsigned int netif_attrmask_next(int n, const unsigned long *srcp,
|
||||
unsigned int nr_bits)
|
||||
{
|
||||
/* n is a prior cpu */
|
||||
cpu_max_bits_warn(n + 1, nr_bits);
|
||||
/* -1 is a legal arg here. */
|
||||
if (n != -1)
|
||||
cpu_max_bits_warn(n, nr_bits);
|
||||
|
||||
if (srcp)
|
||||
return find_next_bit(srcp, nr_bits, n + 1);
|
||||
@ -3685,8 +3686,9 @@ static inline int netif_attrmask_next_and(int n, const unsigned long *src1p,
|
||||
const unsigned long *src2p,
|
||||
unsigned int nr_bits)
|
||||
{
|
||||
/* n is a prior cpu */
|
||||
cpu_max_bits_warn(n + 1, nr_bits);
|
||||
/* -1 is a legal arg here. */
|
||||
if (n != -1)
|
||||
cpu_max_bits_warn(n, nr_bits);
|
||||
|
||||
if (src1p && src2p)
|
||||
return find_next_and_bit(src1p, src2p, nr_bits, n + 1);
|
||||
|
@ -122,6 +122,7 @@ enum phylink_op_type {
|
||||
* (See commit 7cceb599d15d ("net: phylink: avoid mac_config calls")
|
||||
* @poll_fixed_state: if true, starts link_poll,
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
* @mac_managed_pm: if true, indicate the MAC driver is responsible for PHY PM.
|
||||
* @ovr_an_inband: if true, override PCS to MLO_AN_INBAND
|
||||
* @get_fixed_state: callback to execute to determine the fixed link state,
|
||||
* if MAC link is at %MLO_AN_FIXED mode.
|
||||
@ -134,6 +135,7 @@ struct phylink_config {
|
||||
enum phylink_op_type type;
|
||||
bool legacy_pre_march2020;
|
||||
bool poll_fixed_state;
|
||||
bool mac_managed_pm;
|
||||
bool ovr_an_inband;
|
||||
void (*get_fixed_state)(struct phylink_config *config,
|
||||
struct phylink_link_state *state);
|
||||
|
@ -37,6 +37,7 @@ struct genl_info;
|
||||
* do additional, common, filtering and return an error
|
||||
* @post_doit: called after an operation's doit callback, it may
|
||||
* undo operations done by pre_doit, for example release locks
|
||||
* @module: pointer to the owning module (set to THIS_MODULE)
|
||||
* @mcgrps: multicast groups used by this family
|
||||
* @n_mcgrps: number of multicast groups
|
||||
* @resv_start_op: first operation for which reserved fields of the header
|
||||
@ -173,9 +174,9 @@ struct genl_ops {
|
||||
};
|
||||
|
||||
/**
|
||||
* struct genl_info - info that is available during dumpit op call
|
||||
* struct genl_dumpit_info - info that is available during dumpit op call
|
||||
* @family: generic netlink family - for internal genl code usage
|
||||
* @ops: generic netlink ops - for internal genl code usage
|
||||
* @op: generic netlink ops - for internal genl code usage
|
||||
* @attrs: netlink attributes
|
||||
*/
|
||||
struct genl_dumpit_info {
|
||||
@ -354,6 +355,7 @@ int genlmsg_multicast_allns(const struct genl_family *family,
|
||||
|
||||
/**
|
||||
* genlmsg_unicast - unicast a netlink message
|
||||
* @net: network namespace to look up @portid in
|
||||
* @skb: netlink message as socket buffer
|
||||
* @portid: netlink portid of the destination socket
|
||||
*/
|
||||
@ -373,7 +375,7 @@ static inline int genlmsg_reply(struct sk_buff *skb, struct genl_info *info)
|
||||
}
|
||||
|
||||
/**
|
||||
* gennlmsg_data - head of message payload
|
||||
* genlmsg_data - head of message payload
|
||||
* @gnlh: genetlink message header
|
||||
*/
|
||||
static inline void *genlmsg_data(const struct genlmsghdr *gnlh)
|
||||
|
@ -43,21 +43,20 @@ struct sock *reuseport_migrate_sock(struct sock *sk,
|
||||
extern int reuseport_attach_prog(struct sock *sk, struct bpf_prog *prog);
|
||||
extern int reuseport_detach_prog(struct sock *sk);
|
||||
|
||||
static inline bool reuseport_has_conns(struct sock *sk, bool set)
|
||||
static inline bool reuseport_has_conns(struct sock *sk)
|
||||
{
|
||||
struct sock_reuseport *reuse;
|
||||
bool ret = false;
|
||||
|
||||
rcu_read_lock();
|
||||
reuse = rcu_dereference(sk->sk_reuseport_cb);
|
||||
if (reuse) {
|
||||
if (set)
|
||||
reuse->has_conns = 1;
|
||||
ret = reuse->has_conns;
|
||||
}
|
||||
if (reuse && reuse->has_conns)
|
||||
ret = true;
|
||||
rcu_read_unlock();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reuseport_has_conns_set(struct sock *sk);
|
||||
|
||||
#endif /* _SOCK_REUSEPORT_H */
|
||||
|
@ -219,11 +219,12 @@ static ssize_t proc_mpc_write(struct file *file, const char __user *buff,
|
||||
if (!page)
|
||||
return -ENOMEM;
|
||||
|
||||
for (p = page, len = 0; len < nbytes; p++, len++) {
|
||||
for (p = page, len = 0; len < nbytes; p++) {
|
||||
if (get_user(*p, buff++)) {
|
||||
free_page((unsigned long)page);
|
||||
return -EFAULT;
|
||||
}
|
||||
len += 1;
|
||||
if (*p == '\0' || *p == '\n')
|
||||
break;
|
||||
}
|
||||
|
@ -5136,11 +5136,13 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
|
||||
case TC_ACT_SHOT:
|
||||
mini_qdisc_qstats_cpu_drop(miniq);
|
||||
kfree_skb_reason(skb, SKB_DROP_REASON_TC_INGRESS);
|
||||
*ret = NET_RX_DROP;
|
||||
return NULL;
|
||||
case TC_ACT_STOLEN:
|
||||
case TC_ACT_QUEUED:
|
||||
case TC_ACT_TRAP:
|
||||
consume_skb(skb);
|
||||
*ret = NET_RX_SUCCESS;
|
||||
return NULL;
|
||||
case TC_ACT_REDIRECT:
|
||||
/* skb_mac_header check was done by cls/act_bpf, so
|
||||
@ -5153,8 +5155,10 @@ sch_handle_ingress(struct sk_buff *skb, struct packet_type **pt_prev, int *ret,
|
||||
*another = true;
|
||||
break;
|
||||
}
|
||||
*ret = NET_RX_SUCCESS;
|
||||
return NULL;
|
||||
case TC_ACT_CONSUMED:
|
||||
*ret = NET_RX_SUCCESS;
|
||||
return NULL;
|
||||
default:
|
||||
break;
|
||||
|
@ -500,11 +500,11 @@ bool sk_msg_is_readable(struct sock *sk)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(sk_msg_is_readable);
|
||||
|
||||
static struct sk_msg *alloc_sk_msg(void)
|
||||
static struct sk_msg *alloc_sk_msg(gfp_t gfp)
|
||||
{
|
||||
struct sk_msg *msg;
|
||||
|
||||
msg = kzalloc(sizeof(*msg), __GFP_NOWARN | GFP_KERNEL);
|
||||
msg = kzalloc(sizeof(*msg), gfp | __GFP_NOWARN);
|
||||
if (unlikely(!msg))
|
||||
return NULL;
|
||||
sg_init_marker(msg->sg.data, NR_MSG_FRAG_IDS);
|
||||
@ -520,7 +520,7 @@ static struct sk_msg *sk_psock_create_ingress_msg(struct sock *sk,
|
||||
if (!sk_rmem_schedule(sk, skb, skb->truesize))
|
||||
return NULL;
|
||||
|
||||
return alloc_sk_msg();
|
||||
return alloc_sk_msg(GFP_KERNEL);
|
||||
}
|
||||
|
||||
static int sk_psock_skb_ingress_enqueue(struct sk_buff *skb,
|
||||
@ -597,7 +597,7 @@ static int sk_psock_skb_ingress(struct sk_psock *psock, struct sk_buff *skb,
|
||||
static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skb,
|
||||
u32 off, u32 len)
|
||||
{
|
||||
struct sk_msg *msg = alloc_sk_msg();
|
||||
struct sk_msg *msg = alloc_sk_msg(GFP_ATOMIC);
|
||||
struct sock *sk = psock->sk;
|
||||
int err;
|
||||
|
||||
|
@ -21,6 +21,22 @@ static DEFINE_IDA(reuseport_ida);
|
||||
static int reuseport_resurrect(struct sock *sk, struct sock_reuseport *old_reuse,
|
||||
struct sock_reuseport *reuse, bool bind_inany);
|
||||
|
||||
void reuseport_has_conns_set(struct sock *sk)
|
||||
{
|
||||
struct sock_reuseport *reuse;
|
||||
|
||||
if (!rcu_access_pointer(sk->sk_reuseport_cb))
|
||||
return;
|
||||
|
||||
spin_lock_bh(&reuseport_lock);
|
||||
reuse = rcu_dereference_protected(sk->sk_reuseport_cb,
|
||||
lockdep_is_held(&reuseport_lock));
|
||||
if (likely(reuse))
|
||||
reuse->has_conns = 1;
|
||||
spin_unlock_bh(&reuseport_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(reuseport_has_conns_set);
|
||||
|
||||
static int reuseport_sock_index(struct sock *sk,
|
||||
const struct sock_reuseport *reuse,
|
||||
bool closed)
|
||||
|
@ -3145,7 +3145,7 @@ static int dsa_slave_netdevice_event(struct notifier_block *nb,
|
||||
case NETDEV_CHANGELOWERSTATE: {
|
||||
struct netdev_notifier_changelowerstate_info *info = ptr;
|
||||
struct dsa_port *dp;
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
if (dsa_slave_dev_check(dev)) {
|
||||
dp = dsa_slave_to_port(dev);
|
||||
|
@ -150,15 +150,15 @@ struct sk_buff *hsr_get_untagged_frame(struct hsr_frame_info *frame,
|
||||
struct hsr_port *port)
|
||||
{
|
||||
if (!frame->skb_std) {
|
||||
if (frame->skb_hsr) {
|
||||
if (frame->skb_hsr)
|
||||
frame->skb_std =
|
||||
create_stripped_skb_hsr(frame->skb_hsr, frame);
|
||||
} else {
|
||||
/* Unexpected */
|
||||
WARN_ONCE(1, "%s:%d: Unexpected frame received (port_src %s)\n",
|
||||
__FILE__, __LINE__, port->dev->name);
|
||||
else
|
||||
netdev_warn_once(port->dev,
|
||||
"Unexpected frame received in hsr_get_untagged_frame()\n");
|
||||
|
||||
if (!frame->skb_std)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return skb_clone(frame->skb_std, GFP_ATOMIC);
|
||||
|
@ -70,7 +70,7 @@ int __ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len
|
||||
}
|
||||
inet->inet_daddr = fl4->daddr;
|
||||
inet->inet_dport = usin->sin_port;
|
||||
reuseport_has_conns(sk, true);
|
||||
reuseport_has_conns_set(sk);
|
||||
sk->sk_state = TCP_ESTABLISHED;
|
||||
sk_set_txhash(sk);
|
||||
inet->inet_id = get_random_u16();
|
||||
|
@ -78,6 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
|
||||
flow.flowi4_tos = iph->tos & IPTOS_RT_MASK;
|
||||
flow.flowi4_scope = RT_SCOPE_UNIVERSE;
|
||||
flow.flowi4_l3mdev = l3mdev_master_ifindex_rcu(xt_in(par));
|
||||
flow.flowi4_uid = sock_net_uid(xt_net(par), NULL);
|
||||
|
||||
return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert;
|
||||
}
|
||||
|
@ -65,6 +65,7 @@ void nft_fib4_eval(const struct nft_expr *expr, struct nft_regs *regs,
|
||||
struct flowi4 fl4 = {
|
||||
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
||||
.flowi4_iif = LOOPBACK_IFINDEX,
|
||||
.flowi4_uid = sock_net_uid(nft_net(pkt), NULL),
|
||||
};
|
||||
const struct net_device *oif;
|
||||
const struct net_device *found;
|
||||
|
@ -448,7 +448,7 @@ static struct sock *udp4_lib_lookup2(struct net *net,
|
||||
result = lookup_reuseport(net, sk, skb,
|
||||
saddr, sport, daddr, hnum);
|
||||
/* Fall back to scoring if group has connections */
|
||||
if (result && !reuseport_has_conns(sk, false))
|
||||
if (result && !reuseport_has_conns(sk))
|
||||
return result;
|
||||
|
||||
result = result ? : sk;
|
||||
|
@ -7214,9 +7214,11 @@ err_reg_dflt:
|
||||
__addrconf_sysctl_unregister(net, all, NETCONFA_IFINDEX_ALL);
|
||||
err_reg_all:
|
||||
kfree(dflt);
|
||||
net->ipv6.devconf_dflt = NULL;
|
||||
#endif
|
||||
err_alloc_dflt:
|
||||
kfree(all);
|
||||
net->ipv6.devconf_all = NULL;
|
||||
err_alloc_all:
|
||||
kfree(net->ipv6.inet6_addr_lst);
|
||||
err_alloc_addr:
|
||||
|
@ -256,7 +256,7 @@ ipv4_connected:
|
||||
goto out;
|
||||
}
|
||||
|
||||
reuseport_has_conns(sk, true);
|
||||
reuseport_has_conns_set(sk);
|
||||
sk->sk_state = TCP_ESTABLISHED;
|
||||
sk_set_txhash(sk);
|
||||
out:
|
||||
|
@ -40,6 +40,7 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb,
|
||||
.flowi6_l3mdev = l3mdev_master_ifindex_rcu(dev),
|
||||
.flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK,
|
||||
.flowi6_proto = iph->nexthdr,
|
||||
.flowi6_uid = sock_net_uid(net, NULL),
|
||||
.daddr = iph->saddr,
|
||||
};
|
||||
int lookup_flags;
|
||||
|
@ -66,6 +66,7 @@ static u32 __nft_fib6_eval_type(const struct nft_fib *priv,
|
||||
struct flowi6 fl6 = {
|
||||
.flowi6_iif = LOOPBACK_IFINDEX,
|
||||
.flowi6_proto = pkt->tprot,
|
||||
.flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
|
||||
};
|
||||
u32 ret = 0;
|
||||
|
||||
@ -163,6 +164,7 @@ void nft_fib6_eval(const struct nft_expr *expr, struct nft_regs *regs,
|
||||
struct flowi6 fl6 = {
|
||||
.flowi6_iif = LOOPBACK_IFINDEX,
|
||||
.flowi6_proto = pkt->tprot,
|
||||
.flowi6_uid = sock_net_uid(nft_net(pkt), NULL),
|
||||
};
|
||||
struct rt6_info *rt;
|
||||
int lookup_flags;
|
||||
|
@ -195,7 +195,7 @@ static struct sock *udp6_lib_lookup2(struct net *net,
|
||||
result = lookup_reuseport(net, sk, skb,
|
||||
saddr, sport, daddr, hnum);
|
||||
/* Fall back to scoring if group has connections */
|
||||
if (result && !reuseport_has_conns(sk, false))
|
||||
if (result && !reuseport_has_conns(sk))
|
||||
return result;
|
||||
|
||||
result = result ? : sk;
|
||||
|
@ -5865,8 +5865,9 @@ static bool nft_setelem_valid_key_end(const struct nft_set *set,
|
||||
(NFT_SET_CONCAT | NFT_SET_INTERVAL)) {
|
||||
if (flags & NFT_SET_ELEM_INTERVAL_END)
|
||||
return false;
|
||||
if (!nla[NFTA_SET_ELEM_KEY_END] &&
|
||||
!(flags & NFT_SET_ELEM_CATCHALL))
|
||||
|
||||
if (nla[NFTA_SET_ELEM_KEY_END] &&
|
||||
flags & NFT_SET_ELEM_CATCHALL)
|
||||
return false;
|
||||
} else {
|
||||
if (nla[NFTA_SET_ELEM_KEY_END])
|
||||
|
@ -1099,12 +1099,13 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
|
||||
|
||||
skip:
|
||||
if (!ingress) {
|
||||
notify_and_destroy(net, skb, n, classid,
|
||||
rtnl_dereference(dev->qdisc), new);
|
||||
old = rtnl_dereference(dev->qdisc);
|
||||
if (new && !new->ops->attach)
|
||||
qdisc_refcount_inc(new);
|
||||
rcu_assign_pointer(dev->qdisc, new ? : &noop_qdisc);
|
||||
|
||||
notify_and_destroy(net, skb, n, classid, old, new);
|
||||
|
||||
if (new && new->ops->attach)
|
||||
new->ops->attach(new);
|
||||
} else {
|
||||
|
@ -2224,8 +2224,12 @@ retry:
|
||||
|
||||
static void cake_reset(struct Qdisc *sch)
|
||||
{
|
||||
struct cake_sched_data *q = qdisc_priv(sch);
|
||||
u32 c;
|
||||
|
||||
if (!q->tins)
|
||||
return;
|
||||
|
||||
for (c = 0; c < CAKE_MAX_TINS; c++)
|
||||
cake_clear_tin(sch, c);
|
||||
}
|
||||
|
@ -478,24 +478,26 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
|
||||
if (opt) {
|
||||
err = fq_codel_change(sch, opt, extack);
|
||||
if (err)
|
||||
return err;
|
||||
goto init_failure;
|
||||
}
|
||||
|
||||
err = tcf_block_get(&q->block, &q->filter_list, sch, extack);
|
||||
if (err)
|
||||
return err;
|
||||
goto init_failure;
|
||||
|
||||
if (!q->flows) {
|
||||
q->flows = kvcalloc(q->flows_cnt,
|
||||
sizeof(struct fq_codel_flow),
|
||||
GFP_KERNEL);
|
||||
if (!q->flows)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!q->flows) {
|
||||
err = -ENOMEM;
|
||||
goto init_failure;
|
||||
}
|
||||
q->backlogs = kvcalloc(q->flows_cnt, sizeof(u32), GFP_KERNEL);
|
||||
if (!q->backlogs)
|
||||
return -ENOMEM;
|
||||
|
||||
if (!q->backlogs) {
|
||||
err = -ENOMEM;
|
||||
goto alloc_failure;
|
||||
}
|
||||
for (i = 0; i < q->flows_cnt; i++) {
|
||||
struct fq_codel_flow *flow = q->flows + i;
|
||||
|
||||
@ -508,6 +510,13 @@ static int fq_codel_init(struct Qdisc *sch, struct nlattr *opt,
|
||||
else
|
||||
sch->flags &= ~TCQ_F_CAN_BYPASS;
|
||||
return 0;
|
||||
|
||||
alloc_failure:
|
||||
kvfree(q->flows);
|
||||
q->flows = NULL;
|
||||
init_failure:
|
||||
q->flows_cnt = 0;
|
||||
return err;
|
||||
}
|
||||
|
||||
static int fq_codel_dump(struct Qdisc *sch, struct sk_buff *skb)
|
||||
|
@ -455,7 +455,8 @@ static void sfb_reset(struct Qdisc *sch)
|
||||
{
|
||||
struct sfb_sched_data *q = qdisc_priv(sch);
|
||||
|
||||
qdisc_reset(q->qdisc);
|
||||
if (likely(q->qdisc))
|
||||
qdisc_reset(q->qdisc);
|
||||
q->slot = 0;
|
||||
q->double_buffering = false;
|
||||
sfb_zero_all_buckets(q);
|
||||
|
@ -896,7 +896,8 @@ static int smc_lgr_create(struct smc_sock *smc, struct smc_init_info *ini)
|
||||
}
|
||||
memcpy(lgr->pnet_id, ibdev->pnetid[ibport - 1],
|
||||
SMC_MAX_PNETID_LEN);
|
||||
if (smc_wr_alloc_lgr_mem(lgr))
|
||||
rc = smc_wr_alloc_lgr_mem(lgr);
|
||||
if (rc)
|
||||
goto free_wq;
|
||||
smc_llc_lgr_init(lgr, smc);
|
||||
|
||||
|
@ -148,8 +148,8 @@ static bool tipc_disc_addr_trial_msg(struct tipc_discoverer *d,
|
||||
{
|
||||
struct net *net = d->net;
|
||||
struct tipc_net *tn = tipc_net(net);
|
||||
bool trial = time_before(jiffies, tn->addr_trial_end);
|
||||
u32 self = tipc_own_addr(net);
|
||||
bool trial = time_before(jiffies, tn->addr_trial_end) && !self;
|
||||
|
||||
if (mtyp == DSC_TRIAL_FAIL_MSG) {
|
||||
if (!trial)
|
||||
|
@ -568,7 +568,7 @@ bool tipc_topsrv_kern_subscr(struct net *net, u32 port, u32 type, u32 lower,
|
||||
sub.seq.upper = upper;
|
||||
sub.timeout = TIPC_WAIT_FOREVER;
|
||||
sub.filter = filter;
|
||||
*(u32 *)&sub.usr_handle = port;
|
||||
*(u64 *)&sub.usr_handle = (u64)port;
|
||||
|
||||
con = tipc_conn_alloc(tipc_topsrv(net));
|
||||
if (IS_ERR(con))
|
||||
|
@ -273,7 +273,7 @@ static int tls_strp_read_copyin(struct tls_strparser *strp)
|
||||
return desc.error;
|
||||
}
|
||||
|
||||
static int tls_strp_read_short(struct tls_strparser *strp)
|
||||
static int tls_strp_read_copy(struct tls_strparser *strp, bool qshort)
|
||||
{
|
||||
struct skb_shared_info *shinfo;
|
||||
struct page *page;
|
||||
@ -283,7 +283,7 @@ static int tls_strp_read_short(struct tls_strparser *strp)
|
||||
* to read the data out. Otherwise the connection will stall.
|
||||
* Without pressure threshold of INT_MAX will never be ready.
|
||||
*/
|
||||
if (likely(!tcp_epollin_ready(strp->sk, INT_MAX)))
|
||||
if (likely(qshort && !tcp_epollin_ready(strp->sk, INT_MAX)))
|
||||
return 0;
|
||||
|
||||
shinfo = skb_shinfo(strp->anchor);
|
||||
@ -315,6 +315,27 @@ static int tls_strp_read_short(struct tls_strparser *strp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool tls_strp_check_no_dup(struct tls_strparser *strp)
|
||||
{
|
||||
unsigned int len = strp->stm.offset + strp->stm.full_len;
|
||||
struct sk_buff *skb;
|
||||
u32 seq;
|
||||
|
||||
skb = skb_shinfo(strp->anchor)->frag_list;
|
||||
seq = TCP_SKB_CB(skb)->seq;
|
||||
|
||||
while (skb->len < len) {
|
||||
seq += skb->len;
|
||||
len -= skb->len;
|
||||
skb = skb->next;
|
||||
|
||||
if (TCP_SKB_CB(skb)->seq != seq)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tls_strp_load_anchor_with_queue(struct tls_strparser *strp, int len)
|
||||
{
|
||||
struct tcp_sock *tp = tcp_sk(strp->sk);
|
||||
@ -373,7 +394,7 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
|
||||
return tls_strp_read_copyin(strp);
|
||||
|
||||
if (inq < strp->stm.full_len)
|
||||
return tls_strp_read_short(strp);
|
||||
return tls_strp_read_copy(strp, true);
|
||||
|
||||
if (!strp->stm.full_len) {
|
||||
tls_strp_load_anchor_with_queue(strp, inq);
|
||||
@ -387,9 +408,12 @@ static int tls_strp_read_sock(struct tls_strparser *strp)
|
||||
strp->stm.full_len = sz;
|
||||
|
||||
if (!strp->stm.full_len || inq < strp->stm.full_len)
|
||||
return tls_strp_read_short(strp);
|
||||
return tls_strp_read_copy(strp, true);
|
||||
}
|
||||
|
||||
if (!tls_strp_check_no_dup(strp))
|
||||
return tls_strp_read_copy(strp, false);
|
||||
|
||||
strp->msg_ready = 1;
|
||||
tls_rx_msg_ready(strp);
|
||||
|
||||
|
@ -70,6 +70,7 @@ TEST_PROGS += io_uring_zerocopy_tx.sh
|
||||
TEST_GEN_FILES += bind_bhash
|
||||
TEST_GEN_PROGS += sk_bind_sendto_listen
|
||||
TEST_GEN_PROGS += sk_connect_zero_addr
|
||||
TEST_PROGS += test_ingress_egress_chaining.sh
|
||||
|
||||
TEST_FILES := settings
|
||||
|
||||
|
79
tools/testing/selftests/net/test_ingress_egress_chaining.sh
Normal file
79
tools/testing/selftests/net/test_ingress_egress_chaining.sh
Normal file
@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
# This test runs a simple ingress tc setup between two veth pairs,
|
||||
# and chains a single egress rule to test ingress chaining to egress.
|
||||
#
|
||||
# Kselftest framework requirement - SKIP code is 4.
|
||||
ksft_skip=4
|
||||
|
||||
if [ "$(id -u)" -ne 0 ];then
|
||||
echo "SKIP: Need root privileges"
|
||||
exit $ksft_skip
|
||||
fi
|
||||
|
||||
needed_mods="act_mirred cls_flower sch_ingress"
|
||||
for mod in $needed_mods; do
|
||||
modinfo $mod &>/dev/null || { echo "SKIP: Need act_mirred module"; exit $ksft_skip; }
|
||||
done
|
||||
|
||||
ns="ns$((RANDOM%899+100))"
|
||||
veth1="veth1$((RANDOM%899+100))"
|
||||
veth2="veth2$((RANDOM%899+100))"
|
||||
peer1="peer1$((RANDOM%899+100))"
|
||||
peer2="peer2$((RANDOM%899+100))"
|
||||
ip_peer1=198.51.100.5
|
||||
ip_peer2=198.51.100.6
|
||||
|
||||
function fail() {
|
||||
echo "FAIL: $@" >> /dev/stderr
|
||||
exit 1
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
killall -q -9 udpgso_bench_rx
|
||||
ip link del $veth1 &> /dev/null
|
||||
ip link del $veth2 &> /dev/null
|
||||
ip netns del $ns &> /dev/null
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
function config() {
|
||||
echo "Setup veth pairs [$veth1, $peer1], and veth pair [$veth2, $peer2]"
|
||||
ip link add $veth1 type veth peer name $peer1
|
||||
ip link add $veth2 type veth peer name $peer2
|
||||
ip addr add $ip_peer1/24 dev $peer1
|
||||
ip link set $peer1 up
|
||||
ip netns add $ns
|
||||
ip link set dev $peer2 netns $ns
|
||||
ip netns exec $ns ip addr add $ip_peer2/24 dev $peer2
|
||||
ip netns exec $ns ip link set $peer2 up
|
||||
ip link set $veth1 up
|
||||
ip link set $veth2 up
|
||||
|
||||
echo "Add tc filter ingress->egress forwarding $veth1 <-> $veth2"
|
||||
tc qdisc add dev $veth2 ingress
|
||||
tc qdisc add dev $veth1 ingress
|
||||
tc filter add dev $veth2 ingress prio 1 proto all flower \
|
||||
action mirred egress redirect dev $veth1
|
||||
tc filter add dev $veth1 ingress prio 1 proto all flower \
|
||||
action mirred egress redirect dev $veth2
|
||||
|
||||
echo "Add tc filter egress->ingress forwarding $peer1 -> $veth1, bypassing the veth pipe"
|
||||
tc qdisc add dev $peer1 clsact
|
||||
tc filter add dev $peer1 egress prio 20 proto ip flower \
|
||||
action mirred ingress redirect dev $veth1
|
||||
}
|
||||
|
||||
function test_run() {
|
||||
echo "Run tcp traffic"
|
||||
./udpgso_bench_rx -t &
|
||||
sleep 1
|
||||
ip netns exec $ns timeout -k 2 10 ./udpgso_bench_tx -t -l 2 -4 -D $ip_peer1 || fail "traffic failed"
|
||||
echo "Test passed"
|
||||
}
|
||||
|
||||
config
|
||||
test_run
|
||||
trap - EXIT
|
||||
cleanup
|
Loading…
Reference in New Issue
Block a user