There are only lpm add/del for ipv6 needed.
Nexthops indexes shared with ipv4.
Limitations:
- Only "local" and "main" tables supported
- Only generic interfaces supported for router (no bridges or vlans)
Co-developed-by: Taras Chornyi <[email protected]>
Signed-off-by: Taras Chornyi <[email protected]>
Co-developed-by: Elad Nachman <[email protected]>
Signed-off-by: Elad Nachman <[email protected]>
Signed-off-by: Yevhen Orlov <[email protected]>
---
.../ethernet/marvell/prestera/prestera_hw.c | 34 +++++++++++++++++++
.../ethernet/marvell/prestera/prestera_hw.h | 4 +++
.../marvell/prestera/prestera_router_hw.c | 33 ++++++++++++++----
3 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
index fc6f7d2746e8..13341056599a 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
@@ -540,6 +540,11 @@ struct prestera_msg_iface {
u8 __pad[3];
};
+enum prestera_msg_ip_addr_v {
+ PRESTERA_MSG_IPV4 = 0,
+ PRESTERA_MSG_IPV6
+};
+
struct prestera_msg_ip_addr {
union {
__be32 ipv4;
@@ -2088,6 +2093,35 @@ int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
sizeof(req));
}
+int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
+ __u8 *dst, u32 dst_len, u32 grp_id)
+{
+ struct prestera_msg_lpm_req req;
+
+ req.dst.v = PRESTERA_MSG_IPV6;
+ memcpy(&req.dst.u.ipv6, dst, 16);
+ req.dst_len = __cpu_to_le32(dst_len);
+ req.vr_id = __cpu_to_le16(vr_id);
+ req.grp_id = __cpu_to_le32(grp_id);
+
+ return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd,
+ sizeof(req));
+}
+
+int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
+ __u8 *dst, u32 dst_len)
+{
+ struct prestera_msg_lpm_req req;
+
+ req.dst.v = PRESTERA_MSG_IPV6;
+ memcpy(&req.dst.u.ipv6, dst, 16);
+ req.dst_len = __cpu_to_le32(dst_len);
+ req.vr_id = __cpu_to_le16(vr_id);
+
+ return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd,
+ sizeof(req));
+}
+
int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
struct prestera_neigh_info *nhs, u32 grp_id)
{
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
index 0a929279e1ce..8769be6752bc 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h
+++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
@@ -266,6 +266,10 @@ int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id,
__be32 dst, u32 dst_len, u32 grp_id);
int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
__be32 dst, u32 dst_len);
+int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
+ __u8 *dst, u32 dst_len, u32 grp_id);
+int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
+ __u8 *dst, u32 dst_len);
/* NH API */
int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
index 02faaea2aefa..1c6d0cdbdfdf 100644
--- a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
+++ b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
@@ -581,8 +581,16 @@ static void __prestera_fib_node_destruct(struct prestera_switch *sw,
struct prestera_vr *vr;
vr = fib_node->info.vr;
- prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
- fib_node->key.prefix_len);
+ if (fib_node->key.addr.v == PRESTERA_IPV4)
+ prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
+ fib_node->key.prefix_len);
+ else if (fib_node->key.addr.v == PRESTERA_IPV6)
+ prestera_hw_lpm6_del(sw, vr->hw_vr_id,
+ (u8 *)&fib_node->key.addr.u.ipv6.s6_addr,
+ fib_node->key.prefix_len);
+ else
+ WARN(1, "Invalid address version. Memory corrupted?");
+
switch (fib_node->info.type) {
case PRESTERA_FIB_TYPE_UC_NH:
prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
@@ -661,8 +669,16 @@ prestera_fib_node_create(struct prestera_switch *sw,
goto err_nh_grp_get;
}
- err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
- key->prefix_len, grp_id);
+ if (key->addr.v == PRESTERA_IPV4)
+ err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
+ key->prefix_len, grp_id);
+ else if (key->addr.v == PRESTERA_IPV6)
+ err = prestera_hw_lpm6_add(sw, vr->hw_vr_id,
+ (u8 *)&key->addr.u.ipv6.s6_addr,
+ key->prefix_len, grp_id);
+ else
+ WARN(1, "Invalid address version. Memory corrupted?");
+
if (err)
goto err_lpm_add;
@@ -674,8 +690,13 @@ prestera_fib_node_create(struct prestera_switch *sw,
return fib_node;
err_ht_insert:
- prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
- key->prefix_len);
+ if (key->addr.v == PRESTERA_IPV4)
+ prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
+ key->prefix_len);
+ else if (key->addr.v == PRESTERA_IPV6)
+ prestera_hw_lpm6_del(sw, vr->hw_vr_id,
+ (u8 *)&key->addr.u.ipv6.s6_addr,
+ key->prefix_len);
err_lpm_add:
if (fib_type == PRESTERA_FIB_TYPE_UC_NH)
prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
--
2.17.1
Hi Yevhen,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on net-next/master]
url: https://github.com/intel-lab-lkp/linux/commits/Yevhen-Orlov/net-marvell-prestera-add-ipv6-routes-offloading/20221220-035326
patch link: https://lore.kernel.org/r/Y5%2BRSF0Had10xizI%40yorlov.ow.s
patch subject: [PATCH net-next v1 1/2] net: marvell: prestera: Add router ipv6 ABI
config: x86_64-randconfig-a013-20221219
compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/97d5847b7ceba4ba9aaa7402ae3cc3da3eac2725
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Yevhen-Orlov/net-marvell-prestera-add-ipv6-routes-offloading/20221220-035326
git checkout 97d5847b7ceba4ba9aaa7402ae3cc3da3eac2725
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 olddefconfig
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=x86_64 SHELL=/bin/bash drivers/i2c/ drivers/net/ethernet/marvell/prestera/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
All warnings (new ones prefixed by >>):
>> drivers/net/ethernet/marvell/prestera/prestera_router_hw.c:675:11: warning: variable 'err' is used uninitialized whenever 'if' condition is false [-Wsometimes-uninitialized]
else if (key->addr.v == PRESTERA_IPV6)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/marvell/prestera/prestera_router_hw.c:682:6: note: uninitialized use occurs here
if (err)
^~~
drivers/net/ethernet/marvell/prestera/prestera_router_hw.c:675:7: note: remove the 'if' if its condition is always true
else if (key->addr.v == PRESTERA_IPV6)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/ethernet/marvell/prestera/prestera_router_hw.c:637:9: note: initialize the variable 'err' to silence this warning
int err;
^
= 0
1 warning generated.
vim +675 drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
627
628 struct prestera_fib_node *
629 prestera_fib_node_create(struct prestera_switch *sw,
630 struct prestera_fib_key *key,
631 enum prestera_fib_type fib_type,
632 struct prestera_nexthop_group_key *nh_grp_key)
633 {
634 struct prestera_fib_node *fib_node;
635 u32 grp_id;
636 struct prestera_vr *vr;
637 int err;
638
639 fib_node = kzalloc(sizeof(*fib_node), GFP_KERNEL);
640 if (!fib_node)
641 goto err_kzalloc;
642
643 memcpy(&fib_node->key, key, sizeof(*key));
644 fib_node->info.type = fib_type;
645
646 vr = prestera_vr_get(sw, key->tb_id, NULL);
647 if (IS_ERR(vr))
648 goto err_vr_get;
649
650 fib_node->info.vr = vr;
651
652 switch (fib_type) {
653 case PRESTERA_FIB_TYPE_TRAP:
654 grp_id = PRESTERA_NHGR_UNUSED;
655 break;
656 case PRESTERA_FIB_TYPE_DROP:
657 grp_id = PRESTERA_NHGR_DROP;
658 break;
659 case PRESTERA_FIB_TYPE_UC_NH:
660 fib_node->info.nh_grp = prestera_nexthop_group_get(sw,
661 nh_grp_key);
662 if (IS_ERR(fib_node->info.nh_grp))
663 goto err_nh_grp_get;
664
665 grp_id = fib_node->info.nh_grp->grp_id;
666 break;
667 default:
668 pr_err("Unsupported fib_type %d", fib_type);
669 goto err_nh_grp_get;
670 }
671
672 if (key->addr.v == PRESTERA_IPV4)
673 err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
674 key->prefix_len, grp_id);
> 675 else if (key->addr.v == PRESTERA_IPV6)
--
0-DAY CI Kernel Test Service
https://01.org/lkp
On Sun, Dec 18, 2022 at 11:16:40PM +0100, Yevhen Orlov wrote:
> There are only lpm add/del for ipv6 needed.
> Nexthops indexes shared with ipv4.
>
> Limitations:
> - Only "local" and "main" tables supported
> - Only generic interfaces supported for router (no bridges or vlans)
>
Yevhen, currently net-next is closed.
Please repost when net-next reopens after Jan 2nd.
> Co-developed-by: Taras Chornyi <[email protected]>
> Signed-off-by: Taras Chornyi <[email protected]>
> Co-developed-by: Elad Nachman <[email protected]>
> Signed-off-by: Elad Nachman <[email protected]>
> Signed-off-by: Yevhen Orlov <[email protected]>
> ---
> .../ethernet/marvell/prestera/prestera_hw.c | 34 +++++++++++++++++++
> .../ethernet/marvell/prestera/prestera_hw.h | 4 +++
> .../marvell/prestera/prestera_router_hw.c | 33 ++++++++++++++----
> 3 files changed, 65 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
> index fc6f7d2746e8..13341056599a 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_hw.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.c
> @@ -540,6 +540,11 @@ struct prestera_msg_iface {
> u8 __pad[3];
> };
>
> +enum prestera_msg_ip_addr_v {
> + PRESTERA_MSG_IPV4 = 0,
> + PRESTERA_MSG_IPV6
> +};
> +
> struct prestera_msg_ip_addr {
> union {
> __be32 ipv4;
> @@ -2088,6 +2093,35 @@ int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
> sizeof(req));
> }
>
> +int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
> + __u8 *dst, u32 dst_len, u32 grp_id)
> +{
> + struct prestera_msg_lpm_req req;
> +
> + req.dst.v = PRESTERA_MSG_IPV6;
> + memcpy(&req.dst.u.ipv6, dst, 16);
> + req.dst_len = __cpu_to_le32(dst_len);
> + req.vr_id = __cpu_to_le16(vr_id);
> + req.grp_id = __cpu_to_le32(grp_id);
> +
> + return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_ADD, &req.cmd,
> + sizeof(req));
> +}
> +
> +int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
> + __u8 *dst, u32 dst_len)
> +{
> + struct prestera_msg_lpm_req req;
> +
> + req.dst.v = PRESTERA_MSG_IPV6;
> + memcpy(&req.dst.u.ipv6, dst, 16);
> + req.dst_len = __cpu_to_le32(dst_len);
> + req.vr_id = __cpu_to_le16(vr_id);
> +
> + return prestera_cmd(sw, PRESTERA_CMD_TYPE_ROUTER_LPM_DELETE, &req.cmd,
> + sizeof(req));
> +}
> +
> int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
> struct prestera_neigh_info *nhs, u32 grp_id)
> {
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_hw.h b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
> index 0a929279e1ce..8769be6752bc 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_hw.h
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_hw.h
> @@ -266,6 +266,10 @@ int prestera_hw_lpm_add(struct prestera_switch *sw, u16 vr_id,
> __be32 dst, u32 dst_len, u32 grp_id);
> int prestera_hw_lpm_del(struct prestera_switch *sw, u16 vr_id,
> __be32 dst, u32 dst_len);
> +int prestera_hw_lpm6_add(struct prestera_switch *sw, u16 vr_id,
> + __u8 *dst, u32 dst_len, u32 grp_id);
> +int prestera_hw_lpm6_del(struct prestera_switch *sw, u16 vr_id,
> + __u8 *dst, u32 dst_len);
>
> /* NH API */
> int prestera_hw_nh_entries_set(struct prestera_switch *sw, int count,
> diff --git a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
> index 02faaea2aefa..1c6d0cdbdfdf 100644
> --- a/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
> +++ b/drivers/net/ethernet/marvell/prestera/prestera_router_hw.c
> @@ -581,8 +581,16 @@ static void __prestera_fib_node_destruct(struct prestera_switch *sw,
> struct prestera_vr *vr;
>
> vr = fib_node->info.vr;
> - prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
> - fib_node->key.prefix_len);
> + if (fib_node->key.addr.v == PRESTERA_IPV4)
> + prestera_hw_lpm_del(sw, vr->hw_vr_id, fib_node->key.addr.u.ipv4,
> + fib_node->key.prefix_len);
> + else if (fib_node->key.addr.v == PRESTERA_IPV6)
> + prestera_hw_lpm6_del(sw, vr->hw_vr_id,
> + (u8 *)&fib_node->key.addr.u.ipv6.s6_addr,
> + fib_node->key.prefix_len);
> + else
> + WARN(1, "Invalid address version. Memory corrupted?");
> +
> switch (fib_node->info.type) {
> case PRESTERA_FIB_TYPE_UC_NH:
> prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
> @@ -661,8 +669,16 @@ prestera_fib_node_create(struct prestera_switch *sw,
> goto err_nh_grp_get;
> }
>
> - err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
> - key->prefix_len, grp_id);
> + if (key->addr.v == PRESTERA_IPV4)
> + err = prestera_hw_lpm_add(sw, vr->hw_vr_id, key->addr.u.ipv4,
> + key->prefix_len, grp_id);
> + else if (key->addr.v == PRESTERA_IPV6)
> + err = prestera_hw_lpm6_add(sw, vr->hw_vr_id,
> + (u8 *)&key->addr.u.ipv6.s6_addr,
> + key->prefix_len, grp_id);
> + else
> + WARN(1, "Invalid address version. Memory corrupted?");
> +
> if (err)
> goto err_lpm_add;
>
> @@ -674,8 +690,13 @@ prestera_fib_node_create(struct prestera_switch *sw,
> return fib_node;
>
> err_ht_insert:
> - prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
> - key->prefix_len);
> + if (key->addr.v == PRESTERA_IPV4)
> + prestera_hw_lpm_del(sw, vr->hw_vr_id, key->addr.u.ipv4,
> + key->prefix_len);
> + else if (key->addr.v == PRESTERA_IPV6)
> + prestera_hw_lpm6_del(sw, vr->hw_vr_id,
> + (u8 *)&key->addr.u.ipv6.s6_addr,
> + key->prefix_len);
> err_lpm_add:
> if (fib_type == PRESTERA_FIB_TYPE_UC_NH)
> prestera_nexthop_group_put(sw, fib_node->info.nh_grp);
> --
> 2.17.1
>