mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	mlxsw: spectrum_router: Allow appending to dev-only routes
Commitf34436a430("net/ipv6: Simplify route replace and appending into multipath route") changed the IPv6 route append logic so that dev-only routes can be appended and not only gatewayed routes. Align mlxsw with the new behaviour. Fixes:f34436a430("net/ipv6: Simplify route replace and appending into multipath route") Signed-off-by: Ido Schimmel <idosch@mellanox.com> Acked-by: Jiri Pirko <jiri@mellanox.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									6eba08c362
								
							
						
					
					
						commit
						53b562df8c
					
				
					 1 changed files with 19 additions and 8 deletions
				
			
		| 
						 | 
					@ -4771,11 +4771,11 @@ mlxsw_sp_fib6_entry_rt(const struct mlxsw_sp_fib6_entry *fib6_entry)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static struct mlxsw_sp_fib6_entry *
 | 
					static struct mlxsw_sp_fib6_entry *
 | 
				
			||||||
mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 | 
					mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 | 
				
			||||||
				 const struct fib6_info *nrt, bool replace)
 | 
									 const struct fib6_info *nrt, bool append)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlxsw_sp_fib6_entry *fib6_entry;
 | 
						struct mlxsw_sp_fib6_entry *fib6_entry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!mlxsw_sp_fib6_rt_can_mp(nrt) || replace)
 | 
						if (!append)
 | 
				
			||||||
		return NULL;
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
 | 
						list_for_each_entry(fib6_entry, &fib_node->entry_list, common.list) {
 | 
				
			||||||
| 
						 | 
					@ -4790,8 +4790,7 @@ mlxsw_sp_fib6_node_mp_entry_find(const struct mlxsw_sp_fib_node *fib_node,
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		if (rt->fib6_metric < nrt->fib6_metric)
 | 
							if (rt->fib6_metric < nrt->fib6_metric)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
		if (rt->fib6_metric == nrt->fib6_metric &&
 | 
							if (rt->fib6_metric == nrt->fib6_metric)
 | 
				
			||||||
		    mlxsw_sp_fib6_rt_can_mp(rt))
 | 
					 | 
				
			||||||
			return fib6_entry;
 | 
								return fib6_entry;
 | 
				
			||||||
		if (rt->fib6_metric > nrt->fib6_metric)
 | 
							if (rt->fib6_metric > nrt->fib6_metric)
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -5316,7 +5315,8 @@ static void mlxsw_sp_fib6_entry_replace(struct mlxsw_sp *mlxsw_sp,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 | 
					static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 | 
				
			||||||
				    struct fib6_info *rt, bool replace)
 | 
									    struct fib6_info *rt, bool replace,
 | 
				
			||||||
 | 
									    bool append)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mlxsw_sp_fib6_entry *fib6_entry;
 | 
						struct mlxsw_sp_fib6_entry *fib6_entry;
 | 
				
			||||||
	struct mlxsw_sp_fib_node *fib_node;
 | 
						struct mlxsw_sp_fib_node *fib_node;
 | 
				
			||||||
| 
						 | 
					@ -5342,7 +5342,7 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 | 
				
			||||||
	/* Before creating a new entry, try to append route to an existing
 | 
						/* Before creating a new entry, try to append route to an existing
 | 
				
			||||||
	 * multipath entry.
 | 
						 * multipath entry.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, replace);
 | 
						fib6_entry = mlxsw_sp_fib6_node_mp_entry_find(fib_node, rt, append);
 | 
				
			||||||
	if (fib6_entry) {
 | 
						if (fib6_entry) {
 | 
				
			||||||
		err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt);
 | 
							err = mlxsw_sp_fib6_entry_nexthop_add(mlxsw_sp, fib6_entry, rt);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
| 
						 | 
					@ -5350,6 +5350,14 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* We received an append event, yet did not find any route to
 | 
				
			||||||
 | 
						 * append to.
 | 
				
			||||||
 | 
						 */
 | 
				
			||||||
 | 
						if (WARN_ON(append)) {
 | 
				
			||||||
 | 
							err = -EINVAL;
 | 
				
			||||||
 | 
							goto err_fib6_entry_append;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt);
 | 
						fib6_entry = mlxsw_sp_fib6_entry_create(mlxsw_sp, fib_node, rt);
 | 
				
			||||||
	if (IS_ERR(fib6_entry)) {
 | 
						if (IS_ERR(fib6_entry)) {
 | 
				
			||||||
		err = PTR_ERR(fib6_entry);
 | 
							err = PTR_ERR(fib6_entry);
 | 
				
			||||||
| 
						 | 
					@ -5367,6 +5375,7 @@ static int mlxsw_sp_router_fib6_add(struct mlxsw_sp *mlxsw_sp,
 | 
				
			||||||
err_fib6_node_entry_link:
 | 
					err_fib6_node_entry_link:
 | 
				
			||||||
	mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
 | 
						mlxsw_sp_fib6_entry_destroy(mlxsw_sp, fib6_entry);
 | 
				
			||||||
err_fib6_entry_create:
 | 
					err_fib6_entry_create:
 | 
				
			||||||
 | 
					err_fib6_entry_append:
 | 
				
			||||||
err_fib6_entry_nexthop_add:
 | 
					err_fib6_entry_nexthop_add:
 | 
				
			||||||
	mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
 | 
						mlxsw_sp_fib_node_put(mlxsw_sp, fib_node);
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
| 
						 | 
					@ -5717,7 +5726,7 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 | 
				
			||||||
	struct mlxsw_sp_fib_event_work *fib_work =
 | 
						struct mlxsw_sp_fib_event_work *fib_work =
 | 
				
			||||||
		container_of(work, struct mlxsw_sp_fib_event_work, work);
 | 
							container_of(work, struct mlxsw_sp_fib_event_work, work);
 | 
				
			||||||
	struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
 | 
						struct mlxsw_sp *mlxsw_sp = fib_work->mlxsw_sp;
 | 
				
			||||||
	bool replace;
 | 
						bool replace, append;
 | 
				
			||||||
	int err;
 | 
						int err;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rtnl_lock();
 | 
						rtnl_lock();
 | 
				
			||||||
| 
						 | 
					@ -5728,8 +5737,10 @@ static void mlxsw_sp_router_fib6_event_work(struct work_struct *work)
 | 
				
			||||||
	case FIB_EVENT_ENTRY_APPEND: /* fall through */
 | 
						case FIB_EVENT_ENTRY_APPEND: /* fall through */
 | 
				
			||||||
	case FIB_EVENT_ENTRY_ADD:
 | 
						case FIB_EVENT_ENTRY_ADD:
 | 
				
			||||||
		replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
 | 
							replace = fib_work->event == FIB_EVENT_ENTRY_REPLACE;
 | 
				
			||||||
 | 
							append = fib_work->event == FIB_EVENT_ENTRY_APPEND;
 | 
				
			||||||
		err = mlxsw_sp_router_fib6_add(mlxsw_sp,
 | 
							err = mlxsw_sp_router_fib6_add(mlxsw_sp,
 | 
				
			||||||
					       fib_work->fen6_info.rt, replace);
 | 
										       fib_work->fen6_info.rt, replace,
 | 
				
			||||||
 | 
										       append);
 | 
				
			||||||
		if (err)
 | 
							if (err)
 | 
				
			||||||
			mlxsw_sp_router_fib_abort(mlxsw_sp);
 | 
								mlxsw_sp_router_fib_abort(mlxsw_sp);
 | 
				
			||||||
		mlxsw_sp_rt6_release(fib_work->fen6_info.rt);
 | 
							mlxsw_sp_rt6_release(fib_work->fen6_info.rt);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue