* Re: [patch iproute2-next v4 0/2] devlink: couple forgotten flash patches
From: Jiri Pirko @ 2019-09-16 5:31 UTC (permalink / raw)
To: David Ahern; +Cc: netdev, stephen, jakub.kicinski, saeedm, mlxsw, f.fainelli
In-Reply-To: <7f32dc69-7cc1-4488-a1b6-94db64748630@gmail.com>
Sun, Sep 15, 2019 at 07:58:33PM CEST, dsahern@gmail.com wrote:
>On 9/14/19 12:00 AM, Jiri Pirko wrote:
>> Fri, Sep 13, 2019 at 07:25:07PM CEST, dsahern@gmail.com wrote:
>>> On 9/12/19 12:29 PM, Jiri Pirko wrote:
>>>> From: Jiri Pirko <jiri@mellanox.com>
>>>>
>>>> I was under impression they are already merged, but apparently they are
>>>> not. I just rebased them on top of current iproute2 net-next tree.
>>>>
>>>
>>> they were not forgotten; they were dropped asking for changes.
>>>
>>> thread is here:
>>> https://lore.kernel.org/netdev/20190604134450.2839-3-jiri@resnulli.us/
>>
>> Well not really. The path was discussed in the thread. However, that is
>> unrelated to the changes these patches do. The flashing itself is
>> already there and present. These patches only add status.
>>
>> Did I missed something?
>>
>
>you are thinking like a kernel developer and not a user.
>
>The second patch has a man page change that should state that firmware
>files are expected to be in /lib/firmware and that path is added by the
>kernel so the path passed on the command line needs to drop that part.
ok
^ permalink raw reply
* Re: [patch net-next 02/15] net: fib_notifier: make FIB notifier per-netns
From: Jiri Pirko @ 2019-09-16 5:38 UTC (permalink / raw)
To: David Ahern
Cc: netdev, davem, idosch, jakub.kicinski, tariqt, saeedm, kuznet,
yoshfuji, shuah, mlxsw
In-Reply-To: <87139e84-4310-6632-c5d5-64610d4cc56e@gmail.com>
Sun, Sep 15, 2019 at 10:05:47PM CEST, dsahern@gmail.com wrote:
>On 9/14/19 12:45 AM, Jiri Pirko wrote:
>> #define FIB_DUMP_MAX_RETRIES 5
>> -int register_fib_notifier(struct notifier_block *nb,
>> +int register_fib_notifier(struct net *net, struct notifier_block *nb,
>> void (*cb)(struct notifier_block *nb))
>> {
>> int retries = 0;
>> int err;
>>
>> do {
>> - unsigned int fib_seq = fib_seq_sum();
>> - struct net *net;
>> -
>> - rcu_read_lock();
>> - for_each_net_rcu(net) {
>> - err = fib_net_dump(net, nb);
>> - if (err)
>> - goto err_fib_net_dump;
>> - }
>> - rcu_read_unlock();
>> -
>> - if (fib_dump_is_consistent(nb, cb, fib_seq))
>> + unsigned int fib_seq = fib_seq_sum(net);
>> +
>> + err = fib_net_dump(net, nb);
>> + if (err)
>> + return err;
>> +
>> + if (fib_dump_is_consistent(net, nb, cb, fib_seq))
>> return 0;
>> } while (++retries < FIB_DUMP_MAX_RETRIES);
>
>This is still more complicated than it needs to be. Why lump all
>fib_notifier_ops into 1 dump when they are separate databases with
>separate seq numbers? Just dump them 1 at a time and retry that 1
>database as needed.
Well I think that what you describe is out of scope of this patch. It is
another optimization of fib_notifier. The aim of this patchset is not
optimization of fib_notifier, but devlink netns change. This patchset is
just a dependency.
Can't we do optimization in another patchset? I already struggled to
keep this one within 15-patch limit.
Thanks
>
>ie., This:
> list_for_each_entry_rcu(ops, &net->fib_notifier_ops, list) {
>should be in register_fib_notifier and not fib_net_dump.
>
>as it stands you are potentially replaying way more than is needed when
>a dump is inconsistent.
>
>
>>
>> return -EBUSY;
>> -
>> -err_fib_net_dump:
>> - rcu_read_unlock();
>> - return err;
>> }
>> EXPORT_SYMBOL(register_fib_notifier);
>>
>> -int unregister_fib_notifier(struct notifier_block *nb)
>> +int unregister_fib_notifier(struct net *net, struct notifier_block *nb)
>> {
>> - return atomic_notifier_chain_unregister(&fib_chain, nb);
>> + struct fib_notifier_net *fn_net = net_generic(net, fib_notifier_net_id);
>> +
>> + return atomic_notifier_chain_unregister(&fn_net->fib_chain, nb);
>> }
>> EXPORT_SYMBOL(unregister_fib_notifier);
>>
>
>
>
>
>
^ permalink raw reply
* Re: [PATCH 2/3] wlegacy: Remove unneeded variable and make function to be void
From: zhong jiang @ 2019-09-16 5:53 UTC (permalink / raw)
To: Kalle Valo; +Cc: davem, linux-wireless, netdev, linux-kernel
In-Reply-To: <87h85hh0hb.fsf@kamboji.qca.qualcomm.com>
On 2019/9/13 1:45, Kalle Valo wrote:
> zhong jiang <zhongjiang@huawei.com> writes:
>
>> il4965_set_tkip_dynamic_key_info do not need return value to
>> cope with different ases. And change functon return type to void.
>>
>> Signed-off-by: zhong jiang <zhongjiang@huawei.com>
>> ---
>> drivers/net/wireless/intel/iwlegacy/4965-mac.c | 8 ++------
>> 1 file changed, 2 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
>> index ffb705b..a7bbfe2 100644
>> --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
>> +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
>> @@ -3326,12 +3326,11 @@ struct il_mod_params il4965_mod_params = {
>> return il_send_add_sta(il, &sta_cmd, CMD_SYNC);
>> }
>>
>> -static int
>> +static void
>> il4965_set_tkip_dynamic_key_info(struct il_priv *il,
>> struct ieee80211_key_conf *keyconf, u8 sta_id)
>> {
>> unsigned long flags;
>> - int ret = 0;
>> __le16 key_flags = 0;
>>
>> key_flags |= (STA_KEY_FLG_TKIP | STA_KEY_FLG_MAP_KEY_MSK);
>> @@ -3367,8 +3366,6 @@ struct il_mod_params il4965_mod_params = {
>> memcpy(il->stations[sta_id].sta.key.key, keyconf->key, 16);
>>
>> spin_unlock_irqrestore(&il->sta_lock, flags);
>> -
>> - return ret;
>> }
>>
>> void
>> @@ -3483,8 +3480,7 @@ struct il_mod_params il4965_mod_params = {
>> il4965_set_ccmp_dynamic_key_info(il, keyconf, sta_id);
>> break;
>> case WLAN_CIPHER_SUITE_TKIP:
>> - ret =
>> - il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id);
>> + il4965_set_tkip_dynamic_key_info(il, keyconf, sta_id);
>> break;
>> case WLAN_CIPHER_SUITE_WEP40:
>> case WLAN_CIPHER_SUITE_WEP104:
> To me this looks inconsistent with the rest of the cases in the switch
> statement. And won't we then return the ret variable uninitalised?
Yep, I miss that. please ignore the patch. Thanks,
Sincerely,
zhong jiang
^ permalink raw reply
* [PATCH net-next v2 0/3] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer
From: Ido Schimmel @ 2019-09-16 6:17 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel
From: Ido Schimmel <idosch@mellanox.com>
Shalom says:
While debugging packet loss towards the CPU, it is useful to be able to
query the CPU port's shared buffer quotas and occupancy.
Patch #1 prevents changing the CPU port's threshold and binding.
Patch #2 registers the CPU port with devlink.
Patch #3 adds the ability to query the CPU port's shared buffer quotas and
occupancy.
v2:
Patch #1:
* s/0/MLXSW_PORT_CPU_PORT/
* Assign "mlxsw_sp->ports[MLXSW_PORT_CPU_PORT" at the end of
mlxsw_sp_cpu_port_create() to avoid NULL assignment on error path
* Add common functions for mlxsw_core_port_init/fini()
Patch #2:
* Move "changing CPU port's threshold and binding" check to a separate
patch
Shalom Toledo (3):
mlxsw: spectrum_buffers: Prevent changing CPU port's configuration
mlxsw: spectrum: Register CPU port with devlink
mlxsw: spectrum_buffers: Add the ability to query the CPU port's
shared buffer
drivers/net/ethernet/mellanox/mlxsw/core.c | 65 ++++++++++++++++---
drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++
.../net/ethernet/mellanox/mlxsw/spectrum.c | 46 +++++++++++++
.../mellanox/mlxsw/spectrum_buffers.c | 51 ++++++++++++---
4 files changed, 150 insertions(+), 17 deletions(-)
--
2.21.0
^ permalink raw reply
* [PATCH net-next v2 1/3] mlxsw: spectrum_buffers: Prevent changing CPU port's configuration
From: Ido Schimmel @ 2019-09-16 6:17 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-1-idosch@idosch.org>
From: Shalom Toledo <shalomt@mellanox.com>
Next patch is going to register the CPU port with devlink, but only so
that the CPU port's shared buffer configuration and occupancy could be
queried.
Prevent changing CPU port's shared buffer threshold and binding
configuration.
Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
index 888ba4300bcc..f1dbde73fa78 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
@@ -1085,6 +1085,11 @@ int mlxsw_sp_sb_port_pool_set(struct mlxsw_core_port *mlxsw_core_port,
u32 max_buff;
int err;
+ if (local_port == MLXSW_PORT_CPU_PORT) {
+ NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's threshold is forbidden");
+ return -EINVAL;
+ }
+
err = mlxsw_sp_sb_threshold_in(mlxsw_sp, pool_index,
threshold, &max_buff, extack);
if (err)
@@ -1130,6 +1135,11 @@ int mlxsw_sp_sb_tc_pool_bind_set(struct mlxsw_core_port *mlxsw_core_port,
u32 max_buff;
int err;
+ if (local_port == MLXSW_PORT_CPU_PORT) {
+ NL_SET_ERR_MSG_MOD(extack, "Changing CPU port's binding is forbidden");
+ return -EINVAL;
+ }
+
if (dir != mlxsw_sp->sb_vals->pool_dess[pool_index].dir) {
NL_SET_ERR_MSG_MOD(extack, "Binding egress TC to ingress pool and vice versa is forbidden");
return -EINVAL;
--
2.21.0
^ permalink raw reply related
* [PATCH net-next v2 2/3] mlxsw: spectrum: Register CPU port with devlink
From: Ido Schimmel @ 2019-09-16 6:17 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-1-idosch@idosch.org>
From: Shalom Toledo <shalomt@mellanox.com>
Register CPU port with devlink.
Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
drivers/net/ethernet/mellanox/mlxsw/core.c | 65 ++++++++++++++++---
drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++
.../net/ethernet/mellanox/mlxsw/spectrum.c | 46 +++++++++++++
3 files changed, 107 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
index 3fa96076e8a5..66354b05fd6c 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
@@ -1864,11 +1864,13 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
}
EXPORT_SYMBOL(mlxsw_core_res_get);
-int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
- u32 port_number, bool split,
- u32 split_port_subnumber,
- const unsigned char *switch_id,
- unsigned char switch_id_len)
+static int
+__mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
+ enum devlink_port_flavour flavour,
+ u32 port_number, bool split,
+ u32 split_port_subnumber,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len)
{
struct devlink *devlink = priv_to_devlink(mlxsw_core);
struct mlxsw_core_port *mlxsw_core_port =
@@ -1877,17 +1879,17 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
int err;
mlxsw_core_port->local_port = local_port;
- devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
- port_number, split, split_port_subnumber,
+ devlink_port_attrs_set(devlink_port, flavour, port_number,
+ split, split_port_subnumber,
switch_id, switch_id_len);
err = devlink_port_register(devlink, devlink_port, local_port);
if (err)
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
return err;
}
-EXPORT_SYMBOL(mlxsw_core_port_init);
-void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
+static void
+__mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
{
struct mlxsw_core_port *mlxsw_core_port =
&mlxsw_core->ports[local_port];
@@ -1896,8 +1898,53 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
devlink_port_unregister(devlink_port);
memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
}
+
+int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
+ u32 port_number, bool split,
+ u32 split_port_subnumber,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len)
+{
+ return __mlxsw_core_port_init(mlxsw_core, local_port,
+ DEVLINK_PORT_FLAVOUR_PHYSICAL,
+ port_number, split, split_port_subnumber,
+ switch_id, switch_id_len);
+}
+EXPORT_SYMBOL(mlxsw_core_port_init);
+
+void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
+{
+ __mlxsw_core_port_fini(mlxsw_core, local_port);
+}
EXPORT_SYMBOL(mlxsw_core_port_fini);
+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
+ void *port_driver_priv,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len)
+{
+ struct mlxsw_core_port *mlxsw_core_port =
+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT];
+ int err;
+
+ err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
+ DEVLINK_PORT_FLAVOUR_CPU,
+ 0, false, 0,
+ switch_id, switch_id_len);
+ if (err)
+ return err;
+
+ mlxsw_core_port->port_driver_priv = port_driver_priv;
+ return 0;
+}
+EXPORT_SYMBOL(mlxsw_core_cpu_port_init);
+
+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core)
+{
+ __mlxsw_core_port_fini(mlxsw_core, MLXSW_PORT_CPU_PORT);
+}
+EXPORT_SYMBOL(mlxsw_core_cpu_port_fini);
+
void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
void *port_driver_priv, struct net_device *dev)
{
diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
index b65a17d49e43..5d7d2ab6d155 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
@@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
const unsigned char *switch_id,
unsigned char switch_id_len);
void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
+ void *port_driver_priv,
+ const unsigned char *switch_id,
+ unsigned char switch_id_len);
+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
void *port_driver_priv, struct net_device *dev);
void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
index 91e4792bb7e7..dd234cf7b39d 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
@@ -3872,6 +3872,45 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
mlxsw_core_port_fini(mlxsw_sp->core, local_port);
}
+static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port;
+ int err;
+
+ mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL);
+ if (!mlxsw_sp_port)
+ return -ENOMEM;
+
+ mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
+ mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT;
+
+ err = mlxsw_core_cpu_port_init(mlxsw_sp->core,
+ mlxsw_sp_port,
+ mlxsw_sp->base_mac,
+ sizeof(mlxsw_sp->base_mac));
+ if (err) {
+ dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n");
+ goto err_core_cpu_port_init;
+ }
+
+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port;
+ return 0;
+
+err_core_cpu_port_init:
+ kfree(mlxsw_sp_port);
+ return err;
+}
+
+static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp)
+{
+ struct mlxsw_sp_port *mlxsw_sp_port =
+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
+
+ mlxsw_core_cpu_port_fini(mlxsw_sp->core);
+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL;
+ kfree(mlxsw_sp_port);
+}
+
static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port)
{
return mlxsw_sp->ports[local_port] != NULL;
@@ -3884,6 +3923,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
if (mlxsw_sp_port_created(mlxsw_sp, i))
mlxsw_sp_port_remove(mlxsw_sp, i);
+ mlxsw_sp_cpu_port_remove(mlxsw_sp);
kfree(mlxsw_sp->port_to_module);
kfree(mlxsw_sp->ports);
}
@@ -3908,6 +3948,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
goto err_port_to_module_alloc;
}
+ err = mlxsw_sp_cpu_port_create(mlxsw_sp);
+ if (err)
+ goto err_cpu_port_create;
+
for (i = 1; i < max_ports; i++) {
/* Mark as invalid */
mlxsw_sp->port_to_module[i] = -1;
@@ -3931,6 +3975,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
for (i--; i >= 1; i--)
if (mlxsw_sp_port_created(mlxsw_sp, i))
mlxsw_sp_port_remove(mlxsw_sp, i);
+ mlxsw_sp_cpu_port_remove(mlxsw_sp);
+err_cpu_port_create:
kfree(mlxsw_sp->port_to_module);
err_port_to_module_alloc:
kfree(mlxsw_sp->ports);
--
2.21.0
^ permalink raw reply related
* [PATCH net-next v2 3/3] mlxsw: spectrum_buffers: Add the ability to query the CPU port's shared buffer
From: Ido Schimmel @ 2019-09-16 6:17 UTC (permalink / raw)
To: netdev; +Cc: davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-1-idosch@idosch.org>
From: Shalom Toledo <shalomt@mellanox.com>
While debugging packet loss towards the CPU, it is useful to be able to
query the CPU port's shared buffer quotas and occupancy.
Since the CPU port has no ingress buffers, all the shared buffers ingress
information will be cleared.
Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
Signed-off-by: Ido Schimmel <idosch@mellanox.com>
---
.../mellanox/mlxsw/spectrum_buffers.c | 41 +++++++++++++++----
1 file changed, 33 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
index f1dbde73fa78..b9eeae37a4dc 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_buffers.c
@@ -250,6 +250,10 @@ static int mlxsw_sp_sb_pm_occ_clear(struct mlxsw_sp *mlxsw_sp, u8 local_port,
&mlxsw_sp->sb_vals->pool_dess[pool_index];
char sbpm_pl[MLXSW_REG_SBPM_LEN];
+ if (local_port == MLXSW_PORT_CPU_PORT &&
+ des->dir == MLXSW_REG_SBXX_DIR_INGRESS)
+ return 0;
+
mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir,
true, 0, 0);
return mlxsw_reg_trans_query(mlxsw_sp->core, MLXSW_REG(sbpm), sbpm_pl,
@@ -273,6 +277,10 @@ static int mlxsw_sp_sb_pm_occ_query(struct mlxsw_sp *mlxsw_sp, u8 local_port,
char sbpm_pl[MLXSW_REG_SBPM_LEN];
struct mlxsw_sp_sb_pm *pm;
+ if (local_port == MLXSW_PORT_CPU_PORT &&
+ des->dir == MLXSW_REG_SBXX_DIR_INGRESS)
+ return 0;
+
pm = mlxsw_sp_sb_pm_get(mlxsw_sp, local_port, pool_index);
mlxsw_reg_sbpm_pack(sbpm_pl, local_port, des->pool, des->dir,
false, 0, 0);
@@ -1197,6 +1205,11 @@ static void mlxsw_sp_sb_sr_occ_query_cb(struct mlxsw_core *mlxsw_core,
local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
if (!mlxsw_sp->ports[local_port])
continue;
+ if (local_port == MLXSW_PORT_CPU_PORT) {
+ /* Ingress quotas are not supported for the CPU port */
+ masked_count++;
+ continue;
+ }
for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++) {
cm = mlxsw_sp_sb_cm_get(mlxsw_sp, local_port, i,
MLXSW_REG_SBXX_DIR_INGRESS);
@@ -1232,7 +1245,7 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
char *sbsr_pl;
u8 masked_count;
u8 local_port_1;
- u8 local_port = 0;
+ u8 local_port;
int i;
int err;
int err2;
@@ -1241,8 +1254,8 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
if (!sbsr_pl)
return -ENOMEM;
+ local_port = MLXSW_PORT_CPU_PORT;
next_batch:
- local_port++;
local_port_1 = local_port;
masked_count = 0;
mlxsw_reg_sbsr_pack(sbsr_pl, false);
@@ -1253,7 +1266,11 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
if (!mlxsw_sp->ports[local_port])
continue;
- mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
+ if (local_port != MLXSW_PORT_CPU_PORT) {
+ /* Ingress quotas are not supported for the CPU port */
+ mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
+ local_port, 1);
+ }
mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
err = mlxsw_sp_sb_pm_occ_query(mlxsw_sp, local_port, i,
@@ -1274,8 +1291,10 @@ int mlxsw_sp_sb_occ_snapshot(struct mlxsw_core *mlxsw_core,
cb_priv);
if (err)
goto out;
- if (local_port < mlxsw_core_max_ports(mlxsw_core))
+ if (local_port < mlxsw_core_max_ports(mlxsw_core)) {
+ local_port++;
goto next_batch;
+ }
out:
err2 = mlxsw_reg_trans_bulk_wait(&bulk_list);
@@ -1292,7 +1311,7 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
LIST_HEAD(bulk_list);
char *sbsr_pl;
unsigned int masked_count;
- u8 local_port = 0;
+ u8 local_port;
int i;
int err;
int err2;
@@ -1301,8 +1320,8 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
if (!sbsr_pl)
return -ENOMEM;
+ local_port = MLXSW_PORT_CPU_PORT;
next_batch:
- local_port++;
masked_count = 0;
mlxsw_reg_sbsr_pack(sbsr_pl, true);
for (i = 0; i < MLXSW_SP_SB_ING_TC_COUNT; i++)
@@ -1312,7 +1331,11 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
for (; local_port < mlxsw_core_max_ports(mlxsw_core); local_port++) {
if (!mlxsw_sp->ports[local_port])
continue;
- mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl, local_port, 1);
+ if (local_port != MLXSW_PORT_CPU_PORT) {
+ /* Ingress quotas are not supported for the CPU port */
+ mlxsw_reg_sbsr_ingress_port_mask_set(sbsr_pl,
+ local_port, 1);
+ }
mlxsw_reg_sbsr_egress_port_mask_set(sbsr_pl, local_port, 1);
for (i = 0; i < mlxsw_sp->sb_vals->pool_count; i++) {
err = mlxsw_sp_sb_pm_occ_clear(mlxsw_sp, local_port, i,
@@ -1329,8 +1352,10 @@ int mlxsw_sp_sb_occ_max_clear(struct mlxsw_core *mlxsw_core,
&bulk_list, NULL, 0);
if (err)
goto out;
- if (local_port < mlxsw_core_max_ports(mlxsw_core))
+ if (local_port < mlxsw_core_max_ports(mlxsw_core)) {
+ local_port++;
goto next_batch;
+ }
out:
err2 = mlxsw_reg_trans_bulk_wait(&bulk_list);
--
2.21.0
^ permalink raw reply related
* Re: [PATCH v4 2/2] net: phy: adin: implement Energy Detect Powerdown mode via phy-tunable
From: Ardelean, Alexandru @ 2019-09-16 6:44 UTC (permalink / raw)
To: f.fainelli@gmail.com, andrew@lunn.ch
Cc: mkubecek@suse.cz, davem@davemloft.net, hkallweit1@gmail.com,
devicetree@vger.kernel.org, mark.rutland@arm.com,
linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
robh+dt@kernel.org
In-Reply-To: <53816513-436e-b33b-99cf-18fa98e468b1@gmail.com>
On Sun, 2019-09-15 at 08:11 -0700, Florian Fainelli wrote:
> [External]
>
>
>
> On 9/14/2019 8:29 AM, Andrew Lunn wrote:
> > On Thu, Sep 12, 2019 at 07:28:12PM +0300, Alexandru Ardelean wrote:
> >
> > > +static int adin_set_edpd(struct phy_device *phydev, u16 tx_interval)
> > > +{
> > > + u16 val;
> > > +
> > > + if (tx_interval == ETHTOOL_PHY_EDPD_DISABLE)
> > > + return phy_clear_bits(phydev, ADIN1300_PHY_CTRL_STATUS2,
> > > + (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN));
> > > +
> > > + val = ADIN1300_NRG_PD_EN;
> > > +
> > > + switch (tx_interval) {
> > > + case 1000: /* 1 second */
> > > + /* fallthrough */
> > > + case ETHTOOL_PHY_EDPD_DFLT_TX_MSECS:
> > > + val |= ADIN1300_NRG_PD_TX_EN;
> > > + /* fallthrough */
> > > + case ETHTOOL_PHY_EDPD_NO_TX:
> > > + break;
> > > + default:
> > > + return -EINVAL;
> > > + }
> > > +
> > > + return phy_modify(phydev, ADIN1300_PHY_CTRL_STATUS2,
> > > + (ADIN1300_NRG_PD_EN | ADIN1300_NRG_PD_TX_EN),
> > > + val);
> > > +}
> > > +
> > >
> > > + rc = adin_set_edpd(phydev, 1);
> > > + if (rc < 0)
> > > + return rc;
> >
> > Hi Alexandru
> >
> > Shouldn't this be adin_set_edpd(phydev, 1000);
>
> That does sound like the intended use, or use
> ETHTOOL_PHY_EDPD_DFLT_TX_MSECS, with that fixed:
Ack.
Many thanks for catching this.
I missed it when re-spinning.
>
> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com>
^ permalink raw reply
* Re: [PATCH 2/2] dt-bindings: net: dwmac: document 'mac-mode' property
From: Ardelean, Alexandru @ 2019-09-16 6:49 UTC (permalink / raw)
To: robh@kernel.org
Cc: alexandre.torgue@st.com, --cc=andrew@lunn.ch,
devicetree@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, peppe.cavallaro@st.com,
davem@davemloft.net
In-Reply-To: <5d7ba95d.1c69fb81.dabe4.8057@mx.google.com>
On Fri, 2019-09-13 at 15:36 +0100, Rob Herring wrote:
> [External]
>
> On Fri, Sep 06, 2019 at 04:02:56PM +0300, Alexandru Ardelean wrote:
> > This change documents the 'mac-mode' property that was introduced in the
> > 'stmmac' driver to support passive mode converters that can sit in-between
> > the MAC & PHY.
> >
> > Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
> > ---
> > Documentation/devicetree/bindings/net/snps,dwmac.yaml | 8 ++++++++
> > 1 file changed, 8 insertions(+)
> >
> > diff --git a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > index c78be15704b9..ebe4537a7cce 100644
> > --- a/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > +++ b/Documentation/devicetree/bindings/net/snps,dwmac.yaml
> > @@ -112,6 +112,14 @@ properties:
> > reset-names:
> > const: stmmaceth
> >
> > + mac-mode:
> > + maxItems: 1
>
> Is this an array because {min,max}Items is for arrays? It should be
> defined as a string with possible values.
>
> As this property is the same as another, you can do this:
>
> $ref: ethernet-controller.yaml#/properties/phy-connection-type
>
> Unless only a small subset of those values are valid here, then you may
> want to list them here.
>
Ack.
Thank you.
Will investigate and re-spin.
> > + description:
> > + The property is identical to 'phy-mode', and assumes that there is mode
> > + converter in-between the MAC & PHY (e.g. GMII-to-RGMII). This converter
> > + can be passive (no SW requirement), and requires that the MAC operate
> > + in a different mode than the PHY in order to function.
> > +
> > snps,axi-config:
> > $ref: /schemas/types.yaml#definitions/phandle
> > description:
> > --
> > 2.20.1
> >
^ permalink raw reply
* Re: [v3 2/3] samples: pktgen: add helper functions for IP(v4/v6) CIDR parsing
From: Jesper Dangaard Brouer @ 2019-09-16 6:53 UTC (permalink / raw)
To: Daniel T. Lee
Cc: David S . Miller, netdev, brouer,
Toke Høiland-Jørgensen
In-Reply-To: <20190914151353.18054-2-danieltimlee@gmail.com>
On Sun, 15 Sep 2019 00:13:52 +0900
"Daniel T. Lee" <danieltimlee@gmail.com> wrote:
> This commit adds CIDR parsing and IP validate helper function to parse
> single IP or range of IP with CIDR. (e.g. 198.18.0.0/15)
>
> Helpers will be used in prior to set target address in samples/pktgen.
>
> Signed-off-by: Daniel T. Lee <danieltimlee@gmail.com>
> ---
> Changes since v3:
> * Set errexit option to stop script execution on error
>
> samples/pktgen/functions.sh | 124 ++++++++++++++++++++++++++++++++++++
> 1 file changed, 124 insertions(+)
>
> diff --git a/samples/pktgen/functions.sh b/samples/pktgen/functions.sh
> index 4af4046d71be..87ae61701904 100644
> --- a/samples/pktgen/functions.sh
> +++ b/samples/pktgen/functions.sh
> @@ -5,6 +5,8 @@
> # Author: Jesper Dangaaard Brouer
> # License: GPL
>
> +set -o errexit
Unfortunately, this breaks the scripts.
The function proc_cmd are designed to grep after "Result: OK:" which
might fail, and your patch/change makes the script stop immediately.
We actually want to continue, and output what command that failed (and
also grep again after "Result:" to provide the kernel reason).
Even if you somehow "fix" function proc_cmd, then we in general want to
catch different error situations by looking at status $?, and output
meaning full errors via calling err() function. IHMO as minimum with
errexit you need a 'trap' function that can help/inform the user of
what went wrong.
--
Best regards,
Jesper Dangaard Brouer
MSc.CS, Principal Kernel Engineer at Red Hat
LinkedIn: http://www.linkedin.com/in/brouer
^ permalink raw reply
* Re: [PATCH v2] net: stmmac: socfpga: re-use the `interface` parameter from platform data
From: Ardelean, Alexandru @ 2019-09-16 6:58 UTC (permalink / raw)
To: davem@davemloft.net
Cc: linux-stm32@st-md-mailman.stormreply.com, joabreu@synopsys.com,
linux-kernel@vger.kernel.org, mcoquelin.stm32@gmail.com,
netdev@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
peppe.cavallaro@st.com, alexandre.torgue@st.com
In-Reply-To: <20190915.195149.86866545205816280.davem@davemloft.net>
On Sun, 2019-09-15 at 19:51 +0100, David Miller wrote:
> [External]
>
> From: Alexandru Ardelean <alexandru.ardelean@analog.com>
> Date: Thu, 12 Sep 2019 16:28:50 +0300
>
> > diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-
> > socfpga.c
> > index c141fe783e87..5b6213207c43 100644
> > --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> > +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
> ...
> > +static inline int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
>
> Please do not use the inline keyword in foo.c files, let the compiler device.
Ack.
Will remove.
^ permalink raw reply
* Re: [PATCH net-next v2 1/3] mlxsw: spectrum_buffers: Prevent changing CPU port's configuration
From: Jiri Pirko @ 2019-09-16 7:00 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-2-idosch@idosch.org>
Mon, Sep 16, 2019 at 08:17:48AM CEST, idosch@idosch.org wrote:
>From: Shalom Toledo <shalomt@mellanox.com>
>
>Next patch is going to register the CPU port with devlink, but only so
>that the CPU port's shared buffer configuration and occupancy could be
>queried.
>
>Prevent changing CPU port's shared buffer threshold and binding
>configuration.
>
>Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
>Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
^ permalink raw reply
* Re: [patch net-next 00/15] devlink: allow devlink instances to change network namespace
From: David Miller @ 2019-09-16 7:01 UTC (permalink / raw)
To: jiri
Cc: netdev, idosch, dsahern, jakub.kicinski, tariqt, saeedm, kuznet,
yoshfuji, shuah, mlxsw
In-Reply-To: <20190914064608.26799-1-jiri@resnulli.us>
Jiri, this has to wait until the next merge window sorry.
^ permalink raw reply
* Re: [PATCH net] udp: correct reuseport selection with connected sockets
From: David Miller @ 2019-09-16 7:03 UTC (permalink / raw)
To: willemdebruijn.kernel
Cc: netdev, edumazet, kraig, zabele, pabeni, mark.keaton, willemb
In-Reply-To: <20190913011639.55895-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Thu, 12 Sep 2019 21:16:39 -0400
> From: Willem de Bruijn <willemb@google.com>
>
> UDP reuseport groups can hold a mix unconnected and connected sockets.
> Ensure that connections only receive all traffic to their 4-tuple.
>
> Fast reuseport returns on the first reuseport match on the assumption
> that all matches are equal. Only if connections are present, return to
> the previous behavior of scoring all sockets.
>
> Record if connections are present and if so (1) treat such connected
> sockets as an independent match from the group, (2) only return
> 2-tuple matches from reuseport and (3) do not return on the first
> 2-tuple reuseport match to allow for a higher scoring match later.
>
> New field has_conns is set without locks. No other fields in the
> bitmap are modified at runtime and the field is only ever set
> unconditionally, so an RMW cannot miss a change.
>
> Fixes: e32ea7e74727 ("soreuseport: fast reuseport UDP socket selection")
> Link: http://lkml.kernel.org/r/CA+FuTSfRP09aJNYRt04SS6qj22ViiOEWaWmLAwX0psk8-PGNxw@mail.gmail.com
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* [PATCH v3] net: stmmac: socfpga: re-use the `interface` parameter from platform data
From: Alexandru Ardelean @ 2019-09-16 7:04 UTC (permalink / raw)
To: netdev, linux-stm32, linux-arm-kernel, linux-kernel
Cc: peppe.cavallaro, alexandre.torgue, joabreu, mcoquelin.stm32,
davem, Alexandru Ardelean
The socfpga sub-driver defines an `interface` field in the `socfpga_dwmac`
struct and parses it on init.
The shared `stmmac_probe_config_dt()` function also parses this from the
device-tree and makes it available on the returned `plat_data` (which is
the same data available via `netdev_priv()`).
All that's needed now is to dig that information out, via some
`dev_get_drvdata()` && `netdev_priv()` calls and re-use it.
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
Changelog v2 -> v3:
* drop `inline` keyword
Changelog v1 -> v2:
* initially, this patch was developed on a 4.14 kernel, and adapted (badly)
to `net-next`, so it did not build ; the v2 has been fixed and adapted
correctly
.../net/ethernet/stmicro/stmmac/dwmac-socfpga.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
index c141fe783e87..e0212d2fc2a1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-socfpga.c
@@ -46,7 +46,6 @@ struct socfpga_dwmac_ops {
};
struct socfpga_dwmac {
- int interface;
u32 reg_offset;
u32 reg_shift;
struct device *dev;
@@ -110,8 +109,6 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
struct resource res_tse_pcs;
struct resource res_sgmii_adapter;
- dwmac->interface = of_get_phy_mode(np);
-
sys_mgr_base_addr =
altr_sysmgr_regmap_lookup_by_phandle(np, "altr,sysmgr-syscon");
if (IS_ERR(sys_mgr_base_addr)) {
@@ -231,6 +228,14 @@ static int socfpga_dwmac_parse_data(struct socfpga_dwmac *dwmac, struct device *
return ret;
}
+static int socfpga_get_plat_phymode(struct socfpga_dwmac *dwmac)
+{
+ struct net_device *ndev = dev_get_drvdata(dwmac->dev);
+ struct stmmac_priv *priv = netdev_priv(ndev);
+
+ return priv->plat->interface;
+}
+
static int socfpga_set_phy_mode_common(int phymode, u32 *val)
{
switch (phymode) {
@@ -255,7 +260,7 @@ static int socfpga_set_phy_mode_common(int phymode, u32 *val)
static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
{
struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
- int phymode = dwmac->interface;
+ int phymode = socfpga_get_plat_phymode(dwmac);
u32 reg_offset = dwmac->reg_offset;
u32 reg_shift = dwmac->reg_shift;
u32 ctrl, val, module;
@@ -314,7 +319,7 @@ static int socfpga_gen5_set_phy_mode(struct socfpga_dwmac *dwmac)
static int socfpga_gen10_set_phy_mode(struct socfpga_dwmac *dwmac)
{
struct regmap *sys_mgr_base_addr = dwmac->sys_mgr_base_addr;
- int phymode = dwmac->interface;
+ int phymode = socfpga_get_plat_phymode(dwmac);
u32 reg_offset = dwmac->reg_offset;
u32 reg_shift = dwmac->reg_shift;
u32 ctrl, val, module;
--
2.20.1
^ permalink raw reply related
* net-next is CLOSED...
From: David Miller @ 2019-09-16 7:05 UTC (permalink / raw)
To: netdev
It's merge window time...
^ permalink raw reply
* Re: [PATCH net-next] net: dsa: b53: Add support for port_egress_floods callback
From: David Miller @ 2019-09-16 7:06 UTC (permalink / raw)
To: f.fainelli; +Cc: netdev, b.spranger, andrew, vivien.didelot, linux-kernel
In-Reply-To: <20190913032841.4302-1-f.fainelli@gmail.com>
From: Florian Fainelli <f.fainelli@gmail.com>
Date: Thu, 12 Sep 2019 20:28:39 -0700
> Add support for configuring the per-port egress flooding control for
> both Unicast and Multicast traffic.
>
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
Applied with comment typo fixed.
^ permalink raw reply
* Re: [PATCH] qed: fix spelling mistake "fullill" -> "fulfill"
From: David Miller @ 2019-09-16 7:07 UTC (permalink / raw)
To: colin.king
Cc: aelior, GR-everest-linux-l2, netdev, kernel-janitors,
linux-kernel
In-Reply-To: <20190913090759.3490-1-colin.king@canonical.com>
From: Colin King <colin.king@canonical.com>
Date: Fri, 13 Sep 2019 10:07:59 +0100
> From: Colin Ian King <colin.king@canonical.com>
>
> There is a spelling mistake in a DP_VERBOSE debug message. Fix it.
> (Using American English spelling as this is the most common way
> to spell this in the kernel).
>
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied to net-next
^ permalink raw reply
* Re: [PATCH net-next v2 2/3] mlxsw: spectrum: Register CPU port with devlink
From: Jiri Pirko @ 2019-09-16 7:08 UTC (permalink / raw)
To: Ido Schimmel; +Cc: netdev, davem, jiri, shalomt, mlxsw, Ido Schimmel
In-Reply-To: <20190916061750.26207-3-idosch@idosch.org>
Mon, Sep 16, 2019 at 08:17:49AM CEST, idosch@idosch.org wrote:
>From: Shalom Toledo <shalomt@mellanox.com>
>
>Register CPU port with devlink.
>
>Signed-off-by: Shalom Toledo <shalomt@mellanox.com>
>Signed-off-by: Ido Schimmel <idosch@mellanox.com>
>---
> drivers/net/ethernet/mellanox/mlxsw/core.c | 65 ++++++++++++++++---
> drivers/net/ethernet/mellanox/mlxsw/core.h | 5 ++
> .../net/ethernet/mellanox/mlxsw/spectrum.c | 46 +++++++++++++
> 3 files changed, 107 insertions(+), 9 deletions(-)
>
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.c b/drivers/net/ethernet/mellanox/mlxsw/core.c
>index 3fa96076e8a5..66354b05fd6c 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/core.c
>+++ b/drivers/net/ethernet/mellanox/mlxsw/core.c
>@@ -1864,11 +1864,13 @@ u64 mlxsw_core_res_get(struct mlxsw_core *mlxsw_core,
> }
> EXPORT_SYMBOL(mlxsw_core_res_get);
>
>-int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>- u32 port_number, bool split,
>- u32 split_port_subnumber,
>- const unsigned char *switch_id,
>- unsigned char switch_id_len)
>+static int
>+__mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>+ enum devlink_port_flavour flavour,
>+ u32 port_number, bool split,
>+ u32 split_port_subnumber,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len)
No need to wrap after "static int":
static int __mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
enum devlink_port_flavour flavour,
u32 port_number, bool split,
u32 split_port_subnumber,
const unsigned char *switch_id,
unsigned char switch_id_len)
> {
> struct devlink *devlink = priv_to_devlink(mlxsw_core);
> struct mlxsw_core_port *mlxsw_core_port =
>@@ -1877,17 +1879,17 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
> int err;
>
> mlxsw_core_port->local_port = local_port;
>- devlink_port_attrs_set(devlink_port, DEVLINK_PORT_FLAVOUR_PHYSICAL,
>- port_number, split, split_port_subnumber,
>+ devlink_port_attrs_set(devlink_port, flavour, port_number,
>+ split, split_port_subnumber,
> switch_id, switch_id_len);
> err = devlink_port_register(devlink, devlink_port, local_port);
> if (err)
> memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
> return err;
> }
>-EXPORT_SYMBOL(mlxsw_core_port_init);
>
>-void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
>+static void
>+__mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
No need to wrap:
static void __mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
> {
> struct mlxsw_core_port *mlxsw_core_port =
> &mlxsw_core->ports[local_port];
>@@ -1896,8 +1898,53 @@ void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
> devlink_port_unregister(devlink_port);
> memset(mlxsw_core_port, 0, sizeof(*mlxsw_core_port));
> }
>+
>+int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
>+ u32 port_number, bool split,
>+ u32 split_port_subnumber,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len)
>+{
>+ return __mlxsw_core_port_init(mlxsw_core, local_port,
>+ DEVLINK_PORT_FLAVOUR_PHYSICAL,
>+ port_number, split, split_port_subnumber,
>+ switch_id, switch_id_len);
>+}
>+EXPORT_SYMBOL(mlxsw_core_port_init);
>+
>+void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port)
>+{
>+ __mlxsw_core_port_fini(mlxsw_core, local_port);
>+}
> EXPORT_SYMBOL(mlxsw_core_port_fini);
>
>+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
>+ void *port_driver_priv,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len)
>+{
>+ struct mlxsw_core_port *mlxsw_core_port =
>+ &mlxsw_core->ports[MLXSW_PORT_CPU_PORT];
>+ int err;
>+
>+ err = __mlxsw_core_port_init(mlxsw_core, MLXSW_PORT_CPU_PORT,
>+ DEVLINK_PORT_FLAVOUR_CPU,
>+ 0, false, 0,
>+ switch_id, switch_id_len);
>+ if (err)
>+ return err;
>+
>+ mlxsw_core_port->port_driver_priv = port_driver_priv;
It is a bit confusing why this is done here comparing to physical ports,
where it is done during type set. But I didn't find better solution.
>+ return 0;
>+}
>+EXPORT_SYMBOL(mlxsw_core_cpu_port_init);
>+
>+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core)
>+{
>+ __mlxsw_core_port_fini(mlxsw_core, MLXSW_PORT_CPU_PORT);
>+}
>+EXPORT_SYMBOL(mlxsw_core_cpu_port_fini);
>+
> void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
> void *port_driver_priv, struct net_device *dev)
> {
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/core.h b/drivers/net/ethernet/mellanox/mlxsw/core.h
>index b65a17d49e43..5d7d2ab6d155 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/core.h
>+++ b/drivers/net/ethernet/mellanox/mlxsw/core.h
>@@ -177,6 +177,11 @@ int mlxsw_core_port_init(struct mlxsw_core *mlxsw_core, u8 local_port,
> const unsigned char *switch_id,
> unsigned char switch_id_len);
> void mlxsw_core_port_fini(struct mlxsw_core *mlxsw_core, u8 local_port);
>+int mlxsw_core_cpu_port_init(struct mlxsw_core *mlxsw_core,
>+ void *port_driver_priv,
>+ const unsigned char *switch_id,
>+ unsigned char switch_id_len);
>+void mlxsw_core_cpu_port_fini(struct mlxsw_core *mlxsw_core);
> void mlxsw_core_port_eth_set(struct mlxsw_core *mlxsw_core, u8 local_port,
> void *port_driver_priv, struct net_device *dev);
> void mlxsw_core_port_ib_set(struct mlxsw_core *mlxsw_core, u8 local_port,
>diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>index 91e4792bb7e7..dd234cf7b39d 100644
>--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum.c
>@@ -3872,6 +3872,45 @@ static void mlxsw_sp_port_remove(struct mlxsw_sp *mlxsw_sp, u8 local_port)
> mlxsw_core_port_fini(mlxsw_sp->core, local_port);
> }
>
>+static int mlxsw_sp_cpu_port_create(struct mlxsw_sp *mlxsw_sp)
>+{
>+ struct mlxsw_sp_port *mlxsw_sp_port;
>+ int err;
>+
>+ mlxsw_sp_port = kzalloc(sizeof(*mlxsw_sp_port), GFP_KERNEL);
>+ if (!mlxsw_sp_port)
>+ return -ENOMEM;
>+
>+ mlxsw_sp_port->mlxsw_sp = mlxsw_sp;
>+ mlxsw_sp_port->local_port = MLXSW_PORT_CPU_PORT;
>+
>+ err = mlxsw_core_cpu_port_init(mlxsw_sp->core,
>+ mlxsw_sp_port,
>+ mlxsw_sp->base_mac,
>+ sizeof(mlxsw_sp->base_mac));
>+ if (err) {
>+ dev_err(mlxsw_sp->bus_info->dev, "Failed to initialize core CPU port\n");
>+ goto err_core_cpu_port_init;
>+ }
>+
>+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = mlxsw_sp_port;
>+ return 0;
>+
>+err_core_cpu_port_init:
>+ kfree(mlxsw_sp_port);
>+ return err;
>+}
>+
>+static void mlxsw_sp_cpu_port_remove(struct mlxsw_sp *mlxsw_sp)
>+{
>+ struct mlxsw_sp_port *mlxsw_sp_port =
>+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT];
>+
>+ mlxsw_core_cpu_port_fini(mlxsw_sp->core);
>+ mlxsw_sp->ports[MLXSW_PORT_CPU_PORT] = NULL;
>+ kfree(mlxsw_sp_port);
>+}
>+
> static bool mlxsw_sp_port_created(struct mlxsw_sp *mlxsw_sp, u8 local_port)
> {
> return mlxsw_sp->ports[local_port] != NULL;
>@@ -3884,6 +3923,7 @@ static void mlxsw_sp_ports_remove(struct mlxsw_sp *mlxsw_sp)
> for (i = 1; i < mlxsw_core_max_ports(mlxsw_sp->core); i++)
> if (mlxsw_sp_port_created(mlxsw_sp, i))
> mlxsw_sp_port_remove(mlxsw_sp, i);
>+ mlxsw_sp_cpu_port_remove(mlxsw_sp);
> kfree(mlxsw_sp->port_to_module);
> kfree(mlxsw_sp->ports);
> }
>@@ -3908,6 +3948,10 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
> goto err_port_to_module_alloc;
> }
>
>+ err = mlxsw_sp_cpu_port_create(mlxsw_sp);
>+ if (err)
>+ goto err_cpu_port_create;
>+
> for (i = 1; i < max_ports; i++) {
> /* Mark as invalid */
> mlxsw_sp->port_to_module[i] = -1;
>@@ -3931,6 +3975,8 @@ static int mlxsw_sp_ports_create(struct mlxsw_sp *mlxsw_sp)
> for (i--; i >= 1; i--)
> if (mlxsw_sp_port_created(mlxsw_sp, i))
> mlxsw_sp_port_remove(mlxsw_sp, i);
>+ mlxsw_sp_cpu_port_remove(mlxsw_sp);
>+err_cpu_port_create:
> kfree(mlxsw_sp->port_to_module);
> err_port_to_module_alloc:
> kfree(mlxsw_sp->ports);
>--
>2.21.0
>
^ permalink raw reply
* Re: [PATCH net] ip6_gre: fix a dst leak in ip6erspan_tunnel_xmit
From: David Miller @ 2019-09-16 7:09 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, u9012063
In-Reply-To: <1bfbf329c5b3649a6c6362350a0d609ff184deba.1568367947.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Fri, 13 Sep 2019 17:45:47 +0800
> In ip6erspan_tunnel_xmit(), if the skb will not be sent out, it has to
> be freed on the tx_err path. Otherwise when deleting a netns, it would
> cause dst/dev to leak, and dmesg shows:
>
> unregister_netdevice: waiting for lo to become free. Usage count = 1
>
> Fixes: ef7baf5e083c ("ip6_gre: add ip6 erspan collect_md mode")
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [patch net-next 00/15] devlink: allow devlink instances to change network namespace
From: Jiri Pirko @ 2019-09-16 7:09 UTC (permalink / raw)
To: David Miller
Cc: netdev, idosch, dsahern, jakub.kicinski, tariqt, saeedm, kuznet,
yoshfuji, shuah, mlxsw
In-Reply-To: <20190916.090111.605211597512563157.davem@davemloft.net>
Mon, Sep 16, 2019 at 09:01:11AM CEST, davem@davemloft.net wrote:
>
>Jiri, this has to wait until the next merge window sorry.
Sure, no worries :)
^ permalink raw reply
* [PATCH net-next 0/6] net: add support for ip_tun_info options setting
From: Xin Long @ 2019-09-16 7:10 UTC (permalink / raw)
To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
With this patchset, users can configure options with LWTUNNEL_IP(6)_OPTS
by ip route encap for ersapn or vxlan lwtunnel. Note that in kernel part
it won't parse the option details but do some check and memcpy only, and
the options will be parsed by iproute in userspace.
We also improve the vxlan and erspan options processing in this patchset.
As an example I also wrote a patch for iproute2 that I will reply on this
mail, with it we can add options for erspan lwtunnel like:
# ip net a a; ip net a b
# ip -n a l a eth0 type veth peer name eth0 netns b
# ip -n a l s eth0 up; ip -n b link set eth0 up
# ip -n a a a 10.1.0.1/24 dev eth0; ip -n b a a 10.1.0.2/24 dev eth0
# ip -n b l a erspan1 type erspan key 1 seq erspan 123 \
local 10.1.0.2 remote 10.1.0.1
# ip -n b a a 1.1.1.1/24 dev erspan1; ip -n b l s erspan1 up
# ip -n b r a 2.1.1.0/24 dev erspan1
# ip -n a l a erspan1 type erspan key 1 seq local 10.1.0.1 external
# ip -n a a a 2.1.1.1/24 dev erspan1; ip -n a l s erspan1 up
# ip -n a r a 1.1.1.0/24 encap ip id 1 erspan ver 1 idx 123 \
dst 10.1.0.2 dev erspan1
# ip -n a r s; ip net exec a ping 1.1.1.1 -c 1
Xin Long (6):
lwtunnel: add options process for arp request
lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip
lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6
vxlan: check tun_info options_len properly
erspan: fix the tun_info options_len check
erspan: make md work without TUNNEL_ERSPAN_OPT set
drivers/net/vxlan.c | 6 +++--
include/uapi/linux/lwtunnel.h | 2 ++
net/ipv4/ip_gre.c | 31 ++++++++++-------------
net/ipv4/ip_tunnel_core.c | 59 +++++++++++++++++++++++++++++++++----------
net/ipv6/ip6_gre.c | 35 +++++++++++++------------
5 files changed, 84 insertions(+), 49 deletions(-)
--
2.1.0
^ permalink raw reply
* [PATCH net-next 1/6] lwtunnel: add options process for arp request
From: Xin Long @ 2019-09-16 7:10 UTC (permalink / raw)
To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>
Without options copied to the dst tun_info in iptunnel_metadata_reply()
called by arp_process for handling arp_request, the generated arp_reply
packet may be dropped or sent out with wrong options for some tunnels
like erspan and vxlan, and the traffic will break.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
net/ipv4/ip_tunnel_core.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 1452a97..10f0848 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -126,15 +126,14 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
if (!md || md->type != METADATA_IP_TUNNEL ||
md->u.tun_info.mode & IP_TUNNEL_INFO_TX)
-
return NULL;
- res = metadata_dst_alloc(0, METADATA_IP_TUNNEL, flags);
+ src = &md->u.tun_info;
+ res = metadata_dst_alloc(src->options_len, METADATA_IP_TUNNEL, flags);
if (!res)
return NULL;
dst = &res->u.tun_info;
- src = &md->u.tun_info;
dst->key.tun_id = src->key.tun_id;
if (src->mode & IP_TUNNEL_INFO_IPV6)
memcpy(&dst->key.u.ipv6.dst, &src->key.u.ipv6.src,
@@ -143,6 +142,8 @@ struct metadata_dst *iptunnel_metadata_reply(struct metadata_dst *md,
dst->key.u.ipv4.dst = src->key.u.ipv4.src;
dst->key.tun_flags = src->key.tun_flags;
dst->mode = src->mode | IP_TUNNEL_INFO_TX;
+ ip_tunnel_info_opts_set(dst, ip_tunnel_info_opts(src),
+ src->options_len, 0);
return res;
}
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 2/6] lwtunnel: add LWTUNNEL_IP_OPTS support for lwtunnel_ip
From: Xin Long @ 2019-09-16 7:10 UTC (permalink / raw)
To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>
This patch is to add LWTUNNEL_IP_OPTS into lwtunnel_ip_t, by which
users will be able to set options for ip_tunnel_info by "ip route
encap" for erspan and vxlan's private metadata. Like one way to go
in iproute is:
# ip route add 1.1.1.0/24 encap ip id 1 erspan ver 1 idx 123 \
dst 10.1.0.2 dev erspan1
# ip route show
1.1.1.0/24 encap ip id 1 src 0.0.0.0 dst 10.1.0.2 ttl 0 \
tos 0 erspan ver 1 idx 123 dev erspan1 scope link
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/uapi/linux/lwtunnel.h | 1 +
net/ipv4/ip_tunnel_core.c | 30 ++++++++++++++++++++++++------
2 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index de696ca..93f2c05 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -27,6 +27,7 @@ enum lwtunnel_ip_t {
LWTUNNEL_IP_TOS,
LWTUNNEL_IP_FLAGS,
LWTUNNEL_IP_PAD,
+ LWTUNNEL_IP_OPTS,
__LWTUNNEL_IP_MAX,
};
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index 10f0848..d9b7188 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -218,6 +218,7 @@ static const struct nla_policy ip_tun_policy[LWTUNNEL_IP_MAX + 1] = {
[LWTUNNEL_IP_TTL] = { .type = NLA_U8 },
[LWTUNNEL_IP_TOS] = { .type = NLA_U8 },
[LWTUNNEL_IP_FLAGS] = { .type = NLA_U16 },
+ [LWTUNNEL_IP_OPTS] = { .type = NLA_BINARY },
};
static int ip_tun_build_state(struct nlattr *attr,
@@ -228,14 +229,20 @@ static int ip_tun_build_state(struct nlattr *attr,
struct ip_tunnel_info *tun_info;
struct lwtunnel_state *new_state;
struct nlattr *tb[LWTUNNEL_IP_MAX + 1];
- int err;
+ int err, opts_len = 0;
+ void *opts;
err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP_MAX, attr,
ip_tun_policy, extack);
if (err < 0)
return err;
- new_state = lwtunnel_state_alloc(sizeof(*tun_info));
+ if (tb[LWTUNNEL_IP_OPTS]) {
+ opts = nla_data(tb[LWTUNNEL_IP_OPTS]);
+ opts_len = nla_len(tb[LWTUNNEL_IP_OPTS]);
+ }
+
+ new_state = lwtunnel_state_alloc(sizeof(*tun_info) + opts_len);
if (!new_state)
return -ENOMEM;
@@ -269,8 +276,10 @@ static int ip_tun_build_state(struct nlattr *attr,
if (tb[LWTUNNEL_IP_FLAGS])
tun_info->key.tun_flags = nla_get_be16(tb[LWTUNNEL_IP_FLAGS]);
+ if (opts_len)
+ ip_tunnel_info_opts_set(tun_info, opts, opts_len, 0);
+
tun_info->mode = IP_TUNNEL_INFO_TX;
- tun_info->options_len = 0;
*ts = new_state;
@@ -299,6 +308,10 @@ static int ip_tun_fill_encap_info(struct sk_buff *skb,
nla_put_u8(skb, LWTUNNEL_IP_TTL, tun_info->key.ttl) ||
nla_put_be16(skb, LWTUNNEL_IP_FLAGS, tun_info->key.tun_flags))
return -ENOMEM;
+ if (tun_info->options_len &&
+ nla_put(skb, LWTUNNEL_IP_OPTS,
+ tun_info->options_len, ip_tunnel_info_opts(tun_info)))
+ return -ENOMEM;
return 0;
}
@@ -310,13 +323,18 @@ static int ip_tun_encap_nlsize(struct lwtunnel_state *lwtstate)
+ nla_total_size(4) /* LWTUNNEL_IP_SRC */
+ nla_total_size(1) /* LWTUNNEL_IP_TOS */
+ nla_total_size(1) /* LWTUNNEL_IP_TTL */
- + nla_total_size(2); /* LWTUNNEL_IP_FLAGS */
+ + nla_total_size(2) /* LWTUNNEL_IP_FLAGS */
+ + lwt_tun_info(lwtstate)->options_len; /* LWTUNNEL_IP_OPTS */
}
static int ip_tun_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
{
- return memcmp(lwt_tun_info(a), lwt_tun_info(b),
- sizeof(struct ip_tunnel_info));
+ struct ip_tunnel_info *info_a = lwt_tun_info(a);
+ struct ip_tunnel_info *info_b = lwt_tun_info(b);
+ u8 opts_len;
+
+ opts_len = min(info_a->options_len, info_b->options_len);
+ return memcmp(info_a, info_b, sizeof(*info_a) + opts_len);
}
static const struct lwtunnel_encap_ops ip_tun_lwt_ops = {
--
2.1.0
^ permalink raw reply related
* [PATCH net-next 3/6] lwtunnel: add LWTUNNEL_IP6_OPTS support for lwtunnel_ip6
From: Xin Long @ 2019-09-16 7:10 UTC (permalink / raw)
To: network dev; +Cc: davem, Jiri Benc, Thomas Graf, u9012063
In-Reply-To: <cover.1568617721.git.lucien.xin@gmail.com>
Similar to lwtunnel_ip, this patch is to add options set/dump support
for lwtunnel_ip6.
Signed-off-by: Xin Long <lucien.xin@gmail.com>
---
include/uapi/linux/lwtunnel.h | 1 +
net/ipv4/ip_tunnel_core.c | 22 ++++++++++++++++++----
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index 93f2c05..4bed5e6 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -42,6 +42,7 @@ enum lwtunnel_ip6_t {
LWTUNNEL_IP6_TC,
LWTUNNEL_IP6_FLAGS,
LWTUNNEL_IP6_PAD,
+ LWTUNNEL_IP6_OPTS,
__LWTUNNEL_IP6_MAX,
};
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index d9b7188..c8f5375a 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -353,6 +353,7 @@ static const struct nla_policy ip6_tun_policy[LWTUNNEL_IP6_MAX + 1] = {
[LWTUNNEL_IP6_HOPLIMIT] = { .type = NLA_U8 },
[LWTUNNEL_IP6_TC] = { .type = NLA_U8 },
[LWTUNNEL_IP6_FLAGS] = { .type = NLA_U16 },
+ [LWTUNNEL_IP6_OPTS] = { .type = NLA_BINARY },
};
static int ip6_tun_build_state(struct nlattr *attr,
@@ -363,14 +364,20 @@ static int ip6_tun_build_state(struct nlattr *attr,
struct ip_tunnel_info *tun_info;
struct lwtunnel_state *new_state;
struct nlattr *tb[LWTUNNEL_IP6_MAX + 1];
- int err;
+ int err, opts_len = 0;
+ void *opts;
err = nla_parse_nested_deprecated(tb, LWTUNNEL_IP6_MAX, attr,
ip6_tun_policy, extack);
if (err < 0)
return err;
- new_state = lwtunnel_state_alloc(sizeof(*tun_info));
+ if (tb[LWTUNNEL_IP6_OPTS]) {
+ opts = nla_data(tb[LWTUNNEL_IP6_OPTS]);
+ opts_len = nla_len(tb[LWTUNNEL_IP6_OPTS]);
+ }
+
+ new_state = lwtunnel_state_alloc(sizeof(*tun_info) + opts_len);
if (!new_state)
return -ENOMEM;
@@ -396,8 +403,10 @@ static int ip6_tun_build_state(struct nlattr *attr,
if (tb[LWTUNNEL_IP6_FLAGS])
tun_info->key.tun_flags = nla_get_be16(tb[LWTUNNEL_IP6_FLAGS]);
+ if (opts_len)
+ ip_tunnel_info_opts_set(tun_info, opts, opts_len, 0);
+
tun_info->mode = IP_TUNNEL_INFO_TX | IP_TUNNEL_INFO_IPV6;
- tun_info->options_len = 0;
*ts = new_state;
@@ -417,6 +426,10 @@ static int ip6_tun_fill_encap_info(struct sk_buff *skb,
nla_put_u8(skb, LWTUNNEL_IP6_HOPLIMIT, tun_info->key.ttl) ||
nla_put_be16(skb, LWTUNNEL_IP6_FLAGS, tun_info->key.tun_flags))
return -ENOMEM;
+ if (tun_info->options_len &&
+ nla_put(skb, LWTUNNEL_IP6_OPTS,
+ tun_info->options_len, ip_tunnel_info_opts(tun_info)))
+ return -ENOMEM;
return 0;
}
@@ -428,7 +441,8 @@ static int ip6_tun_encap_nlsize(struct lwtunnel_state *lwtstate)
+ nla_total_size(16) /* LWTUNNEL_IP6_SRC */
+ nla_total_size(1) /* LWTUNNEL_IP6_HOPLIMIT */
+ nla_total_size(1) /* LWTUNNEL_IP6_TC */
- + nla_total_size(2); /* LWTUNNEL_IP6_FLAGS */
+ + nla_total_size(2) /* LWTUNNEL_IP6_FLAGS */
+ + lwt_tun_info(lwtstate)->options_len; /* LWTUNNEL_IP6_OPTS */
}
static const struct lwtunnel_encap_ops ip6_tun_lwt_ops = {
--
2.1.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox