Commit 8e36360a authored by David S. Miller's avatar David S. Miller

ipv4: Remove route key identity dependencies in ip_rt_get_source().

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: default avatarDavid S. Miller <davem@davemloft.net>
parent 22f728f8
...@@ -189,7 +189,7 @@ extern unsigned inet_addr_type(struct net *net, __be32 addr); ...@@ -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 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 void ip_rt_multicast_event(struct in_device *);
extern int ip_rt_ioctl(struct net *, unsigned int cmd, void __user *arg); 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); extern int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb);
struct in_ifaddr; struct in_ifaddr;
......
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
*/ */
void ip_options_build(struct sk_buff *skb, struct ip_options *opt, 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); unsigned char *iph = skb_network_header(skb);
...@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt, ...@@ -50,9 +50,9 @@ void ip_options_build(struct sk_buff *skb, struct ip_options *opt,
if (!is_frag) { if (!is_frag) {
if (opt->rr_needaddr) 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) 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) { if (opt->ts_needtime) {
struct timespec tv; struct timespec tv;
__be32 midtime; __be32 midtime;
...@@ -553,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb) ...@@ -553,7 +553,7 @@ void ip_forward_options(struct sk_buff *skb)
if (opt->rr_needaddr) { if (opt->rr_needaddr) {
optptr = (unsigned char *)raw + opt->rr; 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; opt->is_changed = 1;
} }
if (opt->srr_is_hit) { if (opt->srr_is_hit) {
...@@ -572,13 +572,13 @@ void ip_forward_options(struct sk_buff *skb) ...@@ -572,13 +572,13 @@ void ip_forward_options(struct sk_buff *skb)
} }
if (srrptr + 3 <= srrspace) { if (srrptr + 3 <= srrspace) {
opt->is_changed = 1; 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; optptr[2] = srrptr+4;
} else if (net_ratelimit()) } else if (net_ratelimit())
printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n"); printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
if (opt->ts_needaddr) { if (opt->ts_needaddr) {
optptr = raw + opt->ts; 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; opt->is_changed = 1;
} }
} }
......
...@@ -1699,22 +1699,26 @@ static int ip_rt_bug(struct sk_buff *skb) ...@@ -1699,22 +1699,26 @@ static int ip_rt_bug(struct sk_buff *skb)
in IP options! 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; __be32 src;
struct fib_result res;
if (rt_is_output_route(rt)) if (rt_is_output_route(rt))
src = rt->rt_src; src = rt->rt_src;
else { else {
struct flowi4 fl4 = { struct fib_result res;
.daddr = rt->rt_key_dst, struct flowi4 fl4;
.saddr = rt->rt_key_src, struct iphdr *iph;
.flowi4_tos = rt->rt_key_tos,
.flowi4_oif = rt->rt_oif, iph = ip_hdr(skb);
.flowi4_iif = rt->rt_iif,
.flowi4_mark = rt->rt_mark, 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(); rcu_read_lock();
if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0) if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment