summaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-06 23:04:13 +0100
committerDavid S. Miller <davem@davemloft.net>2011-12-06 23:04:13 +0100
commit87a115783eca7a424eef599d6f10a499f85f59c8 (patch)
tree4b80b4d2ea9a61253f89570f63da1ab9a356dfa4 /net/ipv6
parentipv6: Make third arg to anycast_dst_alloc() bool. (diff)
downloadlinux-87a115783eca7a424eef599d6f10a499f85f59c8.tar.xz
linux-87a115783eca7a424eef599d6f10a499f85f59c8.zip
ipv6: Move xfrm_lookup() call down into icmp6_dst_alloc().
And return error pointers. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/mcast.c18
-rw-r--r--net/ipv6/ndisc.c9
-rw-r--r--net/ipv6/route.c12
3 files changed, 11 insertions, 28 deletions
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 518cbb90c44b..ea34d58e836d 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -1410,18 +1410,11 @@ static void mld_sendpack(struct sk_buff *skb)
csum_partial(skb_transport_header(skb),
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,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
+ dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
- dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
err = 0;
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
@@ -1785,17 +1778,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
rcu_read_lock();
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,
&ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
skb->dev->ifindex);
-
- dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
+ dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto err_out;
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index e72c8af85781..f3e50c29add4 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -516,14 +516,7 @@ void ndisc_send_skb(struct sk_buff *skb,
type = icmp6h->icmp6_type;
icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
-
- dst = icmp6_dst_alloc(dev, neigh, daddr);
- if (!dst) {
- kfree_skb(skb);
- return;
- }
-
- dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
+ dst = icmp6_dst_alloc(dev, neigh, &fl6);
if (IS_ERR(dst)) {
kfree_skb(skb);
return;
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f0b582b26209..d98cf41edf2a 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1068,8 +1068,9 @@ static DEFINE_SPINLOCK(icmp6_dst_lock);
struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
struct neighbour *neigh,
- const struct in6_addr *addr)
+ struct flowi6 *fl6)
{
+ struct dst_entry *dst;
struct rt6_info *rt;
struct inet6_dev *idev = in6_dev_get(dev);
struct net *net = dev_net(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);
if (unlikely(!rt)) {
in6_dev_put(idev);
+ dst = ERR_PTR(-ENOMEM);
goto out;
}
if (neigh)
neigh_hold(neigh);
else {
- neigh = __neigh_lookup_errno(&nd_tbl, addr, dev);
+ neigh = __neigh_lookup_errno(&nd_tbl, &fl6->daddr, dev);
if (IS_ERR(neigh))
neigh = NULL;
}
@@ -1095,7 +1097,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
rt->dst.output = ip6_output;
dst_set_neighbour(&rt->dst, neigh);
atomic_set(&rt->dst.__refcnt, 1);
- rt->rt6i_dst.addr = *addr;
+ rt->rt6i_dst.addr = fl6->daddr;
rt->rt6i_dst.plen = 128;
rt->rt6i_idev = idev;
dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
@@ -1107,8 +1109,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
fib6_force_start_gc(net);
+ dst = xfrm_lookup(net, &rt->dst, flowi6_to_flowi(fl6), NULL, 0);
+
out:
- return &rt->dst;
+ return dst;
}
int icmp6_dst_gc(void)