diff options
author | David S. Miller <davem@davemloft.net> | 2012-07-11 23:38:08 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-07-11 23:38:08 -0400 |
commit | 94206125c4aac32e43c25bfe1b827e7ab993b7dc (patch) | |
tree | 6cfbc21c6b69efd90ccec6575a3a3c91e0bd8cad /net | |
parent | d0da720f9f16a5023cc084bed8968702400f6e0f (diff) |
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: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/icmp.c | 36 | ||||
-rw-r--r-- | net/ipv4/route.c | 23 |
2 files changed, 25 insertions, 34 deletions
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c index 588514627aa..70a793559bb 100644 --- a/net/ipv4/icmp.c +++ b/net/ipv4/icmp.c | |||
@@ -755,40 +755,16 @@ out_err: | |||
755 | 755 | ||
756 | static void icmp_redirect(struct sk_buff *skb) | 756 | static void icmp_redirect(struct sk_buff *skb) |
757 | { | 757 | { |
758 | const struct iphdr *iph; | 758 | if (skb->len < sizeof(struct iphdr)) { |
759 | 759 | ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS); | |
760 | if (skb->len < sizeof(struct iphdr)) | 760 | return; |
761 | goto out_err; | 761 | } |
762 | 762 | ||
763 | /* | ||
764 | * Get the copied header of the packet that caused the redirect | ||
765 | */ | ||
766 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 763 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
767 | goto out; | 764 | return; |
768 | |||
769 | iph = (const struct iphdr *)skb->data; | ||
770 | |||
771 | switch (icmp_hdr(skb)->code & 7) { | ||
772 | case ICMP_REDIR_NET: | ||
773 | case ICMP_REDIR_NETTOS: | ||
774 | /* | ||
775 | * As per RFC recommendations now handle it as a host redirect. | ||
776 | */ | ||
777 | case ICMP_REDIR_HOST: | ||
778 | case ICMP_REDIR_HOSTTOS: | ||
779 | ip_rt_redirect(ip_hdr(skb)->saddr, iph->daddr, | ||
780 | icmp_hdr(skb)->un.gateway, | ||
781 | iph->saddr, skb->dev); | ||
782 | break; | ||
783 | } | ||
784 | 765 | ||
766 | ip_rt_redirect(skb, icmp_hdr(skb)->un.gateway); | ||
785 | icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway); | 767 | icmp_socket_deliver(skb, icmp_hdr(skb)->un.gateway); |
786 | |||
787 | out: | ||
788 | return; | ||
789 | out_err: | ||
790 | ICMP_INC_STATS_BH(dev_net(skb->dev), ICMP_MIB_INERRORS); | ||
791 | goto out; | ||
792 | } | 768 | } |
793 | 769 | ||
794 | /* | 770 | /* |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index a4de87f44c3..f8921b448c3 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1292,18 +1292,33 @@ static void ip_do_redirect(struct rtable *rt, __be32 old_gw, __be32 new_gw) | |||
1292 | } | 1292 | } |
1293 | 1293 | ||
1294 | /* called in rcu_read_lock() section */ | 1294 | /* called in rcu_read_lock() section */ |
1295 | void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | 1295 | void ip_rt_redirect(struct sk_buff *skb, __be32 new_gw) |
1296 | __be32 saddr, struct net_device *dev) | ||
1297 | { | 1296 | { |
1298 | int s, i; | 1297 | const struct iphdr *iph = (const struct iphdr *) skb->data; |
1298 | __be32 old_gw = ip_hdr(skb)->saddr; | ||
1299 | __be32 daddr = iph->daddr; | ||
1300 | __be32 saddr = iph->saddr; | ||
1301 | struct net_device *dev = skb->dev; | ||
1299 | struct in_device *in_dev = __in_dev_get_rcu(dev); | 1302 | struct in_device *in_dev = __in_dev_get_rcu(dev); |
1300 | __be32 skeys[2] = { saddr, 0 }; | ||
1301 | int ikeys[2] = { dev->ifindex, 0 }; | 1303 | int ikeys[2] = { dev->ifindex, 0 }; |
1304 | __be32 skeys[2] = { saddr, 0 }; | ||
1302 | struct net *net; | 1305 | struct net *net; |
1306 | int s, i; | ||
1303 | 1307 | ||
1304 | if (!in_dev) | 1308 | if (!in_dev) |
1305 | return; | 1309 | return; |
1306 | 1310 | ||
1311 | switch (icmp_hdr(skb)->code & 7) { | ||
1312 | case ICMP_REDIR_NET: | ||
1313 | case ICMP_REDIR_NETTOS: | ||
1314 | case ICMP_REDIR_HOST: | ||
1315 | case ICMP_REDIR_HOSTTOS: | ||
1316 | break; | ||
1317 | |||
1318 | default: | ||
1319 | return; | ||
1320 | } | ||
1321 | |||
1307 | net = dev_net(dev); | 1322 | net = dev_net(dev); |
1308 | if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) || | 1323 | if (new_gw == old_gw || !IN_DEV_RX_REDIRECTS(in_dev) || |
1309 | ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw) || | 1324 | ipv4_is_multicast(new_gw) || ipv4_is_lbcast(new_gw) || |