| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: mld6.c,v 1.50 2009/04/18 14:58:05 tsutsui Exp $ */ | | 1 | /* $NetBSD: mld6.c,v 1.51 2009/08/04 22:04:23 dyoung Exp $ */ |
2 | /* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */ | | 2 | /* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (C) 1998 WIDE Project. | | 5 | * Copyright (C) 1998 WIDE Project. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -92,27 +92,27 @@ | | | @@ -92,27 +92,27 @@ |
92 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | | 92 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
93 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | | 93 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
94 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 94 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
95 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 95 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
96 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 96 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
97 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 97 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
98 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 98 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
99 | * SUCH DAMAGE. | | 99 | * SUCH DAMAGE. |
100 | * | | 100 | * |
101 | * @(#)igmp.c 8.1 (Berkeley) 7/19/93 | | 101 | * @(#)igmp.c 8.1 (Berkeley) 7/19/93 |
102 | */ | | 102 | */ |
103 | | | 103 | |
104 | #include <sys/cdefs.h> | | 104 | #include <sys/cdefs.h> |
105 | __KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.50 2009/04/18 14:58:05 tsutsui Exp $"); | | 105 | __KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.51 2009/08/04 22:04:23 dyoung Exp $"); |
106 | | | 106 | |
107 | #include "opt_inet.h" | | 107 | #include "opt_inet.h" |
108 | | | 108 | |
109 | #include <sys/param.h> | | 109 | #include <sys/param.h> |
110 | #include <sys/systm.h> | | 110 | #include <sys/systm.h> |
111 | #include <sys/mbuf.h> | | 111 | #include <sys/mbuf.h> |
112 | #include <sys/socket.h> | | 112 | #include <sys/socket.h> |
113 | #include <sys/socketvar.h> | | 113 | #include <sys/socketvar.h> |
114 | #include <sys/protosw.h> | | 114 | #include <sys/protosw.h> |
115 | #include <sys/syslog.h> | | 115 | #include <sys/syslog.h> |
116 | #include <sys/sysctl.h> | | 116 | #include <sys/sysctl.h> |
117 | #include <sys/kernel.h> | | 117 | #include <sys/kernel.h> |
118 | #include <sys/callout.h> | | 118 | #include <sys/callout.h> |
| @@ -627,34 +627,33 @@ in6_addmulti(struct in6_addr *maddr6, st | | | @@ -627,34 +627,33 @@ in6_addmulti(struct in6_addr *maddr6, st |
627 | */ | | 627 | */ |
628 | IN6_LOOKUP_MULTI(*maddr6, ifp, in6m); | | 628 | IN6_LOOKUP_MULTI(*maddr6, ifp, in6m); |
629 | if (in6m != NULL) { | | 629 | if (in6m != NULL) { |
630 | /* | | 630 | /* |
631 | * Found it; just increment the refrence count. | | 631 | * Found it; just increment the refrence count. |
632 | */ | | 632 | */ |
633 | in6m->in6m_refcount++; | | 633 | in6m->in6m_refcount++; |
634 | } else { | | 634 | } else { |
635 | /* | | 635 | /* |
636 | * New address; allocate a new multicast record | | 636 | * New address; allocate a new multicast record |
637 | * and link it into the interface's multicast list. | | 637 | * and link it into the interface's multicast list. |
638 | */ | | 638 | */ |
639 | in6m = (struct in6_multi *) | | 639 | in6m = (struct in6_multi *) |
640 | malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT); | | 640 | malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT|M_ZERO); |
641 | if (in6m == NULL) { | | 641 | if (in6m == NULL) { |
642 | splx(s); | | 642 | splx(s); |
643 | *errorp = ENOBUFS; | | 643 | *errorp = ENOBUFS; |
644 | return (NULL); | | 644 | return (NULL); |
645 | } | | 645 | } |
646 | | | 646 | |
647 | memset(in6m, 0, sizeof(*in6m)); | | | |
648 | in6m->in6m_addr = *maddr6; | | 647 | in6m->in6m_addr = *maddr6; |
649 | in6m->in6m_ifp = ifp; | | 648 | in6m->in6m_ifp = ifp; |
650 | in6m->in6m_refcount = 1; | | 649 | in6m->in6m_refcount = 1; |
651 | in6m->in6m_timer = IN6M_TIMER_UNDEF; | | 650 | in6m->in6m_timer = IN6M_TIMER_UNDEF; |
652 | IFP_TO_IA6(ifp, ia); | | 651 | IFP_TO_IA6(ifp, ia); |
653 | if (ia == NULL) { | | 652 | if (ia == NULL) { |
654 | free(in6m, M_IPMADDR); | | 653 | free(in6m, M_IPMADDR); |
655 | splx(s); | | 654 | splx(s); |
656 | *errorp = EADDRNOTAVAIL; /* appropriate? */ | | 655 | *errorp = EADDRNOTAVAIL; /* appropriate? */ |
657 | return (NULL); | | 656 | return (NULL); |
658 | } | | 657 | } |
659 | in6m->in6m_ia = ia; | | 658 | in6m->in6m_ia = ia; |
660 | IFAREF(&ia->ia_ifa); /* gain a reference */ | | 659 | IFAREF(&ia->ia_ifa); /* gain a reference */ |
| @@ -744,33 +743,32 @@ in6_delmulti(struct in6_multi *in6m) | | | @@ -744,33 +743,32 @@ in6_delmulti(struct in6_multi *in6m) |
744 | callout_destroy(&in6m->in6m_timer_ch); | | 743 | callout_destroy(&in6m->in6m_timer_ch); |
745 | free(in6m, M_IPMADDR); | | 744 | free(in6m, M_IPMADDR); |
746 | } | | 745 | } |
747 | splx(s); | | 746 | splx(s); |
748 | } | | 747 | } |
749 | | | 748 | |
750 | | | 749 | |
751 | struct in6_multi_mship * | | 750 | struct in6_multi_mship * |
752 | in6_joingroup(struct ifnet *ifp, struct in6_addr *addr, | | 751 | in6_joingroup(struct ifnet *ifp, struct in6_addr *addr, |
753 | int *errorp, int timer) | | 752 | int *errorp, int timer) |
754 | { | | 753 | { |
755 | struct in6_multi_mship *imm; | | 754 | struct in6_multi_mship *imm; |
756 | | | 755 | |
757 | imm = malloc(sizeof(*imm), M_IPMADDR, M_NOWAIT); | | 756 | imm = malloc(sizeof(*imm), M_IPMADDR, M_NOWAIT|M_ZERO); |
758 | if (!imm) { | | 757 | if (imm == NULL) { |
759 | *errorp = ENOBUFS; | | 758 | *errorp = ENOBUFS; |
760 | return NULL; | | 759 | return NULL; |
761 | } | | 760 | } |
762 | | | 761 | |
763 | memset(imm, 0, sizeof(*imm)); | | | |
764 | imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp, timer); | | 762 | imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp, timer); |
765 | if (!imm->i6mm_maddr) { | | 763 | if (!imm->i6mm_maddr) { |
766 | /* *errorp is already set */ | | 764 | /* *errorp is already set */ |
767 | free(imm, M_IPMADDR); | | 765 | free(imm, M_IPMADDR); |
768 | return NULL; | | 766 | return NULL; |
769 | } | | 767 | } |
770 | return imm; | | 768 | return imm; |
771 | } | | 769 | } |
772 | | | 770 | |
773 | int | | 771 | int |
774 | in6_leavegroup(struct in6_multi_mship *imm) | | 772 | in6_leavegroup(struct in6_multi_mship *imm) |
775 | { | | 773 | { |
776 | | | 774 | |
| @@ -860,29 +858,28 @@ in6_restoremkludge(struct in6_ifaddr *ia | | | @@ -860,29 +858,28 @@ in6_restoremkludge(struct in6_ifaddr *ia |
860 | * it is a global function. | | 858 | * it is a global function. |
861 | */ | | 859 | */ |
862 | void | | 860 | void |
863 | in6_createmkludge(struct ifnet *ifp) | | 861 | in6_createmkludge(struct ifnet *ifp) |
864 | { | | 862 | { |
865 | struct multi6_kludge *mk; | | 863 | struct multi6_kludge *mk; |
866 | | | 864 | |
867 | LIST_FOREACH(mk, &in6_mk, mk_entry) { | | 865 | LIST_FOREACH(mk, &in6_mk, mk_entry) { |
868 | /* If we've already had one, do not allocate. */ | | 866 | /* If we've already had one, do not allocate. */ |
869 | if (mk->mk_ifp == ifp) | | 867 | if (mk->mk_ifp == ifp) |
870 | return; | | 868 | return; |
871 | } | | 869 | } |
872 | | | 870 | |
873 | mk = malloc(sizeof(*mk), M_IPMADDR, M_WAITOK); | | 871 | mk = malloc(sizeof(*mk), M_IPMADDR, M_ZERO|M_WAITOK); |
874 | | | 872 | |
875 | memset(mk, 0, sizeof(*mk)); | | | |
876 | LIST_INIT(&mk->mk_head); | | 873 | LIST_INIT(&mk->mk_head); |
877 | mk->mk_ifp = ifp; | | 874 | mk->mk_ifp = ifp; |
878 | LIST_INSERT_HEAD(&in6_mk, mk, mk_entry); | | 875 | LIST_INSERT_HEAD(&in6_mk, mk, mk_entry); |
879 | } | | 876 | } |
880 | | | 877 | |
881 | void | | 878 | void |
882 | in6_purgemkludge(struct ifnet *ifp) | | 879 | in6_purgemkludge(struct ifnet *ifp) |
883 | { | | 880 | { |
884 | struct multi6_kludge *mk; | | 881 | struct multi6_kludge *mk; |
885 | struct in6_multi *in6m, *next; | | 882 | struct in6_multi *in6m, *next; |
886 | | | 883 | |
887 | LIST_FOREACH(mk, &in6_mk, mk_entry) { | | 884 | LIST_FOREACH(mk, &in6_mk, mk_entry) { |
888 | if (mk->mk_ifp == ifp) | | 885 | if (mk->mk_ifp == ifp) |