aboutsummaryrefslogtreecommitdiffstats
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 2342545a5ee9..92f952d093db 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
341 case ARPHRD_INFINIBAND: 341 case ARPHRD_INFINIBAND:
342 ipv6_ib_mc_map(addr, dev->broadcast, buf); 342 ipv6_ib_mc_map(addr, dev->broadcast, buf);
343 return 0; 343 return 0;
344 case ARPHRD_IPGRE:
345 return ipv6_ipgre_mc_map(addr, dev->broadcast, buf);
344 default: 346 default:
345 if (dir) { 347 if (dir) {
346 memcpy(buf, dev->broadcast, dev->addr_len); 348 memcpy(buf, dev->broadcast, dev->addr_len);
@@ -511,7 +513,7 @@ void ndisc_send_skb(struct sk_buff *skb,
511 const struct in6_addr *saddr, 513 const struct in6_addr *saddr,
512 struct icmp6hdr *icmp6h) 514 struct icmp6hdr *icmp6h)
513{ 515{
514 struct flowi fl; 516 struct flowi6 fl6;
515 struct dst_entry *dst; 517 struct dst_entry *dst;
516 struct net *net = dev_net(dev); 518 struct net *net = dev_net(dev);
517 struct sock *sk = net->ipv6.ndisc_sk; 519 struct sock *sk = net->ipv6.ndisc_sk;
@@ -521,7 +523,7 @@ void ndisc_send_skb(struct sk_buff *skb,
521 523
522 type = icmp6h->icmp6_type; 524 type = icmp6h->icmp6_type;
523 525
524 icmpv6_flow_init(sk, &fl, type, saddr, daddr, dev->ifindex); 526 icmpv6_flow_init(sk, &fl6, type, saddr, daddr, dev->ifindex);
525 527
526 dst = icmp6_dst_alloc(dev, neigh, daddr); 528 dst = icmp6_dst_alloc(dev, neigh, daddr);
527 if (!dst) { 529 if (!dst) {
@@ -529,8 +531,8 @@ void ndisc_send_skb(struct sk_buff *skb,
529 return; 531 return;
530 } 532 }
531 533
532 err = xfrm_lookup(net, &dst, &fl, NULL, 0); 534 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
533 if (err < 0) { 535 if (IS_ERR(dst)) {
534 kfree_skb(skb); 536 kfree_skb(skb);
535 return; 537 return;
536 } 538 }
@@ -1515,7 +1517,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1515 struct rt6_info *rt; 1517 struct rt6_info *rt;
1516 struct dst_entry *dst; 1518 struct dst_entry *dst;
1517 struct inet6_dev *idev; 1519 struct inet6_dev *idev;
1518 struct flowi fl; 1520 struct flowi6 fl6;
1519 u8 *opt; 1521 u8 *opt;
1520 int rd_len; 1522 int rd_len;
1521 int err; 1523 int err;
@@ -1535,15 +1537,15 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1535 return; 1537 return;
1536 } 1538 }
1537 1539
1538 icmpv6_flow_init(sk, &fl, NDISC_REDIRECT, 1540 icmpv6_flow_init(sk, &fl6, NDISC_REDIRECT,
1539 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex); 1541 &saddr_buf, &ipv6_hdr(skb)->saddr, dev->ifindex);
1540 1542
1541 dst = ip6_route_output(net, NULL, &fl); 1543 dst = ip6_route_output(net, NULL, &fl6);
1542 if (dst == NULL) 1544 if (dst == NULL)
1543 return; 1545 return;
1544 1546
1545 err = xfrm_lookup(net, &dst, &fl, NULL, 0); 1547 dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0);
1546 if (err) 1548 if (IS_ERR(dst))
1547 return; 1549 return;
1548 1550
1549 rt = (struct rt6_info *) dst; 1551 rt = (struct rt6_info *) dst;
@@ -1553,7 +1555,9 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1553 "ICMPv6 Redirect: destination is not a neighbour.\n"); 1555 "ICMPv6 Redirect: destination is not a neighbour.\n");
1554 goto release; 1556 goto release;
1555 } 1557 }
1556 if (!xrlim_allow(dst, 1*HZ)) 1558 if (!rt->rt6i_peer)
1559 rt6_bind_peer(rt, 1);
1560 if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
1557 goto release; 1561 goto release;
1558 1562
1559 if (dev->addr_len) { 1563 if (dev->addr_len) {