Commit 19a9d136 authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

ipv4: Flag fib_info with a fib_nh using IPv6 gateway



Until support is added to the offload drivers, they need to be able to
reject routes with an IPv6 gateway. To that end add a flag to fib_info
that indicates if any fib_nh has a v6 gateway. The flag allows the drivers
to efficiently know the use of a v6 gateway without walking all fib_nh
tied to a fib_info each time a route is added.

Update mlxsw and rocker to reject the routes with extack message as to why.

Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1a38c43d
Loading
Loading
Loading
Loading
+8 −0
Original line number Original line Diff line number Diff line
@@ -6092,6 +6092,14 @@ static int mlxsw_sp_router_fib_event(struct notifier_block *nb,
			NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
			NL_SET_ERR_MSG_MOD(info->extack, "FIB offload was aborted. Not configuring route");
			return notifier_from_errno(-EINVAL);
			return notifier_from_errno(-EINVAL);
		}
		}
		if (info->family == AF_INET) {
			struct fib_entry_notifier_info *fen_info = ptr;

			if (fen_info->fi->fib_nh_is_v6) {
				NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported");
				return notifier_from_errno(-EINVAL);
			}
		}
		break;
		break;
	}
	}


+9 −0
Original line number Original line Diff line number Diff line
@@ -2207,6 +2207,15 @@ static int rocker_router_fib_event(struct notifier_block *nb,
	switch (event) {
	switch (event) {
	case FIB_EVENT_ENTRY_ADD: /* fall through */
	case FIB_EVENT_ENTRY_ADD: /* fall through */
	case FIB_EVENT_ENTRY_DEL:
	case FIB_EVENT_ENTRY_DEL:
		if (info->family == AF_INET) {
			struct fib_entry_notifier_info *fen_info = ptr;

			if (fen_info->fi->fib_nh_is_v6) {
				NL_SET_ERR_MSG_MOD(info->extack, "IPv6 gateway with IPv4 route is not supported");
				return notifier_from_errno(-EINVAL);
			}
		}

		memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
		memcpy(&fib_work->fen_info, ptr, sizeof(fib_work->fen_info));
		/* Take referece on fib_info to prevent it from being
		/* Take referece on fib_info to prevent it from being
		 * freed while work is queued. Release it afterwards.
		 * freed while work is queued. Release it afterwards.
+1 −0
Original line number Original line Diff line number Diff line
@@ -147,6 +147,7 @@ struct fib_info {
#define fib_rtt fib_metrics->metrics[RTAX_RTT-1]
#define fib_rtt fib_metrics->metrics[RTAX_RTT-1]
#define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
#define fib_advmss fib_metrics->metrics[RTAX_ADVMSS-1]
	int			fib_nhs;
	int			fib_nhs;
	bool			fib_nh_is_v6;
	struct rcu_head		rcu;
	struct rcu_head		rcu;
	struct fib_nh		fib_nh[0];
	struct fib_nh		fib_nh[0];
#define fib_dev		fib_nh[0].fib_nh_dev
#define fib_dev		fib_nh[0].fib_nh_dev
+2 −0
Original line number Original line Diff line number Diff line
@@ -1349,6 +1349,8 @@ struct fib_info *fib_create_info(struct fib_config *cfg,


	change_nexthops(fi) {
	change_nexthops(fi) {
		fib_info_update_nh_saddr(net, nexthop_nh);
		fib_info_update_nh_saddr(net, nexthop_nh);
		if (nexthop_nh->fib_nh_gw_family == AF_INET6)
			fi->fib_nh_is_v6 = true;
	} endfor_nexthops(fi)
	} endfor_nexthops(fi)


	fib_rebalance(fi);
	fib_rebalance(fi);