aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-12-06 17:04:13 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-06 17:04:13 -0500
commit87a115783eca7a424eef599d6f10a499f85f59c8 (patch)
tree4b80b4d2ea9a61253f89570f63da1ab9a356dfa4 /net/ipv6
parent8f0315190dec88bf035d50e4fd1db89859b414f6 (diff)
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)
1410 csum_partial(skb_transport_header(skb), 1410 csum_partial(skb_transport_header(skb),
1411 mldlen, 0)); 1411 mldlen, 0));
1412 1412
1413 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1414
1415 if (!dst) {
1416 err = -ENOMEM;
1417 goto err_out;
1418 }
1419
1420 icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT, 1413 icmpv6_flow_init(net->ipv6.igmp_sk, &fl6, ICMPV6_MLD2_REPORT,
1421 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1414 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1422 skb->dev->ifindex); 1415 skb->dev->ifindex);
1416 dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
1423 1417
1424 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1425 err = 0; 1418 err = 0;
1426 if (IS_ERR(dst)) { 1419 if (IS_ERR(dst)) {
1427 err = PTR_ERR(dst); 1420 err = PTR_ERR(dst);
@@ -1785,17 +1778,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1785 rcu_read_lock(); 1778 rcu_read_lock();
1786 idev = __in6_dev_get(skb->dev); 1779 idev = __in6_dev_get(skb->dev);
1787 1780
1788 dst = icmp6_dst_alloc(skb->dev, NULL, &ipv6_hdr(skb)->daddr);
1789 if (!dst) {
1790 err = -ENOMEM;
1791 goto err_out;
1792 }
1793
1794 icmpv6_flow_init(sk, &fl6, type, 1781 icmpv6_flow_init(sk, &fl6, type,
1795 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr, 1782 &ipv6_hdr(skb)->saddr, &ipv6_hdr(skb)->daddr,
1796 skb->dev->ifindex); 1783 skb->dev->ifindex);
1797 1784 dst = icmp6_dst_alloc(skb->dev, NULL, &fl6);
1798 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1799 if (IS_ERR(dst)) { 1785 if (IS_ERR(dst)) {
1800 err = PTR_ERR(dst); 1786 err = PTR_ERR(dst);
1801 goto err_out; 1787 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,
516 type = icmp6h->icmp6_type; 516 type = icmp6h->icmp6_type;
517 517
518 icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex); 518 icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
519 519 dst = icmp6_dst_alloc(dev, neigh, &fl6);
520 dst = icmp6_dst_alloc(dev, neigh, daddr);
521 if (!dst) {
522 kfree_skb(skb);
523 return;
524 }
525
526 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
527 if (IS_ERR(dst)) { 520 if (IS_ERR(dst)) {
528 kfree_skb(skb); 521 kfree_skb(skb);
529 return; 522 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);
1068 1068
1069struct dst_entry *icmp6_dst_alloc(struct net_device *dev, 1069struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1070 struct neighbour *neigh, 1070 struct neighbour *neigh,
1071 const struct in6_addr *addr) 1071 struct flowi6 *fl6)
1072{ 1072{
1073 struct dst_entry *dst;
1073 struct rt6_info *rt; 1074 struct rt6_info *rt;
1074 struct inet6_dev *idev = in6_dev_get(dev); 1075 struct inet6_dev *idev = in6_dev_get(dev);
1075 struct net *net = dev_net(dev); 1076 struct net *net = dev_net(dev);
@@ -1080,13 +1081,14 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1080 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0); 1081 rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
1081 if (unlikely(!rt)) { 1082 if (unlikely(!rt)) {
1082 in6_dev_put(idev); 1083 in6_dev_put(idev);
1084 dst = ERR_PTR(-ENOMEM);
1083 goto out; 1085 goto out;
1084 } 1086 }
1085 1087
1086 if (neigh) 1088 if (neigh)
1087 neigh_hold(neigh); 1089 neigh_hold(neigh);
1088 else { 1090 else {
1089 neigh = __neigh_lookup_errno(&nd_tbl, addr, dev); 1091 neigh = __neigh_lookup_errno(&nd_tbl, &fl6->daddr, dev);
1090 if (IS_ERR(neigh)) 1092 if (IS_ERR(neigh))
1091 neigh = NULL; 1093 neigh = NULL;
1092 } 1094 }
@@ -1095,7 +1097,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1095 rt->dst.output = ip6_output; 1097 rt->dst.output = ip6_output;
1096 dst_set_neighbour(&rt->dst, neigh); 1098 dst_set_neighbour(&rt->dst, neigh);
1097 atomic_set(&rt->dst.__refcnt, 1); 1099 atomic_set(&rt->dst.__refcnt, 1);
1098 rt->rt6i_dst.addr = *addr; 1100 rt->rt6i_dst.addr = fl6->daddr;
1099 rt->rt6i_dst.plen = 128; 1101 rt->rt6i_dst.plen = 128;
1100 rt->rt6i_idev = idev; 1102 rt->rt6i_idev = idev;
1101 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255); 1103 dst_metric_set(&rt->dst, RTAX_HOPLIMIT, 255);
@@ -1107,8 +1109,10 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
1107 1109
1108 fib6_force_start_gc(net); 1110 fib6_force_start_gc(net);
1109 1111
1112 dst = xfrm_lookup(net, &rt->dst, flowi6_to_flowi(fl6), NULL, 0);
1113
1110out: 1114out:
1111 return &rt->dst; 1115 return dst;
1112} 1116}
1113 1117
1114int icmp6_dst_gc(void) 1118int icmp6_dst_gc(void)