ndisc.c (7159039a128fa0a73ca7b532f6e1d30d9885277f) | ndisc.c (95c385b4d5a71b8ad552aecaa968ea46d7da2f6a) |
---|---|
1/* 2 * Neighbour Discovery for IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * Mike Shaver <shaver@ingenia.com> 8 * --- 435 unchanged lines hidden (view full) --- 444 int err; 445 446 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 447 448 /* for anycast or proxy, solicited_addr != src_addr */ 449 ifp = ipv6_get_ifaddr(solicited_addr, dev, 1); 450 if (ifp) { 451 src_addr = solicited_addr; | 1/* 2 * Neighbour Discovery for IPv6 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * Mike Shaver <shaver@ingenia.com> 8 * --- 435 unchanged lines hidden (view full) --- 444 int err; 445 446 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 447 448 /* for anycast or proxy, solicited_addr != src_addr */ 449 ifp = ipv6_get_ifaddr(solicited_addr, dev, 1); 450 if (ifp) { 451 src_addr = solicited_addr; |
452 if (ifp->flags & IFA_F_OPTIMISTIC) 453 override = 0; |
|
452 in6_ifa_put(ifp); 453 } else { 454 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr)) 455 return; 456 src_addr = &tmpaddr; 457 } 458 459 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr, --- 79 unchanged lines hidden (view full) --- 539 struct sk_buff *skb; 540 struct nd_msg *msg; 541 struct in6_addr addr_buf; 542 int len; 543 int err; 544 int send_llinfo; 545 546 if (saddr == NULL) { | 454 in6_ifa_put(ifp); 455 } else { 456 if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr)) 457 return; 458 src_addr = &tmpaddr; 459 } 460 461 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_ADVERTISEMENT, src_addr, daddr, --- 79 unchanged lines hidden (view full) --- 541 struct sk_buff *skb; 542 struct nd_msg *msg; 543 struct in6_addr addr_buf; 544 int len; 545 int err; 546 int send_llinfo; 547 548 if (saddr == NULL) { |
547 if (ipv6_get_lladdr(dev, &addr_buf)) | 549 if (ipv6_get_lladdr(dev, &addr_buf, 550 (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC))) |
548 return; 549 saddr = &addr_buf; 550 } 551 552 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr, 553 dev->ifindex); 554 555 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); --- 63 unchanged lines hidden (view full) --- 619{ 620 struct flowi fl; 621 struct dst_entry* dst; 622 struct inet6_dev *idev; 623 struct sock *sk = ndisc_socket->sk; 624 struct sk_buff *skb; 625 struct icmp6hdr *hdr; 626 __u8 * opt; | 551 return; 552 saddr = &addr_buf; 553 } 554 555 ndisc_flow_init(&fl, NDISC_NEIGHBOUR_SOLICITATION, saddr, daddr, 556 dev->ifindex); 557 558 dst = ndisc_dst_alloc(dev, neigh, daddr, ip6_output); --- 63 unchanged lines hidden (view full) --- 622{ 623 struct flowi fl; 624 struct dst_entry* dst; 625 struct inet6_dev *idev; 626 struct sock *sk = ndisc_socket->sk; 627 struct sk_buff *skb; 628 struct icmp6hdr *hdr; 629 __u8 * opt; |
630 struct inet6_ifaddr *ifp; 631 int send_sllao = dev->addr_len; |
|
627 int len; 628 int err; 629 | 632 int len; 633 int err; 634 |
635 636#ifdef CONFIG_IPV6_OPTIMISTIC_DAD 637 /* 638 * According to section 2.2 of RFC 4429, we must not 639 * send router solicitations with a sllao from 640 * optimistic addresses, but we may send the solicitation 641 * if we don't include the sllao. So here we check 642 * if our address is optimistic, and if so, we 643 * supress the inclusion of the sllao. 644 */ 645 if (send_sllao) { 646 ifp = ipv6_get_ifaddr(saddr, dev, 1); 647 if (ifp) { 648 if (ifp->flags & IFA_F_OPTIMISTIC) { 649 send_sllao=0; 650 in6_ifa_put(ifp); 651 } 652 } else { 653 send_sllao = 0; 654 } 655 } 656#endif |
|
630 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr, 631 dev->ifindex); 632 633 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output); 634 if (!dst) 635 return; 636 637 err = xfrm_lookup(&dst, &fl, NULL, 0); 638 if (err < 0) 639 return; 640 641 len = sizeof(struct icmp6hdr); | 657 ndisc_flow_init(&fl, NDISC_ROUTER_SOLICITATION, saddr, daddr, 658 dev->ifindex); 659 660 dst = ndisc_dst_alloc(dev, NULL, daddr, ip6_output); 661 if (!dst) 662 return; 663 664 err = xfrm_lookup(&dst, &fl, NULL, 0); 665 if (err < 0) 666 return; 667 668 len = sizeof(struct icmp6hdr); |
642 if (dev->addr_len) | 669 if (send_sllao) |
643 len += ndisc_opt_addr_space(dev); 644 645 skb = sock_alloc_send_skb(sk, 646 (MAX_HEADER + sizeof(struct ipv6hdr) + 647 len + LL_RESERVED_SPACE(dev)), 648 1, &err); 649 if (skb == NULL) { 650 ND_PRINTK0(KERN_ERR --- 10 unchanged lines hidden (view full) --- 661 skb->h.raw = (unsigned char*)hdr; 662 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION; 663 hdr->icmp6_code = 0; 664 hdr->icmp6_cksum = 0; 665 hdr->icmp6_unused = 0; 666 667 opt = (u8*) (hdr + 1); 668 | 670 len += ndisc_opt_addr_space(dev); 671 672 skb = sock_alloc_send_skb(sk, 673 (MAX_HEADER + sizeof(struct ipv6hdr) + 674 len + LL_RESERVED_SPACE(dev)), 675 1, &err); 676 if (skb == NULL) { 677 ND_PRINTK0(KERN_ERR --- 10 unchanged lines hidden (view full) --- 688 skb->h.raw = (unsigned char*)hdr; 689 hdr->icmp6_type = NDISC_ROUTER_SOLICITATION; 690 hdr->icmp6_code = 0; 691 hdr->icmp6_cksum = 0; 692 hdr->icmp6_unused = 0; 693 694 opt = (u8*) (hdr + 1); 695 |
669 if (dev->addr_len) | 696 if (send_sllao) |
670 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, 671 dev->addr_len, dev->type); 672 673 /* checksum */ 674 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len, 675 IPPROTO_ICMPV6, 676 csum_partial((__u8 *) hdr, len, 0)); 677 --- 115 unchanged lines hidden (view full) --- 793 "ICMPv6 NS: bad DAD packet (link-layer address option)\n"); 794 return; 795 } 796 } 797 798 inc = ipv6_addr_is_multicast(daddr); 799 800 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) { | 697 ndisc_fill_addr_option(opt, ND_OPT_SOURCE_LL_ADDR, dev->dev_addr, 698 dev->addr_len, dev->type); 699 700 /* checksum */ 701 hdr->icmp6_cksum = csum_ipv6_magic(&skb->nh.ipv6h->saddr, daddr, len, 702 IPPROTO_ICMPV6, 703 csum_partial((__u8 *) hdr, len, 0)); 704 --- 115 unchanged lines hidden (view full) --- 820 "ICMPv6 NS: bad DAD packet (link-layer address option)\n"); 821 return; 822 } 823 } 824 825 inc = ipv6_addr_is_multicast(daddr); 826 827 if ((ifp = ipv6_get_ifaddr(&msg->target, dev, 1)) != NULL) { |
801 if (ifp->flags & IFA_F_TENTATIVE) { 802 /* Address is tentative. If the source 803 is unspecified address, it is someone 804 does DAD, otherwise we ignore solicitations 805 until DAD timer expires. 806 */ 807 if (!dad) | 828 829 if (ifp->flags & (IFA_F_TENTATIVE|IFA_F_OPTIMISTIC)) { 830 if (dad) { 831 if (dev->type == ARPHRD_IEEE802_TR) { 832 unsigned char *sadr = skb->mac.raw; 833 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 && 834 sadr[9] == dev->dev_addr[1] && 835 sadr[10] == dev->dev_addr[2] && 836 sadr[11] == dev->dev_addr[3] && 837 sadr[12] == dev->dev_addr[4] && 838 sadr[13] == dev->dev_addr[5]) { 839 /* looped-back to us */ 840 goto out; 841 } 842 } 843 844 /* 845 * We are colliding with another node 846 * who is doing DAD 847 * so fail our DAD process 848 */ 849 addrconf_dad_failure(ifp); |
808 goto out; | 850 goto out; |
809 if (dev->type == ARPHRD_IEEE802_TR) { 810 unsigned char *sadr = skb->mac.raw; 811 if (((sadr[8] ^ dev->dev_addr[0]) & 0x7f) == 0 && 812 sadr[9] == dev->dev_addr[1] && 813 sadr[10] == dev->dev_addr[2] && 814 sadr[11] == dev->dev_addr[3] && 815 sadr[12] == dev->dev_addr[4] && 816 sadr[13] == dev->dev_addr[5]) { 817 /* looped-back to us */ | 851 } else { 852 /* 853 * This is not a dad solicitation. 854 * If we are an optimistic node, 855 * we should respond. 856 * Otherwise, we should ignore it. 857 */ 858 if (!(ifp->flags & IFA_F_OPTIMISTIC)) |
818 goto out; | 859 goto out; |
819 } | |
820 } | 860 } |
821 addrconf_dad_failure(ifp); 822 return; | |
823 } 824 825 idev = ifp->idev; 826 } else { 827 idev = in6_dev_get(dev); 828 if (!idev) { 829 /* XXX: count this drop? */ 830 return; --- 572 unchanged lines hidden (view full) --- 1403 u8 *opt; 1404 int rd_len; 1405 int err; 1406 int hlen; 1407 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; 1408 1409 dev = skb->dev; 1410 | 861 } 862 863 idev = ifp->idev; 864 } else { 865 idev = in6_dev_get(dev); 866 if (!idev) { 867 /* XXX: count this drop? */ 868 return; --- 572 unchanged lines hidden (view full) --- 1441 u8 *opt; 1442 int rd_len; 1443 int err; 1444 int hlen; 1445 u8 ha_buf[MAX_ADDR_LEN], *ha = NULL; 1446 1447 dev = skb->dev; 1448 |
1411 if (ipv6_get_lladdr(dev, &saddr_buf)) { | 1449 if (ipv6_get_lladdr(dev, &saddr_buf, IFA_F_TENTATIVE)) { |
1412 ND_PRINTK2(KERN_WARNING 1413 "ICMPv6 Redirect: no link-local address on %s\n", 1414 dev->name); 1415 return; 1416 } 1417 1418 if (!ipv6_addr_equal(&skb->nh.ipv6h->daddr, target) && 1419 !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { --- 348 unchanged lines hidden --- | 1450 ND_PRINTK2(KERN_WARNING 1451 "ICMPv6 Redirect: no link-local address on %s\n", 1452 dev->name); 1453 return; 1454 } 1455 1456 if (!ipv6_addr_equal(&skb->nh.ipv6h->daddr, target) && 1457 !(ipv6_addr_type(target) & IPV6_ADDR_LINKLOCAL)) { --- 348 unchanged lines hidden --- |