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

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

ipv4: Rearrange arguments to ip_rt_redirect()



Pass in the SKB rather than just the IP addresses, so that policy
and other aspects can reside in ip_rt_redirect() rather then
icmp_redirect().

Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d0da720f
Loading
Loading
Loading
Loading
+1 −2
Original line number Diff line number Diff line
@@ -108,8 +108,7 @@ extern struct ip_rt_acct __percpu *ip_rt_acct;

struct in_device;
extern int		ip_rt_init(void);
extern void		ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
				       __be32 src, struct net_device *dev);
extern void		ip_rt_redirect(struct sk_buff *skb, __be32 new_gw);
extern void		rt_cache_flush(struct net *net, int how);
extern void		rt_cache_flush_batch(struct net *net);
extern struct rtable *__ip_route_output_key(struct net *, struct flowi4 *flp);
+6 −30
Original line number Diff line number Diff line
@@ -755,40 +755,16 @@ out_err:

static void icmp_redirect(struct sk_buff *skb)
{
	const struct iphdr *iph;

	if (skb->len < sizeof(struct iphdr))
		goto out_err;
	if (skb->len < sizeof(struct iphdr)) {
		ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
		return;
	}

	/*
	 *	Get the copied header of the packet that caused the redirect
	 */
	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
		goto out;

	iph = (const struct iphdr *)skb->data;

	switch (icmp_hdr(skb)->code & 7) {
	case ICMP_REDIR_NET:
	case ICMP_REDIR_NETTOS:
		/*
		 * As per RFC recommendations now handle it as a host redirect.
		 */
	case ICMP_REDIR_HOST:
	case ICMP_REDIR_HOSTTOS:
		ip_rt_redirect(ip_hdr(skb)->saddr, iph->daddr,
			       icmp_hdr(skb)->un.gateway,
			       iph->saddr, skb->dev);
		break;
	}
		return;

	ip_rt_redirect(skb, icmp_hdr(skb)->un.gateway);
	icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway);

out:
	return;
out_err:
	ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS);
	goto out;
}

/*
+19 −4
Original line number Diff line number Diff line
@@ -1292,18 +1292,33 @@ static void ip_do_redirect(struct rtable *rt, __be32 old_gw, __be32 new_gw)
}

/* called in rcu_read_lock() section */
void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
		    __be32 saddr, struct net_device *dev)
void ip_rt_redirect(struct sk_buff *skb, __be32 new_gw)
{
	int s, i;
	const struct iphdr *iph = (const struct iphdr *) skb->data;
	__be32 old_gw = ip_hdr(skb)->saddr;
	__be32 daddr = iph->daddr;
	__be32 saddr = iph->saddr;
	struct net_device *dev = skb->dev;
	struct in_device *in_dev = __in_dev_get_rcu(dev);
	__be32 skeys[2] = { saddr, 0 };
	int    ikeys[2] = { dev->ifindex, 0 };
	__be32 skeys[2] = { saddr, 0 };
	struct net *net;
	int s, i;

	if (!in_dev)
		return;

	switch (icmp_hdr(skb)->code & 7) {
	case ICMP_REDIR_NET:
	case ICMP_REDIR_NETTOS:
	case ICMP_REDIR_HOST:
	case ICMP_REDIR_HOSTTOS:
		break;

	default:
		return;
	}

	net = dev_net(dev);
	if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) ||
	    ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw) ||