mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-27 21:03:32 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
No conflicts. Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
c248b27cfc
44 changed files with 294 additions and 187 deletions
|
@ -20,6 +20,7 @@ properties:
|
||||||
items:
|
items:
|
||||||
- enum:
|
- enum:
|
||||||
- mediatek,mt7622-wed
|
- mediatek,mt7622-wed
|
||||||
|
- mediatek,mt7981-wed
|
||||||
- mediatek,mt7986-wed
|
- mediatek,mt7986-wed
|
||||||
- const: syscon
|
- const: syscon
|
||||||
|
|
||||||
|
|
|
@ -848,14 +848,21 @@ The kernel interface functions are as follows:
|
||||||
returned. The caller now holds a reference on this and it must be
|
returned. The caller now holds a reference on this and it must be
|
||||||
properly ended.
|
properly ended.
|
||||||
|
|
||||||
(#) End a client call::
|
(#) Shut down a client call::
|
||||||
|
|
||||||
void rxrpc_kernel_end_call(struct socket *sock,
|
void rxrpc_kernel_shutdown_call(struct socket *sock,
|
||||||
|
struct rxrpc_call *call);
|
||||||
|
|
||||||
|
This is used to shut down a previously begun call. The user_call_ID is
|
||||||
|
expunged from AF_RXRPC's knowledge and will not be seen again in
|
||||||
|
association with the specified call.
|
||||||
|
|
||||||
|
(#) Release the ref on a client call::
|
||||||
|
|
||||||
|
void rxrpc_kernel_put_call(struct socket *sock,
|
||||||
struct rxrpc_call *call);
|
struct rxrpc_call *call);
|
||||||
|
|
||||||
This is used to end a previously begun call. The user_call_ID is expunged
|
This is used to release the caller's ref on an rxrpc call.
|
||||||
from AF_RXRPC's knowledge and will not be seen again in association with
|
|
||||||
the specified call.
|
|
||||||
|
|
||||||
(#) Send data through a call::
|
(#) Send data through a call::
|
||||||
|
|
||||||
|
|
|
@ -8706,7 +8706,7 @@ F: drivers/input/touchscreen/goodix*
|
||||||
|
|
||||||
GOOGLE ETHERNET DRIVERS
|
GOOGLE ETHERNET DRIVERS
|
||||||
M: Jeroen de Borst <jeroendb@google.com>
|
M: Jeroen de Borst <jeroendb@google.com>
|
||||||
M: Catherine Sullivan <csully@google.com>
|
M: Praveen Kaligineedi <pkaligineedi@google.com>
|
||||||
R: Shailend Chand <shailend@google.com>
|
R: Shailend Chand <shailend@google.com>
|
||||||
L: netdev@vger.kernel.org
|
L: netdev@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
@ -16817,9 +16817,8 @@ F: include/uapi/linux/if_pppol2tp.h
|
||||||
F: net/l2tp/l2tp_ppp.c
|
F: net/l2tp/l2tp_ppp.c
|
||||||
|
|
||||||
PPP PROTOCOL DRIVERS AND COMPRESSORS
|
PPP PROTOCOL DRIVERS AND COMPRESSORS
|
||||||
M: Paul Mackerras <paulus@samba.org>
|
|
||||||
L: linux-ppp@vger.kernel.org
|
L: linux-ppp@vger.kernel.org
|
||||||
S: Maintained
|
S: Orphan
|
||||||
F: drivers/net/ppp/ppp_*
|
F: drivers/net/ppp/ppp_*
|
||||||
|
|
||||||
PPS SUPPORT
|
PPS SUPPORT
|
||||||
|
|
|
@ -651,7 +651,7 @@ static int nmclan_config(struct pcmcia_device *link)
|
||||||
} else {
|
} else {
|
||||||
pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
|
pr_notice("mace id not found: %x %x should be 0x40 0x?9\n",
|
||||||
sig[0], sig[1]);
|
sig[0], sig[1]);
|
||||||
return -ENODEV;
|
goto failed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -299,7 +299,8 @@ static int dpaa_stop(struct net_device *net_dev)
|
||||||
{
|
{
|
||||||
struct mac_device *mac_dev;
|
struct mac_device *mac_dev;
|
||||||
struct dpaa_priv *priv;
|
struct dpaa_priv *priv;
|
||||||
int i, err, error;
|
int i, error;
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
priv = netdev_priv(net_dev);
|
priv = netdev_priv(net_dev);
|
||||||
mac_dev = priv->mac_dev;
|
mac_dev = priv->mac_dev;
|
||||||
|
|
|
@ -2665,6 +2665,14 @@ static int ixgbe_get_rss_hash_opts(struct ixgbe_adapter *adapter,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
|
||||||
|
{
|
||||||
|
if (adapter->hw.mac.type < ixgbe_mac_X550)
|
||||||
|
return 16;
|
||||||
|
else
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||||
u32 *rule_locs)
|
u32 *rule_locs)
|
||||||
{
|
{
|
||||||
|
@ -2673,7 +2681,8 @@ static int ixgbe_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||||
|
|
||||||
switch (cmd->cmd) {
|
switch (cmd->cmd) {
|
||||||
case ETHTOOL_GRXRINGS:
|
case ETHTOOL_GRXRINGS:
|
||||||
cmd->data = adapter->num_rx_queues;
|
cmd->data = min_t(int, adapter->num_rx_queues,
|
||||||
|
ixgbe_rss_indir_tbl_max(adapter));
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
case ETHTOOL_GRXCLSRLCNT:
|
case ETHTOOL_GRXCLSRLCNT:
|
||||||
|
@ -3075,14 +3084,6 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
|
|
||||||
{
|
|
||||||
if (adapter->hw.mac.type < ixgbe_mac_X550)
|
|
||||||
return 16;
|
|
||||||
else
|
|
||||||
return 64;
|
|
||||||
}
|
|
||||||
|
|
||||||
static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
|
static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
|
||||||
{
|
{
|
||||||
return IXGBE_RSS_KEY_SIZE;
|
return IXGBE_RSS_KEY_SIZE;
|
||||||
|
@ -3131,8 +3132,8 @@ static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
|
||||||
int i;
|
int i;
|
||||||
u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
|
u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
|
||||||
|
|
||||||
if (hfunc)
|
if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
|
||||||
return -EINVAL;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
/* Fill out the redirection table */
|
/* Fill out the redirection table */
|
||||||
if (indir) {
|
if (indir) {
|
||||||
|
|
|
@ -252,8 +252,6 @@ void mtk_wed_hw_add_debugfs(struct mtk_wed_hw *hw)
|
||||||
|
|
||||||
snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index);
|
snprintf(hw->dirname, sizeof(hw->dirname), "wed%d", hw->index);
|
||||||
dir = debugfs_create_dir(hw->dirname, NULL);
|
dir = debugfs_create_dir(hw->dirname, NULL);
|
||||||
if (!dir)
|
|
||||||
return;
|
|
||||||
|
|
||||||
hw->debugfs_dir = dir;
|
hw->debugfs_dir = dir;
|
||||||
debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
|
debugfs_create_u32("regidx", 0600, dir, &hw->debugfs_reg);
|
||||||
|
|
|
@ -326,7 +326,11 @@ mtk_wed_mcu_load_firmware(struct mtk_wed_wo *wo)
|
||||||
wo->hw->index + 1);
|
wo->hw->index + 1);
|
||||||
|
|
||||||
/* load firmware */
|
/* load firmware */
|
||||||
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
|
if (of_device_is_compatible(wo->hw->node, "mediatek,mt7981-wed"))
|
||||||
|
fw_name = MT7981_FIRMWARE_WO;
|
||||||
|
else
|
||||||
|
fw_name = wo->hw->index ? MT7986_FIRMWARE_WO1 : MT7986_FIRMWARE_WO0;
|
||||||
|
|
||||||
ret = request_firmware(&fw, fw_name, wo->hw->dev);
|
ret = request_firmware(&fw, fw_name, wo->hw->dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -386,5 +390,6 @@ int mtk_wed_mcu_init(struct mtk_wed_wo *wo)
|
||||||
100, MTK_FW_DL_TIMEOUT);
|
100, MTK_FW_DL_TIMEOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MODULE_FIRMWARE(MT7981_FIRMWARE_WO);
|
||||||
MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
|
MODULE_FIRMWARE(MT7986_FIRMWARE_WO0);
|
||||||
MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
|
MODULE_FIRMWARE(MT7986_FIRMWARE_WO1);
|
||||||
|
|
|
@ -88,6 +88,7 @@ enum mtk_wed_dummy_cr_idx {
|
||||||
MTK_WED_DUMMY_CR_WO_STATUS,
|
MTK_WED_DUMMY_CR_WO_STATUS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin"
|
||||||
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
|
#define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin"
|
||||||
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
|
#define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin"
|
||||||
|
|
||||||
|
|
|
@ -202,7 +202,7 @@ static int mlx5_devlink_reload_up(struct devlink *devlink, enum devlink_reload_a
|
||||||
break;
|
break;
|
||||||
/* On fw_activate action, also driver is reloaded and reinit performed */
|
/* On fw_activate action, also driver is reloaded and reinit performed */
|
||||||
*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
*actions_performed |= BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT);
|
||||||
ret = mlx5_load_one_devl_locked(dev, false);
|
ret = mlx5_load_one_devl_locked(dev, true);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Unsupported action should not get to this function */
|
/* Unsupported action should not get to this function */
|
||||||
|
|
|
@ -734,5 +734,6 @@ void mlx5e_rep_tc_receive(struct mlx5_cqe64 *cqe, struct mlx5e_rq *rq,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
free_skb:
|
free_skb:
|
||||||
|
dev_put(tc_priv.fwd_dev);
|
||||||
dev_kfree_skb_any(skb);
|
dev_kfree_skb_any(skb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,22 +106,17 @@ mlx5e_tc_post_act_offload(struct mlx5e_post_act *post_act,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mlx5e_post_act_handle *
|
struct mlx5e_post_act_handle *
|
||||||
mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *attr)
|
mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *post_attr)
|
||||||
{
|
{
|
||||||
u32 attr_sz = ns_to_attr_sz(post_act->ns_type);
|
|
||||||
struct mlx5e_post_act_handle *handle;
|
struct mlx5e_post_act_handle *handle;
|
||||||
struct mlx5_flow_attr *post_attr;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||||
post_attr = mlx5_alloc_flow_attr(post_act->ns_type);
|
if (!handle) {
|
||||||
if (!handle || !post_attr) {
|
|
||||||
kfree(post_attr);
|
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(post_attr, attr, attr_sz);
|
|
||||||
post_attr->chain = 0;
|
post_attr->chain = 0;
|
||||||
post_attr->prio = 0;
|
post_attr->prio = 0;
|
||||||
post_attr->ft = post_act->ft;
|
post_attr->ft = post_act->ft;
|
||||||
|
@ -145,7 +140,6 @@ mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *at
|
||||||
return handle;
|
return handle;
|
||||||
|
|
||||||
err_xarray:
|
err_xarray:
|
||||||
kfree(post_attr);
|
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
return ERR_PTR(err);
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
@ -164,7 +158,6 @@ mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_han
|
||||||
if (!IS_ERR_OR_NULL(handle->rule))
|
if (!IS_ERR_OR_NULL(handle->rule))
|
||||||
mlx5e_tc_post_act_unoffload(post_act, handle);
|
mlx5e_tc_post_act_unoffload(post_act, handle);
|
||||||
xa_erase(&post_act->ids, handle->id);
|
xa_erase(&post_act->ids, handle->id);
|
||||||
kfree(handle->attr);
|
|
||||||
kfree(handle);
|
kfree(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ void
|
||||||
mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act);
|
mlx5e_tc_post_act_destroy(struct mlx5e_post_act *post_act);
|
||||||
|
|
||||||
struct mlx5e_post_act_handle *
|
struct mlx5e_post_act_handle *
|
||||||
mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *attr);
|
mlx5e_tc_post_act_add(struct mlx5e_post_act *post_act, struct mlx5_flow_attr *post_attr);
|
||||||
|
|
||||||
void
|
void
|
||||||
mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_handle *handle);
|
mlx5e_tc_post_act_del(struct mlx5e_post_act *post_act, struct mlx5e_post_act_handle *handle);
|
||||||
|
|
|
@ -14,10 +14,10 @@
|
||||||
|
|
||||||
#define MLX5_ESW_VPORT_TBL_SIZE_SAMPLE (64 * 1024)
|
#define MLX5_ESW_VPORT_TBL_SIZE_SAMPLE (64 * 1024)
|
||||||
|
|
||||||
static const struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_sample_ns = {
|
static struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_sample_ns = {
|
||||||
.max_fte = MLX5_ESW_VPORT_TBL_SIZE_SAMPLE,
|
.max_fte = MLX5_ESW_VPORT_TBL_SIZE_SAMPLE,
|
||||||
.max_num_groups = 0, /* default num of groups */
|
.max_num_groups = 0, /* default num of groups */
|
||||||
.flags = MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT | MLX5_FLOW_TABLE_TUNNEL_EN_DECAP,
|
.flags = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5e_tc_psample {
|
struct mlx5e_tc_psample {
|
||||||
|
|
|
@ -908,6 +908,7 @@ mlx5_tc_ct_entry_replace_rule(struct mlx5_tc_ct_priv *ct_priv,
|
||||||
zone_rule->rule = rule;
|
zone_rule->rule = rule;
|
||||||
mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, old_attr, zone_rule->mh);
|
mlx5_tc_ct_entry_destroy_mod_hdr(ct_priv, old_attr, zone_rule->mh);
|
||||||
zone_rule->mh = mh;
|
zone_rule->mh = mh;
|
||||||
|
mlx5_put_label_mapping(ct_priv, old_attr->ct_attr.ct_labels_id);
|
||||||
|
|
||||||
kfree(old_attr);
|
kfree(old_attr);
|
||||||
kvfree(spec);
|
kvfree(spec);
|
||||||
|
|
|
@ -783,6 +783,7 @@ static int mlx5e_create_promisc_table(struct mlx5e_flow_steering *fs)
|
||||||
ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr);
|
ft->t = mlx5_create_auto_grouped_flow_table(fs->ns, &ft_attr);
|
||||||
if (IS_ERR(ft->t)) {
|
if (IS_ERR(ft->t)) {
|
||||||
err = PTR_ERR(ft->t);
|
err = PTR_ERR(ft->t);
|
||||||
|
ft->t = NULL;
|
||||||
fs_err(fs, "fail to create promisc table err=%d\n", err);
|
fs_err(fs, "fail to create promisc table err=%d\n", err);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
@ -810,7 +811,7 @@ static void mlx5e_del_promisc_rule(struct mlx5e_flow_steering *fs)
|
||||||
|
|
||||||
static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs)
|
static void mlx5e_destroy_promisc_table(struct mlx5e_flow_steering *fs)
|
||||||
{
|
{
|
||||||
if (WARN(!fs->promisc.ft.t, "Trying to remove non-existing promiscuous table"))
|
if (!fs->promisc.ft.t)
|
||||||
return;
|
return;
|
||||||
mlx5e_del_promisc_rule(fs);
|
mlx5e_del_promisc_rule(fs);
|
||||||
mlx5_destroy_flow_table(fs->promisc.ft.t);
|
mlx5_destroy_flow_table(fs->promisc.ft.t);
|
||||||
|
@ -1490,6 +1491,8 @@ struct mlx5e_flow_steering *mlx5e_fs_init(const struct mlx5e_profile *profile,
|
||||||
|
|
||||||
void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs)
|
void mlx5e_fs_cleanup(struct mlx5e_flow_steering *fs)
|
||||||
{
|
{
|
||||||
|
if (!fs)
|
||||||
|
return;
|
||||||
debugfs_remove_recursive(fs->dfs_root);
|
debugfs_remove_recursive(fs->dfs_root);
|
||||||
mlx5e_fs_ethtool_free(fs);
|
mlx5e_fs_ethtool_free(fs);
|
||||||
mlx5e_fs_tc_free(fs);
|
mlx5e_fs_tc_free(fs);
|
||||||
|
|
|
@ -5305,6 +5305,7 @@ static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
|
||||||
mlx5e_health_destroy_reporters(priv);
|
mlx5e_health_destroy_reporters(priv);
|
||||||
mlx5e_ktls_cleanup(priv);
|
mlx5e_ktls_cleanup(priv);
|
||||||
mlx5e_fs_cleanup(priv->fs);
|
mlx5e_fs_cleanup(priv->fs);
|
||||||
|
priv->fs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
|
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
|
||||||
|
|
|
@ -829,6 +829,7 @@ static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
|
||||||
static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
|
static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
|
||||||
{
|
{
|
||||||
mlx5e_fs_cleanup(priv->fs);
|
mlx5e_fs_cleanup(priv->fs);
|
||||||
|
priv->fs = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
|
static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
|
||||||
|
@ -995,6 +996,7 @@ static int mlx5e_init_rep_rx(struct mlx5e_priv *priv)
|
||||||
priv->rx_res = NULL;
|
priv->rx_res = NULL;
|
||||||
err_free_fs:
|
err_free_fs:
|
||||||
mlx5e_fs_cleanup(priv->fs);
|
mlx5e_fs_cleanup(priv->fs);
|
||||||
|
priv->fs = NULL;
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ struct mlx5_vport_key {
|
||||||
u16 prio;
|
u16 prio;
|
||||||
u16 vport;
|
u16 vport;
|
||||||
u16 vhca_id;
|
u16 vhca_id;
|
||||||
const struct esw_vport_tbl_namespace *vport_ns;
|
struct esw_vport_tbl_namespace *vport_ns;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
struct mlx5_vport_table {
|
struct mlx5_vport_table {
|
||||||
|
@ -21,6 +21,14 @@ struct mlx5_vport_table {
|
||||||
struct mlx5_vport_key key;
|
struct mlx5_vport_key key;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
esw_vport_tbl_init(struct mlx5_eswitch *esw, struct esw_vport_tbl_namespace *ns)
|
||||||
|
{
|
||||||
|
if (esw->offloads.encap != DEVLINK_ESWITCH_ENCAP_MODE_NONE)
|
||||||
|
ns->flags |= (MLX5_FLOW_TABLE_TUNNEL_EN_REFORMAT |
|
||||||
|
MLX5_FLOW_TABLE_TUNNEL_EN_DECAP);
|
||||||
|
}
|
||||||
|
|
||||||
static struct mlx5_flow_table *
|
static struct mlx5_flow_table *
|
||||||
esw_vport_tbl_create(struct mlx5_eswitch *esw, struct mlx5_flow_namespace *ns,
|
esw_vport_tbl_create(struct mlx5_eswitch *esw, struct mlx5_flow_namespace *ns,
|
||||||
const struct esw_vport_tbl_namespace *vport_ns)
|
const struct esw_vport_tbl_namespace *vport_ns)
|
||||||
|
@ -80,6 +88,7 @@ mlx5_esw_vporttbl_get(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr
|
||||||
u32 hkey;
|
u32 hkey;
|
||||||
|
|
||||||
mutex_lock(&esw->fdb_table.offloads.vports.lock);
|
mutex_lock(&esw->fdb_table.offloads.vports.lock);
|
||||||
|
esw_vport_tbl_init(esw, attr->vport_ns);
|
||||||
hkey = flow_attr_to_vport_key(esw, attr, &skey);
|
hkey = flow_attr_to_vport_key(esw, attr, &skey);
|
||||||
e = esw_vport_tbl_lookup(esw, &skey, hkey);
|
e = esw_vport_tbl_lookup(esw, &skey, hkey);
|
||||||
if (e) {
|
if (e) {
|
||||||
|
@ -127,6 +136,7 @@ mlx5_esw_vporttbl_put(struct mlx5_eswitch *esw, struct mlx5_vport_tbl_attr *attr
|
||||||
u32 hkey;
|
u32 hkey;
|
||||||
|
|
||||||
mutex_lock(&esw->fdb_table.offloads.vports.lock);
|
mutex_lock(&esw->fdb_table.offloads.vports.lock);
|
||||||
|
esw_vport_tbl_init(esw, attr->vport_ns);
|
||||||
hkey = flow_attr_to_vport_key(esw, attr, &key);
|
hkey = flow_attr_to_vport_key(esw, attr, &key);
|
||||||
e = esw_vport_tbl_lookup(esw, &key, hkey);
|
e = esw_vport_tbl_lookup(esw, &key, hkey);
|
||||||
if (!e || --e->num_rules)
|
if (!e || --e->num_rules)
|
||||||
|
|
|
@ -672,7 +672,7 @@ struct mlx5_vport_tbl_attr {
|
||||||
u32 chain;
|
u32 chain;
|
||||||
u16 prio;
|
u16 prio;
|
||||||
u16 vport;
|
u16 vport;
|
||||||
const struct esw_vport_tbl_namespace *vport_ns;
|
struct esw_vport_tbl_namespace *vport_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mlx5_flow_table *
|
struct mlx5_flow_table *
|
||||||
|
|
|
@ -73,7 +73,7 @@
|
||||||
|
|
||||||
#define MLX5_ESW_FT_OFFLOADS_DROP_RULE (1)
|
#define MLX5_ESW_FT_OFFLOADS_DROP_RULE (1)
|
||||||
|
|
||||||
static const struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_mirror_ns = {
|
static struct esw_vport_tbl_namespace mlx5_esw_vport_tbl_mirror_ns = {
|
||||||
.max_fte = MLX5_ESW_VPORT_TBL_SIZE,
|
.max_fte = MLX5_ESW_VPORT_TBL_SIZE,
|
||||||
.max_num_groups = MLX5_ESW_VPORT_TBL_NUM_GROUPS,
|
.max_num_groups = MLX5_ESW_VPORT_TBL_NUM_GROUPS,
|
||||||
.flags = 0,
|
.flags = 0,
|
||||||
|
@ -760,7 +760,6 @@ mlx5_eswitch_add_fwd_rule(struct mlx5_eswitch *esw,
|
||||||
kfree(dest);
|
kfree(dest);
|
||||||
return rule;
|
return rule;
|
||||||
err_chain_src_rewrite:
|
err_chain_src_rewrite:
|
||||||
esw_put_dest_tables_loop(esw, attr, 0, i);
|
|
||||||
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
||||||
err_get_fwd:
|
err_get_fwd:
|
||||||
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
|
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
|
||||||
|
@ -803,7 +802,6 @@ __mlx5_eswitch_del_rule(struct mlx5_eswitch *esw,
|
||||||
if (fwd_rule) {
|
if (fwd_rule) {
|
||||||
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
||||||
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
|
mlx5_chains_put_table(chains, attr->chain, attr->prio, 0);
|
||||||
esw_put_dest_tables_loop(esw, attr, 0, esw_attr->split_count);
|
|
||||||
} else {
|
} else {
|
||||||
if (split)
|
if (split)
|
||||||
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
mlx5_esw_vporttbl_put(esw, &fwd_attr);
|
||||||
|
|
|
@ -210,18 +210,6 @@ static bool mlx5_eswitch_offload_is_uplink_port(const struct mlx5_eswitch *esw,
|
||||||
return (port_mask & port_value) == MLX5_VPORT_UPLINK;
|
return (port_mask & port_value) == MLX5_VPORT_UPLINK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
mlx5_eswitch_is_push_vlan_no_cap(struct mlx5_eswitch *esw,
|
|
||||||
struct mlx5_flow_act *flow_act)
|
|
||||||
{
|
|
||||||
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
|
|
||||||
!(mlx5_fs_get_capabilities(esw->dev, MLX5_FLOW_NAMESPACE_FDB) &
|
|
||||||
MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
|
mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
|
||||||
struct mlx5_flow_attr *attr,
|
struct mlx5_flow_attr *attr,
|
||||||
|
@ -237,7 +225,10 @@ mlx5_eswitch_termtbl_required(struct mlx5_eswitch *esw,
|
||||||
(!mlx5_eswitch_offload_is_uplink_port(esw, spec) && !esw_attr->int_port))
|
(!mlx5_eswitch_offload_is_uplink_port(esw, spec) && !esw_attr->int_port))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (mlx5_eswitch_is_push_vlan_no_cap(esw, flow_act))
|
/* push vlan on RX */
|
||||||
|
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH &&
|
||||||
|
!(mlx5_fs_get_capabilities(esw->dev, MLX5_FLOW_NAMESPACE_FDB) &
|
||||||
|
MLX5_FLOW_STEERING_CAP_VLAN_PUSH_ON_RX))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* hairpin */
|
/* hairpin */
|
||||||
|
@ -261,31 +252,19 @@ mlx5_eswitch_add_termtbl_rule(struct mlx5_eswitch *esw,
|
||||||
struct mlx5_flow_act term_tbl_act = {};
|
struct mlx5_flow_act term_tbl_act = {};
|
||||||
struct mlx5_flow_handle *rule = NULL;
|
struct mlx5_flow_handle *rule = NULL;
|
||||||
bool term_table_created = false;
|
bool term_table_created = false;
|
||||||
bool is_push_vlan_on_rx;
|
|
||||||
int num_vport_dests = 0;
|
int num_vport_dests = 0;
|
||||||
int i, curr_dest;
|
int i, curr_dest;
|
||||||
|
|
||||||
is_push_vlan_on_rx = mlx5_eswitch_is_push_vlan_no_cap(esw, flow_act);
|
|
||||||
mlx5_eswitch_termtbl_actions_move(flow_act, &term_tbl_act);
|
mlx5_eswitch_termtbl_actions_move(flow_act, &term_tbl_act);
|
||||||
term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
|
||||||
|
|
||||||
for (i = 0; i < num_dest; i++) {
|
for (i = 0; i < num_dest; i++) {
|
||||||
struct mlx5_termtbl_handle *tt;
|
struct mlx5_termtbl_handle *tt;
|
||||||
bool hairpin = false;
|
|
||||||
|
|
||||||
/* only vport destinations can be terminated */
|
/* only vport destinations can be terminated */
|
||||||
if (dest[i].type != MLX5_FLOW_DESTINATION_TYPE_VPORT)
|
if (dest[i].type != MLX5_FLOW_DESTINATION_TYPE_VPORT)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (attr->dests[num_vport_dests].rep &&
|
|
||||||
attr->dests[num_vport_dests].rep->vport == MLX5_VPORT_UPLINK)
|
|
||||||
hairpin = true;
|
|
||||||
|
|
||||||
if (!is_push_vlan_on_rx && !hairpin) {
|
|
||||||
num_vport_dests++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (attr->dests[num_vport_dests].flags & MLX5_ESW_DEST_ENCAP) {
|
if (attr->dests[num_vport_dests].flags & MLX5_ESW_DEST_ENCAP) {
|
||||||
term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
term_tbl_act.action |= MLX5_FLOW_CONTEXT_ACTION_PACKET_REFORMAT;
|
||||||
term_tbl_act.pkt_reformat = attr->dests[num_vport_dests].pkt_reformat;
|
term_tbl_act.pkt_reformat = attr->dests[num_vport_dests].pkt_reformat;
|
||||||
|
@ -333,9 +312,6 @@ mlx5_eswitch_add_termtbl_rule(struct mlx5_eswitch *esw,
|
||||||
for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) {
|
for (curr_dest = 0; curr_dest < num_vport_dests; curr_dest++) {
|
||||||
struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl;
|
struct mlx5_termtbl_handle *tt = attr->dests[curr_dest].termtbl;
|
||||||
|
|
||||||
if (!tt)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
attr->dests[curr_dest].termtbl = NULL;
|
attr->dests[curr_dest].termtbl = NULL;
|
||||||
|
|
||||||
/* search for the destination associated with the
|
/* search for the destination associated with the
|
||||||
|
|
|
@ -167,7 +167,7 @@ static void mlx5_fw_reset_complete_reload(struct mlx5_core_dev *dev)
|
||||||
if (mlx5_health_wait_pci_up(dev))
|
if (mlx5_health_wait_pci_up(dev))
|
||||||
mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
|
mlx5_core_err(dev, "reset reload flow aborted, PCI reads still not working\n");
|
||||||
else
|
else
|
||||||
mlx5_load_one(dev);
|
mlx5_load_one(dev, true);
|
||||||
devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
|
devlink_remote_reload_actions_performed(priv_to_devlink(dev), 0,
|
||||||
BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
|
BIT(DEVLINK_RELOAD_ACTION_DRIVER_REINIT) |
|
||||||
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
|
BIT(DEVLINK_RELOAD_ACTION_FW_ACTIVATE));
|
||||||
|
@ -499,7 +499,7 @@ int mlx5_fw_reset_wait_reset_done(struct mlx5_core_dev *dev)
|
||||||
err = fw_reset->ret;
|
err = fw_reset->ret;
|
||||||
if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
|
if (test_and_clear_bit(MLX5_FW_RESET_FLAGS_RELOAD_REQUIRED, &fw_reset->reset_flags)) {
|
||||||
mlx5_unload_one_devl_locked(dev, false);
|
mlx5_unload_one_devl_locked(dev, false);
|
||||||
mlx5_load_one_devl_locked(dev, false);
|
mlx5_load_one_devl_locked(dev, true);
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
|
clear_bit(MLX5_FW_RESET_FLAGS_PENDING_COMP, &fw_reset->reset_flags);
|
||||||
|
|
|
@ -1514,13 +1514,13 @@ int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mlx5_load_one(struct mlx5_core_dev *dev)
|
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery)
|
||||||
{
|
{
|
||||||
struct devlink *devlink = priv_to_devlink(dev);
|
struct devlink *devlink = priv_to_devlink(dev);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
devl_lock(devlink);
|
devl_lock(devlink);
|
||||||
ret = mlx5_load_one_devl_locked(dev, false);
|
ret = mlx5_load_one_devl_locked(dev, recovery);
|
||||||
devl_unlock(devlink);
|
devl_unlock(devlink);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -1922,7 +1922,8 @@ static void mlx5_pci_resume(struct pci_dev *pdev)
|
||||||
|
|
||||||
mlx5_pci_trace(dev, "Enter, loading driver..\n");
|
mlx5_pci_trace(dev, "Enter, loading driver..\n");
|
||||||
|
|
||||||
err = mlx5_load_one(dev);
|
err = mlx5_load_one(dev, false);
|
||||||
|
|
||||||
if (!err)
|
if (!err)
|
||||||
devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
|
devlink_health_reporter_state_update(dev->priv.health.fw_fatal_reporter,
|
||||||
DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
|
DEVLINK_HEALTH_REPORTER_STATE_HEALTHY);
|
||||||
|
@ -2013,7 +2014,7 @@ static int mlx5_resume(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
struct mlx5_core_dev *dev = pci_get_drvdata(pdev);
|
||||||
|
|
||||||
return mlx5_load_one(dev);
|
return mlx5_load_one(dev, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct pci_device_id mlx5_core_pci_table[] = {
|
static const struct pci_device_id mlx5_core_pci_table[] = {
|
||||||
|
|
|
@ -322,7 +322,7 @@ int mlx5_init_one(struct mlx5_core_dev *dev);
|
||||||
void mlx5_uninit_one(struct mlx5_core_dev *dev);
|
void mlx5_uninit_one(struct mlx5_core_dev *dev);
|
||||||
void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend);
|
void mlx5_unload_one(struct mlx5_core_dev *dev, bool suspend);
|
||||||
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend);
|
void mlx5_unload_one_devl_locked(struct mlx5_core_dev *dev, bool suspend);
|
||||||
int mlx5_load_one(struct mlx5_core_dev *dev);
|
int mlx5_load_one(struct mlx5_core_dev *dev, bool recovery);
|
||||||
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery);
|
int mlx5_load_one_devl_locked(struct mlx5_core_dev *dev, bool recovery);
|
||||||
|
|
||||||
int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap, u16 function_id,
|
int mlx5_vport_set_other_func_cap(struct mlx5_core_dev *dev, const void *hca_cap, u16 function_id,
|
||||||
|
|
|
@ -269,7 +269,7 @@ static void set_sha2_512hmac(struct nfp_ipsec_cfg_add_sa *cfg, int *trunc_len)
|
||||||
static int nfp_net_xfrm_add_state(struct xfrm_state *x,
|
static int nfp_net_xfrm_add_state(struct xfrm_state *x,
|
||||||
struct netlink_ext_ack *extack)
|
struct netlink_ext_ack *extack)
|
||||||
{
|
{
|
||||||
struct net_device *netdev = x->xso.dev;
|
struct net_device *netdev = x->xso.real_dev;
|
||||||
struct nfp_ipsec_cfg_mssg msg = {};
|
struct nfp_ipsec_cfg_mssg msg = {};
|
||||||
int i, key_len, trunc_len, err = 0;
|
int i, key_len, trunc_len, err = 0;
|
||||||
struct nfp_ipsec_cfg_add_sa *cfg;
|
struct nfp_ipsec_cfg_add_sa *cfg;
|
||||||
|
@ -513,7 +513,7 @@ static void nfp_net_xfrm_del_state(struct xfrm_state *x)
|
||||||
.cmd = NFP_IPSEC_CFG_MSSG_INV_SA,
|
.cmd = NFP_IPSEC_CFG_MSSG_INV_SA,
|
||||||
.sa_idx = x->xso.offload_handle - 1,
|
.sa_idx = x->xso.offload_handle - 1,
|
||||||
};
|
};
|
||||||
struct net_device *netdev = x->xso.dev;
|
struct net_device *netdev = x->xso.real_dev;
|
||||||
struct nfp_net *nn;
|
struct nfp_net *nn;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,8 @@ void afs_put_call(struct afs_call *call)
|
||||||
ASSERT(call->type->name != NULL);
|
ASSERT(call->type->name != NULL);
|
||||||
|
|
||||||
if (call->rxcall) {
|
if (call->rxcall) {
|
||||||
rxrpc_kernel_end_call(net->socket, call->rxcall);
|
rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
|
||||||
|
rxrpc_kernel_put_call(net->socket, call->rxcall);
|
||||||
call->rxcall = NULL;
|
call->rxcall = NULL;
|
||||||
}
|
}
|
||||||
if (call->type->destructor)
|
if (call->type->destructor)
|
||||||
|
@ -420,10 +421,8 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
|
||||||
* The call, however, might be queued on afs_async_calls and we need to
|
* The call, however, might be queued on afs_async_calls and we need to
|
||||||
* make sure we don't get any more notifications that might requeue it.
|
* make sure we don't get any more notifications that might requeue it.
|
||||||
*/
|
*/
|
||||||
if (call->rxcall) {
|
if (call->rxcall)
|
||||||
rxrpc_kernel_end_call(call->net->socket, call->rxcall);
|
rxrpc_kernel_shutdown_call(call->net->socket, call->rxcall);
|
||||||
call->rxcall = NULL;
|
|
||||||
}
|
|
||||||
if (call->async) {
|
if (call->async) {
|
||||||
if (cancel_work_sync(&call->async_work))
|
if (cancel_work_sync(&call->async_work))
|
||||||
afs_put_call(call);
|
afs_put_call(call);
|
||||||
|
|
|
@ -57,7 +57,8 @@ int rxrpc_kernel_recv_data(struct socket *, struct rxrpc_call *,
|
||||||
struct iov_iter *, size_t *, bool, u32 *, u16 *);
|
struct iov_iter *, size_t *, bool, u32 *, u16 *);
|
||||||
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
|
bool rxrpc_kernel_abort_call(struct socket *, struct rxrpc_call *,
|
||||||
u32, int, enum rxrpc_abort_reason);
|
u32, int, enum rxrpc_abort_reason);
|
||||||
void rxrpc_kernel_end_call(struct socket *, struct rxrpc_call *);
|
void rxrpc_kernel_shutdown_call(struct socket *sock, struct rxrpc_call *call);
|
||||||
|
void rxrpc_kernel_put_call(struct socket *sock, struct rxrpc_call *call);
|
||||||
void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
|
void rxrpc_kernel_get_peer(struct socket *, struct rxrpc_call *,
|
||||||
struct sockaddr_rxrpc *);
|
struct sockaddr_rxrpc *);
|
||||||
bool rxrpc_kernel_get_srtt(struct socket *, struct rxrpc_call *, u32 *);
|
bool rxrpc_kernel_get_srtt(struct socket *, struct rxrpc_call *, u32 *);
|
||||||
|
|
|
@ -89,7 +89,11 @@ static inline void __nf_ct_set_timeout(struct nf_conn *ct, u64 timeout)
|
||||||
{
|
{
|
||||||
if (timeout > INT_MAX)
|
if (timeout > INT_MAX)
|
||||||
timeout = INT_MAX;
|
timeout = INT_MAX;
|
||||||
WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
|
|
||||||
|
if (nf_ct_is_confirmed(ct))
|
||||||
|
WRITE_ONCE(ct->timeout, nfct_time_stamp + (u32)timeout);
|
||||||
|
else
|
||||||
|
ct->timeout = (u32)timeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
int __nf_ct_change_timeout(struct nf_conn *ct, u64 cta_timeout);
|
int __nf_ct_change_timeout(struct nf_conn *ct, u64 cta_timeout);
|
||||||
|
|
|
@ -5215,6 +5215,9 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb,
|
||||||
skb = alloc_skb(0, GFP_ATOMIC);
|
skb = alloc_skb(0, GFP_ATOMIC);
|
||||||
} else {
|
} else {
|
||||||
skb = skb_clone(orig_skb, GFP_ATOMIC);
|
skb = skb_clone(orig_skb, GFP_ATOMIC);
|
||||||
|
|
||||||
|
if (skb_orphan_frags_rx(skb, GFP_ATOMIC))
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (!skb)
|
if (!skb)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1571,9 +1571,19 @@ struct sk_buff *__ip_make_skb(struct sock *sk,
|
||||||
cork->dst = NULL;
|
cork->dst = NULL;
|
||||||
skb_dst_set(skb, &rt->dst);
|
skb_dst_set(skb, &rt->dst);
|
||||||
|
|
||||||
if (iph->protocol == IPPROTO_ICMP)
|
if (iph->protocol == IPPROTO_ICMP) {
|
||||||
icmp_out_count(net, ((struct icmphdr *)
|
u8 icmp_type;
|
||||||
skb_transport_header(skb))->type);
|
|
||||||
|
/* For such sockets, transhdrlen is zero when do ip_append_data(),
|
||||||
|
* so icmphdr does not in skb linear region and can not get icmp_type
|
||||||
|
* by icmp_hdr(skb)->type.
|
||||||
|
*/
|
||||||
|
if (sk->sk_type == SOCK_RAW && !inet_sk(sk)->hdrincl)
|
||||||
|
icmp_type = fl4->fl4_icmp_type;
|
||||||
|
else
|
||||||
|
icmp_type = icmp_hdr(skb)->type;
|
||||||
|
icmp_out_count(net, icmp_type);
|
||||||
|
}
|
||||||
|
|
||||||
ip_cork_release(cork);
|
ip_cork_release(cork);
|
||||||
out:
|
out:
|
||||||
|
|
|
@ -380,6 +380,7 @@ __bpf_kfunc struct nf_conn *bpf_ct_insert_entry(struct nf_conn___init *nfct_i)
|
||||||
struct nf_conn *nfct = (struct nf_conn *)nfct_i;
|
struct nf_conn *nfct = (struct nf_conn *)nfct_i;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
nfct->status |= IPS_CONFIRMED;
|
||||||
err = nf_conntrack_hash_check_insert(nfct);
|
err = nf_conntrack_hash_check_insert(nfct);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
nf_conntrack_free(nfct);
|
nf_conntrack_free(nfct);
|
||||||
|
|
|
@ -932,7 +932,6 @@ nf_conntrack_hash_check_insert(struct nf_conn *ct)
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
ct->status |= IPS_CONFIRMED;
|
|
||||||
smp_wmb();
|
smp_wmb();
|
||||||
/* The caller holds a reference to this object */
|
/* The caller holds a reference to this object */
|
||||||
refcount_set(&ct->ct_general.use, 2);
|
refcount_set(&ct->ct_general.use, 2);
|
||||||
|
|
|
@ -176,7 +176,12 @@ static int ctnetlink_dump_status(struct sk_buff *skb, const struct nf_conn *ct)
|
||||||
static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct,
|
static int ctnetlink_dump_timeout(struct sk_buff *skb, const struct nf_conn *ct,
|
||||||
bool skip_zero)
|
bool skip_zero)
|
||||||
{
|
{
|
||||||
long timeout = nf_ct_expires(ct) / HZ;
|
long timeout;
|
||||||
|
|
||||||
|
if (nf_ct_is_confirmed(ct))
|
||||||
|
timeout = nf_ct_expires(ct) / HZ;
|
||||||
|
else
|
||||||
|
timeout = ct->timeout / HZ;
|
||||||
|
|
||||||
if (skip_zero && timeout == 0)
|
if (skip_zero && timeout == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -2245,9 +2250,6 @@ ctnetlink_create_conntrack(struct net *net,
|
||||||
if (!cda[CTA_TIMEOUT])
|
if (!cda[CTA_TIMEOUT])
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
|
|
||||||
__nf_ct_set_timeout(ct, timeout);
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
if (cda[CTA_HELP]) {
|
if (cda[CTA_HELP]) {
|
||||||
char *helpname = NULL;
|
char *helpname = NULL;
|
||||||
|
@ -2308,6 +2310,12 @@ ctnetlink_create_conntrack(struct net *net,
|
||||||
nfct_seqadj_ext_add(ct);
|
nfct_seqadj_ext_add(ct);
|
||||||
nfct_synproxy_ext_add(ct);
|
nfct_synproxy_ext_add(ct);
|
||||||
|
|
||||||
|
/* we must add conntrack extensions before confirmation. */
|
||||||
|
ct->status |= IPS_CONFIRMED;
|
||||||
|
|
||||||
|
timeout = (u64)ntohl(nla_get_be32(cda[CTA_TIMEOUT])) * HZ;
|
||||||
|
__nf_ct_set_timeout(ct, timeout);
|
||||||
|
|
||||||
if (cda[CTA_STATUS]) {
|
if (cda[CTA_STATUS]) {
|
||||||
err = ctnetlink_change_status(ct, cda);
|
err = ctnetlink_change_status(ct, cda);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -1742,7 +1742,8 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
|
||||||
{
|
{
|
||||||
struct sock *sk = sock->sk;
|
struct sock *sk = sock->sk;
|
||||||
struct netlink_sock *nlk = nlk_sk(sk);
|
struct netlink_sock *nlk = nlk_sk(sk);
|
||||||
int len, val, err;
|
unsigned int flag;
|
||||||
|
int len, val;
|
||||||
|
|
||||||
if (level != SOL_NETLINK)
|
if (level != SOL_NETLINK)
|
||||||
return -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
|
@ -1754,39 +1755,17 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
|
||||||
|
|
||||||
switch (optname) {
|
switch (optname) {
|
||||||
case NETLINK_PKTINFO:
|
case NETLINK_PKTINFO:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_RECV_PKTINFO;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_RECV_PKTINFO ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) ||
|
|
||||||
put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
case NETLINK_BROADCAST_ERROR:
|
case NETLINK_BROADCAST_ERROR:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_BROADCAST_SEND_ERROR;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_BROADCAST_SEND_ERROR ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) ||
|
|
||||||
put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
case NETLINK_NO_ENOBUFS:
|
case NETLINK_NO_ENOBUFS:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_RECV_NO_ENOBUFS;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_RECV_NO_ENOBUFS ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) ||
|
|
||||||
put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
case NETLINK_LIST_MEMBERSHIPS: {
|
case NETLINK_LIST_MEMBERSHIPS: {
|
||||||
int pos, idx, shift;
|
int pos, idx, shift, err = 0;
|
||||||
|
|
||||||
err = 0;
|
|
||||||
netlink_lock_table();
|
netlink_lock_table();
|
||||||
for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
|
for (pos = 0; pos * 8 < nlk->ngroups; pos += sizeof(u32)) {
|
||||||
if (len - pos < sizeof(u32))
|
if (len - pos < sizeof(u32))
|
||||||
|
@ -1803,40 +1782,32 @@ static int netlink_getsockopt(struct socket *sock, int level, int optname,
|
||||||
if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
|
if (put_user(ALIGN(nlk->ngroups / 8, sizeof(u32)), optlen))
|
||||||
err = -EFAULT;
|
err = -EFAULT;
|
||||||
netlink_unlock_table();
|
netlink_unlock_table();
|
||||||
break;
|
return err;
|
||||||
}
|
}
|
||||||
case NETLINK_CAP_ACK:
|
case NETLINK_CAP_ACK:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_CAP_ACK;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_CAP_ACK ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) ||
|
|
||||||
put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
case NETLINK_EXT_ACK:
|
case NETLINK_EXT_ACK:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_EXT_ACK;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_EXT_ACK ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) || put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
case NETLINK_GET_STRICT_CHK:
|
case NETLINK_GET_STRICT_CHK:
|
||||||
if (len < sizeof(int))
|
flag = NETLINK_F_STRICT_CHK;
|
||||||
return -EINVAL;
|
|
||||||
len = sizeof(int);
|
|
||||||
val = nlk->flags & NETLINK_F_STRICT_CHK ? 1 : 0;
|
|
||||||
if (put_user(len, optlen) || put_user(val, optval))
|
|
||||||
return -EFAULT;
|
|
||||||
err = 0;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = -ENOPROTOOPT;
|
return -ENOPROTOOPT;
|
||||||
}
|
}
|
||||||
return err;
|
|
||||||
|
if (len < sizeof(int))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
len = sizeof(int);
|
||||||
|
val = nlk->flags & flag ? 1 : 0;
|
||||||
|
|
||||||
|
if (put_user(len, optlen) ||
|
||||||
|
copy_to_user(optval, &val, len))
|
||||||
|
return -EFAULT;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
|
static void netlink_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
|
||||||
|
|
|
@ -342,31 +342,44 @@ static void rxrpc_dummy_notify_rx(struct sock *sk, struct rxrpc_call *rxcall,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rxrpc_kernel_end_call - Allow a kernel service to end a call it was using
|
* rxrpc_kernel_shutdown_call - Allow a kernel service to shut down a call it was using
|
||||||
* @sock: The socket the call is on
|
* @sock: The socket the call is on
|
||||||
* @call: The call to end
|
* @call: The call to end
|
||||||
*
|
*
|
||||||
* Allow a kernel service to end a call it was using. The call must be
|
* Allow a kernel service to shut down a call it was using. The call must be
|
||||||
* complete before this is called (the call should be aborted if necessary).
|
* complete before this is called (the call should be aborted if necessary).
|
||||||
*/
|
*/
|
||||||
void rxrpc_kernel_end_call(struct socket *sock, struct rxrpc_call *call)
|
void rxrpc_kernel_shutdown_call(struct socket *sock, struct rxrpc_call *call)
|
||||||
{
|
{
|
||||||
_enter("%d{%d}", call->debug_id, refcount_read(&call->ref));
|
_enter("%d{%d}", call->debug_id, refcount_read(&call->ref));
|
||||||
|
|
||||||
mutex_lock(&call->user_mutex);
|
mutex_lock(&call->user_mutex);
|
||||||
rxrpc_release_call(rxrpc_sk(sock->sk), call);
|
if (!test_bit(RXRPC_CALL_RELEASED, &call->flags)) {
|
||||||
|
rxrpc_release_call(rxrpc_sk(sock->sk), call);
|
||||||
|
|
||||||
/* Make sure we're not going to call back into a kernel service */
|
/* Make sure we're not going to call back into a kernel service */
|
||||||
if (call->notify_rx) {
|
if (call->notify_rx) {
|
||||||
spin_lock(&call->notify_lock);
|
spin_lock(&call->notify_lock);
|
||||||
call->notify_rx = rxrpc_dummy_notify_rx;
|
call->notify_rx = rxrpc_dummy_notify_rx;
|
||||||
spin_unlock(&call->notify_lock);
|
spin_unlock(&call->notify_lock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_unlock(&call->user_mutex);
|
mutex_unlock(&call->user_mutex);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(rxrpc_kernel_shutdown_call);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rxrpc_kernel_put_call - Release a reference to a call
|
||||||
|
* @sock: The socket the call is on
|
||||||
|
* @call: The call to put
|
||||||
|
*
|
||||||
|
* Drop the application's ref on an rxrpc call.
|
||||||
|
*/
|
||||||
|
void rxrpc_kernel_put_call(struct socket *sock, struct rxrpc_call *call)
|
||||||
|
{
|
||||||
rxrpc_put_call(call, rxrpc_call_put_kernel);
|
rxrpc_put_call(call, rxrpc_call_put_kernel);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rxrpc_kernel_end_call);
|
EXPORT_SYMBOL(rxrpc_kernel_put_call);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* rxrpc_kernel_check_life - Check to see whether a call is still alive
|
* rxrpc_kernel_check_life - Check to see whether a call is still alive
|
||||||
|
|
|
@ -680,7 +680,7 @@ static long rxrpc_read(const struct key *key,
|
||||||
return -ENOPKG;
|
return -ENOPKG;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr ==
|
if (WARN_ON((unsigned long)xdr - (unsigned long)oldxdr !=
|
||||||
toksize))
|
toksize))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
|
@ -342,7 +342,8 @@ static void rxperf_deliver_to_call(struct work_struct *work)
|
||||||
call_complete:
|
call_complete:
|
||||||
rxperf_set_call_complete(call, ret, remote_abort);
|
rxperf_set_call_complete(call, ret, remote_abort);
|
||||||
/* The call may have been requeued */
|
/* The call may have been requeued */
|
||||||
rxrpc_kernel_end_call(rxperf_socket, call->rxcall);
|
rxrpc_kernel_shutdown_call(rxperf_socket, call->rxcall);
|
||||||
|
rxrpc_kernel_put_call(rxperf_socket, call->rxcall);
|
||||||
cancel_work(&call->work);
|
cancel_work(&call->work);
|
||||||
kfree(call);
|
kfree(call);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3211,6 +3211,7 @@ int tcf_exts_init_ex(struct tcf_exts *exts, struct net *net, int action,
|
||||||
#ifdef CONFIG_NET_CLS_ACT
|
#ifdef CONFIG_NET_CLS_ACT
|
||||||
exts->type = 0;
|
exts->type = 0;
|
||||||
exts->nr_actions = 0;
|
exts->nr_actions = 0;
|
||||||
|
exts->miss_cookie_node = NULL;
|
||||||
/* Note: we do not own yet a reference on net.
|
/* Note: we do not own yet a reference on net.
|
||||||
* This reference might be taken later from tcf_exts_get_net().
|
* This reference might be taken later from tcf_exts_get_net().
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -779,13 +779,17 @@ static int fq_resize(struct Qdisc *sch, u32 log)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct netlink_range_validation iq_range = {
|
||||||
|
.max = INT_MAX,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
|
static const struct nla_policy fq_policy[TCA_FQ_MAX + 1] = {
|
||||||
[TCA_FQ_UNSPEC] = { .strict_start_type = TCA_FQ_TIMER_SLACK },
|
[TCA_FQ_UNSPEC] = { .strict_start_type = TCA_FQ_TIMER_SLACK },
|
||||||
|
|
||||||
[TCA_FQ_PLIMIT] = { .type = NLA_U32 },
|
[TCA_FQ_PLIMIT] = { .type = NLA_U32 },
|
||||||
[TCA_FQ_FLOW_PLIMIT] = { .type = NLA_U32 },
|
[TCA_FQ_FLOW_PLIMIT] = { .type = NLA_U32 },
|
||||||
[TCA_FQ_QUANTUM] = { .type = NLA_U32 },
|
[TCA_FQ_QUANTUM] = { .type = NLA_U32 },
|
||||||
[TCA_FQ_INITIAL_QUANTUM] = { .type = NLA_U32 },
|
[TCA_FQ_INITIAL_QUANTUM] = NLA_POLICY_FULL_RANGE(NLA_U32, &iq_range),
|
||||||
[TCA_FQ_RATE_ENABLE] = { .type = NLA_U32 },
|
[TCA_FQ_RATE_ENABLE] = { .type = NLA_U32 },
|
||||||
[TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 },
|
[TCA_FQ_FLOW_DEFAULT_RATE] = { .type = NLA_U32 },
|
||||||
[TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
|
[TCA_FQ_FLOW_MAX_RATE] = { .type = NLA_U32 },
|
||||||
|
|
|
@ -1786,7 +1786,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
err = nla_parse_nested_deprecated(tb, TCA_HTB_MAX, opt, htb_policy,
|
err = nla_parse_nested_deprecated(tb, TCA_HTB_MAX, opt, htb_policy,
|
||||||
NULL);
|
extack);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto failure;
|
goto failure;
|
||||||
|
|
||||||
|
@ -1858,7 +1858,7 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
|
|
||||||
/* check maximal depth */
|
/* check maximal depth */
|
||||||
if (parent && parent->parent && parent->parent->level < 2) {
|
if (parent && parent->parent && parent->parent->level < 2) {
|
||||||
pr_err("htb: tree is too deep\n");
|
NL_SET_ERR_MSG_MOD(extack, "tree is too deep");
|
||||||
goto failure;
|
goto failure;
|
||||||
}
|
}
|
||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
|
@ -1917,8 +1917,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
};
|
};
|
||||||
err = htb_offload(dev, &offload_opt);
|
err = htb_offload(dev, &offload_opt);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("htb: TC_HTB_LEAF_ALLOC_QUEUE failed with err = %d\n",
|
NL_SET_ERR_MSG_WEAK(extack,
|
||||||
err);
|
"Failed to offload TC_HTB_LEAF_ALLOC_QUEUE");
|
||||||
goto err_kill_estimator;
|
goto err_kill_estimator;
|
||||||
}
|
}
|
||||||
dev_queue = netdev_get_tx_queue(dev, offload_opt.qid);
|
dev_queue = netdev_get_tx_queue(dev, offload_opt.qid);
|
||||||
|
@ -1937,8 +1937,8 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
};
|
};
|
||||||
err = htb_offload(dev, &offload_opt);
|
err = htb_offload(dev, &offload_opt);
|
||||||
if (err) {
|
if (err) {
|
||||||
pr_err("htb: TC_HTB_LEAF_TO_INNER failed with err = %d\n",
|
NL_SET_ERR_MSG_WEAK(extack,
|
||||||
err);
|
"Failed to offload TC_HTB_LEAF_TO_INNER");
|
||||||
htb_graft_helper(dev_queue, old_q);
|
htb_graft_helper(dev_queue, old_q);
|
||||||
goto err_kill_estimator;
|
goto err_kill_estimator;
|
||||||
}
|
}
|
||||||
|
@ -2067,8 +2067,9 @@ static int htb_change_class(struct Qdisc *sch, u32 classid,
|
||||||
qdisc_put(parent_qdisc);
|
qdisc_put(parent_qdisc);
|
||||||
|
|
||||||
if (warn)
|
if (warn)
|
||||||
pr_warn("HTB: quantum of class %X is %s. Consider r2q change.\n",
|
NL_SET_ERR_MSG_FMT_MOD(extack,
|
||||||
cl->common.classid, (warn == -1 ? "small" : "big"));
|
"quantum of class %X is %s. Consider r2q change.",
|
||||||
|
cl->common.classid, (warn == -1 ? "small" : "big"));
|
||||||
|
|
||||||
qdisc_class_hash_grow(sch, &q->clhash);
|
qdisc_class_hash_grow(sch, &q->clhash);
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,7 @@
|
||||||
|
|
||||||
#define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */
|
#define QFQ_MTU_SHIFT 16 /* to support TSO/GSO */
|
||||||
#define QFQ_MIN_LMAX 512 /* see qfq_slot_insert */
|
#define QFQ_MIN_LMAX 512 /* see qfq_slot_insert */
|
||||||
|
#define QFQ_MAX_LMAX (1UL << QFQ_MTU_SHIFT)
|
||||||
|
|
||||||
#define QFQ_MAX_AGG_CLASSES 8 /* max num classes per aggregate allowed */
|
#define QFQ_MAX_AGG_CLASSES 8 /* max num classes per aggregate allowed */
|
||||||
|
|
||||||
|
@ -214,9 +215,14 @@ static struct qfq_class *qfq_find_class(struct Qdisc *sch, u32 classid)
|
||||||
return container_of(clc, struct qfq_class, common);
|
return container_of(clc, struct qfq_class, common);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct netlink_range_validation lmax_range = {
|
||||||
|
.min = QFQ_MIN_LMAX,
|
||||||
|
.max = QFQ_MAX_LMAX,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
|
static const struct nla_policy qfq_policy[TCA_QFQ_MAX + 1] = {
|
||||||
[TCA_QFQ_WEIGHT] = { .type = NLA_U32 },
|
[TCA_QFQ_WEIGHT] = NLA_POLICY_RANGE(NLA_U32, 1, QFQ_MAX_WEIGHT),
|
||||||
[TCA_QFQ_LMAX] = { .type = NLA_U32 },
|
[TCA_QFQ_LMAX] = NLA_POLICY_FULL_RANGE(NLA_U32, &lmax_range),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -402,23 +408,19 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||||
int err;
|
int err;
|
||||||
int delta_w;
|
int delta_w;
|
||||||
|
|
||||||
if (tca[TCA_OPTIONS] == NULL) {
|
if (NL_REQ_ATTR_CHECK(extack, NULL, tca, TCA_OPTIONS)) {
|
||||||
pr_notice("qfq: no options\n");
|
NL_SET_ERR_MSG_MOD(extack, "missing options");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = nla_parse_nested_deprecated(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS],
|
err = nla_parse_nested_deprecated(tb, TCA_QFQ_MAX, tca[TCA_OPTIONS],
|
||||||
qfq_policy, NULL);
|
qfq_policy, extack);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (tb[TCA_QFQ_WEIGHT]) {
|
if (tb[TCA_QFQ_WEIGHT])
|
||||||
weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
|
weight = nla_get_u32(tb[TCA_QFQ_WEIGHT]);
|
||||||
if (!weight || weight > (1UL << QFQ_MAX_WSHIFT)) {
|
else
|
||||||
pr_notice("qfq: invalid weight %u\n", weight);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
weight = 1;
|
weight = 1;
|
||||||
|
|
||||||
if (tb[TCA_QFQ_LMAX])
|
if (tb[TCA_QFQ_LMAX])
|
||||||
|
@ -426,11 +428,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||||
else
|
else
|
||||||
lmax = psched_mtu(qdisc_dev(sch));
|
lmax = psched_mtu(qdisc_dev(sch));
|
||||||
|
|
||||||
if (lmax < QFQ_MIN_LMAX || lmax > (1UL << QFQ_MTU_SHIFT)) {
|
|
||||||
pr_notice("qfq: invalid max length %u\n", lmax);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
inv_w = ONE_FP / weight;
|
inv_w = ONE_FP / weight;
|
||||||
weight = ONE_FP / inv_w;
|
weight = ONE_FP / inv_w;
|
||||||
|
|
||||||
|
@ -442,8 +439,9 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
|
||||||
delta_w = weight - (cl ? cl->agg->class_weight : 0);
|
delta_w = weight - (cl ? cl->agg->class_weight : 0);
|
||||||
|
|
||||||
if (q->wsum + delta_w > QFQ_MAX_WSUM) {
|
if (q->wsum + delta_w > QFQ_MAX_WSUM) {
|
||||||
pr_notice("qfq: total weight out of range (%d + %u)\n",
|
NL_SET_ERR_MSG_FMT_MOD(extack,
|
||||||
delta_w, q->wsum);
|
"total weight out of range (%d + %u)\n",
|
||||||
|
delta_w, q->wsum);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -114,6 +114,28 @@
|
||||||
"$IP link del dev $DUMMY type dummy"
|
"$IP link del dev $DUMMY type dummy"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "10f7",
|
||||||
|
"name": "Create FQ with invalid initial_quantum setting",
|
||||||
|
"category": [
|
||||||
|
"qdisc",
|
||||||
|
"fq"
|
||||||
|
],
|
||||||
|
"plugins": {
|
||||||
|
"requires": "nsPlugin"
|
||||||
|
},
|
||||||
|
"setup": [
|
||||||
|
"$IP link add dev $DUMMY type dummy || /bin/true"
|
||||||
|
],
|
||||||
|
"cmdUnderTest": "$TC qdisc add dev $DUMMY handle 1: root fq initial_quantum 0x80000000",
|
||||||
|
"expExitCode": "2",
|
||||||
|
"verifyCmd": "$TC qdisc show dev $DUMMY",
|
||||||
|
"matchPattern": "qdisc fq 1: root.*initial_quantum 2048Mb",
|
||||||
|
"matchCount": "0",
|
||||||
|
"teardown": [
|
||||||
|
"$IP link del dev $DUMMY type dummy"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "9398",
|
"id": "9398",
|
||||||
"name": "Create FQ with maxrate setting",
|
"name": "Create FQ with maxrate setting",
|
||||||
|
|
|
@ -46,6 +46,30 @@
|
||||||
"$IP link del dev $DUMMY type dummy"
|
"$IP link del dev $DUMMY type dummy"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "d364",
|
||||||
|
"name": "Test QFQ with max class weight setting",
|
||||||
|
"category": [
|
||||||
|
"qdisc",
|
||||||
|
"qfq"
|
||||||
|
],
|
||||||
|
"plugins": {
|
||||||
|
"requires": "nsPlugin"
|
||||||
|
},
|
||||||
|
"setup": [
|
||||||
|
"$IP link add dev $DUMMY type dummy || /bin/true",
|
||||||
|
"$TC qdisc add dev $DUMMY handle 1: root qfq"
|
||||||
|
],
|
||||||
|
"cmdUnderTest": "$TC class add dev $DUMMY parent 1: classid 1:1 qfq weight 9999",
|
||||||
|
"expExitCode": "2",
|
||||||
|
"verifyCmd": "$TC class show dev $DUMMY",
|
||||||
|
"matchPattern": "class qfq 1:1 root weight 9999 maxpkt",
|
||||||
|
"matchCount": "0",
|
||||||
|
"teardown": [
|
||||||
|
"$TC qdisc del dev $DUMMY handle 1: root",
|
||||||
|
"$IP link del dev $DUMMY type dummy"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "8452",
|
"id": "8452",
|
||||||
"name": "Create QFQ with class maxpkt setting",
|
"name": "Create QFQ with class maxpkt setting",
|
||||||
|
@ -70,6 +94,54 @@
|
||||||
"$IP link del dev $DUMMY type dummy"
|
"$IP link del dev $DUMMY type dummy"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "22df",
|
||||||
|
"name": "Test QFQ class maxpkt setting lower bound",
|
||||||
|
"category": [
|
||||||
|
"qdisc",
|
||||||
|
"qfq"
|
||||||
|
],
|
||||||
|
"plugins": {
|
||||||
|
"requires": "nsPlugin"
|
||||||
|
},
|
||||||
|
"setup": [
|
||||||
|
"$IP link add dev $DUMMY type dummy || /bin/true",
|
||||||
|
"$TC qdisc add dev $DUMMY handle 1: root qfq"
|
||||||
|
],
|
||||||
|
"cmdUnderTest": "$TC class add dev $DUMMY parent 1: classid 1:1 qfq maxpkt 128",
|
||||||
|
"expExitCode": "2",
|
||||||
|
"verifyCmd": "$TC class show dev $DUMMY",
|
||||||
|
"matchPattern": "class qfq 1:1 root weight 1 maxpkt 128",
|
||||||
|
"matchCount": "0",
|
||||||
|
"teardown": [
|
||||||
|
"$TC qdisc del dev $DUMMY handle 1: root",
|
||||||
|
"$IP link del dev $DUMMY type dummy"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "92ee",
|
||||||
|
"name": "Test QFQ class maxpkt setting upper bound",
|
||||||
|
"category": [
|
||||||
|
"qdisc",
|
||||||
|
"qfq"
|
||||||
|
],
|
||||||
|
"plugins": {
|
||||||
|
"requires": "nsPlugin"
|
||||||
|
},
|
||||||
|
"setup": [
|
||||||
|
"$IP link add dev $DUMMY type dummy || /bin/true",
|
||||||
|
"$TC qdisc add dev $DUMMY handle 1: root qfq"
|
||||||
|
],
|
||||||
|
"cmdUnderTest": "$TC class add dev $DUMMY parent 1: classid 1:1 qfq maxpkt 99999",
|
||||||
|
"expExitCode": "2",
|
||||||
|
"verifyCmd": "$TC class show dev $DUMMY",
|
||||||
|
"matchPattern": "class qfq 1:1 root weight 1 maxpkt 99999",
|
||||||
|
"matchCount": "0",
|
||||||
|
"teardown": [
|
||||||
|
"$TC qdisc del dev $DUMMY handle 1: root",
|
||||||
|
"$IP link del dev $DUMMY type dummy"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "d920",
|
"id": "d920",
|
||||||
"name": "Create QFQ with multiple class setting",
|
"name": "Create QFQ with multiple class setting",
|
||||||
|
|
Loading…
Reference in a new issue