summaryrefslogtreecommitdiffstats
path: root/net/ipv6/ndisc.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ndisc.c')
-rw-r--r--net/ipv6/ndisc.c24
1 files changed, 14 insertions, 10 deletions
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index 2342545..92f952d 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -341,6 +341,8 @@ int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int d
case ARPHRD_INFINIBAND:
ipv6_ib_mc_map(addr, dev->broadcast, buf);
return 0;
+ case ARPHRD_IPGRE:
+ return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
default:
if (dir) {
memcpy(buf, dev->broadcast, dev->addr_len);
@@ -511,7 +513,7 @@ void ndisc_send_skb(struct sk_buff *skb,
const struct in6_addr *saddr,
struct icmp6hdr *icmp6h)
{
- struct flowi fl;
+ struct flowi6 fl6;
struct dst_entry *dst;
struct net *net = dev_net(dev);
struct sock *sk = net->ipv6.ndisc_sk;
@@ -521,7 +523,7 @@ void ndisc_send_skb(struct sk_buff *skb,
type = icmp6h->icmp6_type;
- icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex);
+ icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
dst = icmp6_dst_alloc(dev, neigh, daddr);
if (!dst) {
@@ -529,8 +531,8 @@ void ndisc_send_skb(struct sk_buff *skb,
return;
}
- err = xfrm_lookup(net, &dst, &fl, NULL, 0);
- if (err < 0) {
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
+ if (IS_ERR(dst)) {
kfree_skb(skb);
return;
}
@@ -1515,7 +1517,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
struct rt6_info *rt;
struct dst_entry *dst;
struct inet6_dev *idev;
- struct flowi fl;
+ struct flowi6 fl6;
u8 *opt;
int rd_len;
int err;
@@ -1535,15 +1537,15 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
return;
}
- icmpv6_flow_init(sk, &fl, NDISC_REDIRECT,
+ icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
&saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
- dst = ip6_route_output(net, NULL, &fl);
+ dst = ip6_route_output(net, NULL, &fl6);
if (dst == NULL)
return;
- err = xfrm_lookup(net, &dst, &fl, NULL, 0);
- if (err)
+ dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
+ if (IS_ERR(dst))
return;
rt = (struct rt6_info *) dst;
@@ -1553,7 +1555,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
"ICMPv6 Redirect: destination is not a neighbour.\n");
goto release;
}
- if (!xrlim_allow(dst, 1*HZ))
+ if (!rt->rt6i_peer)
+ rt6_bind_peer(rt, 1);
+ if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
goto release;
if (dev->addr_len) {
OpenPOWER on IntegriCloud