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 ---