Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315125
b: refs/heads/master
c: 9420612
h: refs/heads/master
i:
  315123: c55bda9
v: v3
  • Loading branch information
David S. Miller committed Jul 12, 2012
1 parent bdb8182 commit 8ce66b2
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d0da720f9f16a5023cc084bed8968702400f6e0f
refs/heads/master: 94206125c4aac32e43c25bfe1b827e7ab993b7dc
3 changes: 1 addition & 2 deletions trunk/include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
36 changes: 6 additions & 30 deletions trunk/net/ipv4/icmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,40 +755,16 @@ static void icmp_unreach(struct sk_buff *skb)

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;
}

/*
Expand Down
23 changes: 19 additions & 4 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) ||
Expand Down

0 comments on commit 8ce66b2

Please sign in to comment.