Commit 87a11578 authored by David S. Miller's avatar David S. Miller

ipv6: Move xfrm_lookup() call down into icmp6_dst_alloc().

And return error pointers.
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8f031519
...@@ -95,7 +95,7 @@ extern struct rt6_info *rt6_lookup(struct net *net, ...@@ -95,7 +95,7 @@ extern struct rt6_info *rt6_lookup(struct net *net,
extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev, extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
struct neighbour *neigh, struct neighbour *neigh,
const struct in6_addr *addr); struct flowi6 *fl6);
extern int icmp6_dst_gc(void); extern int icmp6_dst_gc(void);
extern void fib6_force_start_gc(struct net *net); extern void fib6_force_start_gc(struct net *net);
......
...@@ -1410,18 +1410,11 @@ static void mld_sendpack(struct sk_buff *skb) ...@@ -1410,18 +1410,11 @@ static void mld_sendpack(struct sk_buff *skb)
csum_partial(skb_transport_header(skb), csum_partial(skb_transport_header(skb),
mldlen, 0)); mldlen, 0));
dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
if (!dst) {
err = -ENOMEM;
goto err_out;
}
icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT, icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex); skb->dev->ifindex);
dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
err = 0; err = 0;
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
err = PTR_ERR(dst); err = PTR_ERR(dst);
...@@ -1785,17 +1778,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type) ...@@ -1785,17 +1778,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
rcu_read_lock(); rcu_read_lock();
idev = __in6_dev_get(skb->dev); idev = __in6_dev_get(skb->dev);
dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
if (!dst) {
err = -ENOMEM;
goto err_out;
}
icmpv6_flow_init(sk, &fl6, type, icmpv6_flow_init(sk, &fl6, type,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex); skb->dev->ifindex);
dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
err = PTR_ERR(dst); err = PTR_ERR(dst);
goto err_out; goto err_out;
......
...@@ -516,14 +516,7 @@ void ndisc_send_skb(struct sk_buff *skb, ...@@ -516,14 +516,7 @@ void ndisc_send_skb(struct sk_buff *skb,
type = icmp6h->icmp6_type; type = icmp6h->icmp6_type;
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex); icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
dst = icmp6_dst_alloc(dev, neigh, &fl6);
dst = icmp6_dst_alloc(dev, neigh, daddr);
if (!dst) {
kfree_skb(skb);
return;
}
dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
if (IS_ERR(dst)) { if (IS_ERR(dst)) {
kfree_skb(skb); kfree_skb(skb);
return; return;
......
...@@ -1068,8 +1068,9 @@ static DEFINE_SPINLOCK(icmp6_dst_lock); ...@@ -1068,8 +1068,9 @@ static DEFINE_SPINLOCK(icmp6_dst_lock);
struct dst_entry *icmp6_dst_alloc(struct net_device *dev, struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
struct neighbour *neigh, struct neighbour *neigh,
const struct in6_addr *addr) struct flowi6 *fl6)
{ {
struct dst_entry *dst;
struct rt6_info *rt; struct rt6_info *rt;
struct inet6_dev *idev = in6_dev_get(dev); struct inet6_dev *idev = in6_dev_get(dev);
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
...@@ -1080,13 +1081,14 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, ...@@ -1080,13 +1081,14 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
if (unlikely(!rt)) { if (unlikely(!rt)) {
in6_dev_put(idev); in6_dev_put(idev);
dst = ERR_PTR(-ENOMEM);
goto out; goto out;
} }
if (neigh) if (neigh)
neigh_hold(neigh); neigh_hold(neigh);
else { else {
neigh = __neigh_lookup_errno(&nd_tbl, addr, dev); neigh = __neigh_lookup_errno(&nd_tbl, &fl6->daddr, dev);
if (IS_ERR(neigh)) if (IS_ERR(neigh))
neigh = NULL; neigh = NULL;
} }
...@@ -1095,7 +1097,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, ...@@ -1095,7 +1097,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
rt->dst.output = ip6_output; rt->dst.output = ip6_output;
dst_set_neighbour(&rt->dst, neigh); dst_set_neighbour(&rt->dst, neigh);
atomic_set(&rt->dst.__refcnt, 1); atomic_set(&rt->dst.__refcnt, 1);
rt->rt6i_dst.addr = *addr; rt->rt6i_dst.addr = fl6->daddr;
rt->rt6i_dst.plen = 128; rt->rt6i_dst.plen = 128;
rt->rt6i_idev = idev; rt->rt6i_idev = idev;
dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
...@@ -1107,8 +1109,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev, ...@@ -1107,8 +1109,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
fib6_force_start_gc(net); fib6_force_start_gc(net);
dst = xfrm_lookup(net, &rt->dst, flowi6_to_flowi(fl6), NULL, 0);
out: out:
return &rt->dst; return dst;
} }
int icmp6_dst_gc(void) int icmp6_dst_gc(void)
......
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