Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8126f1d authored by David S. Miller's avatar David S. Miller
Browse files

ipv4: Adjust semantics of rt->rt_gateway.



In order to allow prefixed routes, we have to adjust how rt_gateway
is set and interpreted.

The new interpretation is:

1) rt_gateway == 0, destination is on-link, nexthop is iph->daddr

2) rt_gateway != 0, destination requires a nexthop gateway

Abstract the fetching of the proper nexthop value using a new
inline helper, rt_nexthop(), as suggested by Joe Perches.

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Tested-by: default avatarVijay Subramanian <subramanian.vijay@gmail.com>
parent f1ce3062
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -70,6 +70,13 @@ static inline bool rt_is_output_route(const struct rtable *rt)
	return rt->rt_route_iif == 0;
}

static inline __be32 rt_nexthop(const struct rtable *rt, __be32 daddr)
{
	if (rt->rt_gateway)
		return rt->rt_gateway;
	return daddr;
}

struct ip_rt_acct {
	__u32 	o_bytes;
	__u32 	o_packets;
+1 −2
Original line number Diff line number Diff line
@@ -475,8 +475,7 @@ int arp_find(unsigned char *haddr, struct sk_buff *skb)
		return 1;
	}

	paddr = skb_rtable(skb)->rt_gateway;

	paddr = rt_nexthop(skb_rtable(skb), ip_hdr(skb)->daddr);
	if (arp_set_predefined(inet_addr_type(dev_net(dev), paddr), haddr,
			       paddr, dev))
		return 0;
+2 −2
Original line number Diff line number Diff line
@@ -389,7 +389,7 @@ struct dst_entry *inet_csk_route_req(struct sock *sk,
	rt = ip_route_output_flow(net, fl4, sk);
	if (IS_ERR(rt))
		goto no_route;
	if (opt && opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
	if (opt && opt->opt.is_strictroute && rt->rt_gateway)
		goto route_err;
	return &rt->dst;

@@ -422,7 +422,7 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,
	rt = ip_route_output_flow(net, fl4, sk);
	if (IS_ERR(rt))
		goto no_route;
	if (opt && opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
	if (opt && opt->opt.is_strictroute && rt->rt_gateway)
		goto route_err;
	return &rt->dst;

+1 −1
Original line number Diff line number Diff line
@@ -766,7 +766,7 @@ static netdev_tx_t ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev

		if (skb->protocol == htons(ETH_P_IP)) {
			rt = skb_rtable(skb);
			dst = rt->rt_gateway;
			dst = rt_nexthop(rt, old_iph->daddr);
		}
#if IS_ENABLED(CONFIG_IPV6)
		else if (skb->protocol == htons(ETH_P_IPV6)) {
+1 −1
Original line number Diff line number Diff line
@@ -371,7 +371,7 @@ int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl)
	skb_dst_set_noref(skb, &rt->dst);

packet_routed:
	if (inet_opt && inet_opt->opt.is_strictroute && fl4->daddr != rt->rt_gateway)
	if (inet_opt && inet_opt->opt.is_strictroute && rt->rt_gateway)
		goto no_route;

	/* OK, we know where to send it, allocate and build IP header. */
Loading