mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-10-30 08:02:30 +00:00
ipv6: Move xfrm_lookup() call down into icmp6_dst_alloc().
And return error pointers. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
8f0315190d
commit
87a115783e
4 changed files with 12 additions and 29 deletions
|
@ -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)
|
||||||
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)
|
||||||
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,
|
||||||
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);
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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,
|
||||||
|
|
||||||
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)
|
||||||
|
|
Loading…
Reference in a new issue