From: Ido Schimmel <ido...@mellanox.com>

Allow the driver to create an IPv6 multipath route in one go by passing
an array of sibling routes and iterating over them.

Signed-off-by: Ido Schimmel <ido...@mellanox.com>
Acked-by: Jiri Pirko <j...@mellanox.com>
---
 .../ethernet/mellanox/mlxsw/spectrum_router.c | 36 ++++++++++++-------
 1 file changed, 23 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c 
b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
index b3077aceb884..2f5fa1fac825 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
@@ -5306,29 +5306,32 @@ mlxsw_sp_fib6_entry_rt_destroy_all(struct 
mlxsw_sp_fib6_entry *fib6_entry)
 static struct mlxsw_sp_fib6_entry *
 mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
                           struct mlxsw_sp_fib_node *fib_node,
-                          struct fib6_info *rt)
+                          struct fib6_info **rt_arr, unsigned int nrt6)
 {
        struct mlxsw_sp_fib6_entry *fib6_entry;
        struct mlxsw_sp_fib_entry *fib_entry;
        struct mlxsw_sp_rt6 *mlxsw_sp_rt6;
-       int err;
+       int err, i;
 
        fib6_entry = kzalloc(sizeof(*fib6_entry), GFP_KERNEL);
        if (!fib6_entry)
                return ERR_PTR(-ENOMEM);
        fib_entry = &fib6_entry->common;
 
-       mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt);
-       if (IS_ERR(mlxsw_sp_rt6)) {
-               err = PTR_ERR(mlxsw_sp_rt6);
-               goto err_rt6_create;
+       INIT_LIST_HEAD(&fib6_entry->rt6_list);
+
+       for (i = 0; i < nrt6; i++) {
+               mlxsw_sp_rt6 = mlxsw_sp_rt6_create(rt_arr[i]);
+               if (IS_ERR(mlxsw_sp_rt6)) {
+                       err = PTR_ERR(mlxsw_sp_rt6);
+                       goto err_rt6_create;
+               }
+               list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
+               fib6_entry->nrt6++;
        }
 
-       mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, mlxsw_sp_rt6->rt);
+       mlxsw_sp_fib6_entry_type_set(mlxsw_sp, fib_entry, rt_arr[0]);
 
-       INIT_LIST_HEAD(&fib6_entry->rt6_list);
-       list_add_tail(&mlxsw_sp_rt6->list, &fib6_entry->rt6_list);
-       fib6_entry->nrt6 = 1;
        err = mlxsw_sp_nexthop6_group_get(mlxsw_sp, fib6_entry);
        if (err)
                goto err_nexthop6_group_get;
@@ -5338,9 +5341,15 @@ mlxsw_sp_fib6_entry_create(struct mlxsw_sp *mlxsw_sp,
        return fib6_entry;
 
 err_nexthop6_group_get:
-       list_del(&mlxsw_sp_rt6->list);
-       mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
+       i = nrt6;
 err_rt6_create:
+       for (i--; i >= 0; i--) {
+               fib6_entry->nrt6--;
+               mlxsw_sp_rt6 = list_last_entry(&fib6_entry->rt6_list,
+                                              struct mlxsw_sp_rt6, list);
+               list_del(&mlxsw_sp_rt6->list);
+               mlxsw_sp_rt6_destroy(mlxsw_sp_rt6);
+       }
        kfree(fib6_entry);
        return ERR_PTR(err);
 }
@@ -5541,7 +5550,8 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp 
*mlxsw_sp,
                return 0;
        }
 
-       fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt);
+       fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt_arr,
+                                               nrt6);
        if (IS_ERR(fib6_entry)) {
                err = PTR_ERR(fib6_entry);
                goto err_fib6_entry_create;
-- 
2.20.1

Reply via email to