ipv4: Remove route key identity dependencies in ip_rt_get_source().
authorDavid S. Miller <davem@davemloft.net>
Fri, 13 May 2011 21:29:41 +0000 (17:29 -0400)
committerDavid S. Miller <davem@davemloft.net>
Fri, 13 May 2011 21:29:41 +0000 (17:29 -0400)
Pass in the sk_buff so that we can fetch the necessary keys from
the packet header when working with input routes.

Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/route.h
net/ipv4/ip_options.c
net/ipv4/route.c

index 9f8070b251fb4cd8de042cdca80b3c82016c4584..ba0e0840370cb0f3b7a966abc69223a117ffeeba 100644 (file)
@@ -189,7 +189,7 @@ extern unsigned             inet_addr_type(struct net *net, __be32 addr);
 extern unsigned                inet_dev_addr_type(struct net *net, const struct net_device *dev, __be32 addr);
 extern void            ip_rt_multicast_event(struct in_device *);
 extern int             ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg);
-extern void            ip_rt_get_source(u8 *src, struct rtable *rt);
+extern void            ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
 extern int             ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);
 
 struct in_ifaddr;
index c6474cd1cbfa16c72efdc44433b6d6c1c236a0d1..89268baabc87bb6b48368dd3911c2bb594fa5272 100644 (file)
@@ -37,7 +37,7 @@
  */
 
 void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
-                           __be32 daddr, struct rtable *rt, int is_frag)
+                     __be32 daddr, struct rtable *rt, int is_frag)
 {
        unsigned char *iph = skb_network_header(skb);
 
@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
 
        if (!is_frag) {
                if (opt->rr_needaddr)
-                       ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, rt);
+                       ip_rt_get_source(iph+opt->rr+iph[opt->rr+2]-5, skb, rt);
                if (opt->ts_needaddr)
-                       ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, rt);
+                       ip_rt_get_source(iph+opt->ts+iph[opt->ts+2]-9, skb, rt);
                if (opt->ts_needtime) {
                        struct timespec tv;
                        __be32 midtime;
@@ -553,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb)
 
        if (opt->rr_needaddr) {
                optptr = (unsigned char *)raw + opt->rr;
-               ip_rt_get_source(&optptr[optptr[2]-5], rt);
+               ip_rt_get_source(&optptr[optptr[2]-5], skb, rt);
                opt->is_changed = 1;
        }
        if (opt->srr_is_hit) {
@@ -572,13 +572,13 @@ void ip_forward_options(struct sk_buff *skb)
                }
                if (srrptr + 3 <= srrspace) {
                        opt->is_changed = 1;
-                       ip_rt_get_source(&optptr[srrptr-1], rt);
+                       ip_rt_get_source(&optptr[srrptr-1], skb, rt);
                        optptr[2] = srrptr+4;
                } else if (net_ratelimit())
                        printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
                if (opt->ts_needaddr) {
                        optptr = raw + opt->ts;
-                       ip_rt_get_source(&optptr[optptr[2]-9], rt);
+                       ip_rt_get_source(&optptr[optptr[2]-9], skb, rt);
                        opt->is_changed = 1;
                }
        }
index 6a83840b16af7657076ed8c14fd42c0c4a7904ab..ad141d894e4ec4b059a7704df322c1a7ec429e68 100644 (file)
@@ -1699,22 +1699,26 @@ static int ip_rt_bug(struct sk_buff *skb)
    in IP options!
  */
 
-void ip_rt_get_source(u8 *addr, struct rtable *rt)
+void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
 {
        __be32 src;
-       struct fib_result res;
 
        if (rt_is_output_route(rt))
                src = rt->rt_src;
        else {
-               struct flowi4 fl4 = {
-                       .daddr = rt->rt_key_dst,
-                       .saddr = rt->rt_key_src,
-                       .flowi4_tos = rt->rt_key_tos,
-                       .flowi4_oif = rt->rt_oif,
-                       .flowi4_iif = rt->rt_iif,
-                       .flowi4_mark = rt->rt_mark,
-               };
+               struct fib_result res;
+               struct flowi4 fl4;
+               struct iphdr *iph;
+
+               iph = ip_hdr(skb);
+
+               memset(&fl4, 0, sizeof(fl4));
+               fl4.daddr = iph->daddr;
+               fl4.saddr = iph->saddr;
+               fl4.flowi4_tos = iph->tos;
+               fl4.flowi4_oif = rt->dst.dev->ifindex;
+               fl4.flowi4_iif = skb->dev->ifindex;
+               fl4.flowi4_mark = skb->mark;
 
                rcu_read_lock();
                if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)