version 1.29.2.1, 2006/09/09 02:58:55 |
version 1.36, 2006/11/29 03:05:12 |
Line 428 mld_input(m, off) |
|
Line 428 mld_input(m, off) |
|
if (ia == NULL) |
if (ia == NULL) |
break; |
break; |
|
|
for (in6m = ia->ia6_multiaddrs.lh_first; |
LIST_FOREACH(in6m, &ia->ia6_multiaddrs, in6m_entry) { |
in6m; |
|
in6m = in6m->in6m_entry.le_next) |
|
{ |
|
if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) || |
if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) || |
IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < |
IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < |
IPV6_ADDR_SCOPE_LINKLOCAL) |
IPV6_ADDR_SCOPE_LINKLOCAL) |
Line 571 mld_sendpkt(in6m, type, dst) |
|
Line 568 mld_sendpkt(in6m, type, dst) |
|
} |
} |
|
|
static struct mld_hdr * |
static struct mld_hdr * |
mld_allocbuf(mh, len, in6m, type) |
mld_allocbuf(struct mbuf **mh, int len, struct in6_multi *in6m, |
struct mbuf **mh; |
int type) |
int len; |
|
struct in6_multi *in6m; |
|
int type; |
|
{ |
{ |
struct mbuf *md; |
struct mbuf *md; |
struct mld_hdr *mldh; |
struct mld_hdr *mldh; |
Line 674 in6_addmulti(maddr6, ifp, errorp, timer) |
|
Line 668 in6_addmulti(maddr6, ifp, errorp, timer) |
|
} |
} |
IFP_TO_IA6(ifp, ia); |
IFP_TO_IA6(ifp, ia); |
if (ia == NULL) { |
if (ia == NULL) { |
|
/* leaks in6m_timer_ch */ |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
splx(s); |
splx(s); |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
*errorp = EADDRNOTAVAIL; /* appropriate? */ |
Line 698 in6_addmulti(maddr6, ifp, errorp, timer) |
|
Line 693 in6_addmulti(maddr6, ifp, errorp, timer) |
|
(caddr_t)&ifr); |
(caddr_t)&ifr); |
if (*errorp) { |
if (*errorp) { |
LIST_REMOVE(in6m, in6m_entry); |
LIST_REMOVE(in6m, in6m_entry); |
|
/* leaks in6m_timer_ch */ |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
IFAFREE(&ia->ia_ifa); |
IFAFREE(&ia->ia_ifa); |
splx(s); |
splx(s); |
Line 748 in6_delmulti(in6m) |
|
Line 744 in6_delmulti(in6m) |
|
* Unlink from list. |
* Unlink from list. |
*/ |
*/ |
LIST_REMOVE(in6m, in6m_entry); |
LIST_REMOVE(in6m, in6m_entry); |
if (in6m->in6m_ia) { |
if (in6m->in6m_ia != NULL) { |
IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ |
IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ |
|
in6m->in6m_ia = NULL; |
} |
} |
|
|
/* |
/* |
Line 758 in6_delmulti(in6m) |
|
Line 755 in6_delmulti(in6m) |
|
*/ |
*/ |
for (ia = in6_ifaddr; ia; ia = ia->ia_next) { |
for (ia = in6_ifaddr; ia; ia = ia->ia_next) { |
struct in6_multi_mship *imm; |
struct in6_multi_mship *imm; |
LIST_FOREACH(imm, &ia->ia6_memberships, |
LIST_FOREACH(imm, &ia->ia6_memberships, i6mm_chain) { |
i6mm_chain) { |
|
if (imm->i6mm_maddr == in6m) |
if (imm->i6mm_maddr == in6m) |
imm->i6mm_maddr = NULL; |
imm->i6mm_maddr = NULL; |
} |
} |
Line 799 in6_joingroup(ifp, addr, errorp, timer) |
|
Line 795 in6_joingroup(ifp, addr, errorp, timer) |
|
memset(imm, 0, sizeof(*imm)); |
memset(imm, 0, sizeof(*imm)); |
imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp, timer); |
imm->i6mm_maddr = in6_addmulti(addr, ifp, errorp, timer); |
if (!imm->i6mm_maddr) { |
if (!imm->i6mm_maddr) { |
/* *errorp is alrady set */ |
/* *errorp is already set */ |
free(imm, M_IPMADDR); |
free(imm, M_IPMADDR); |
return NULL; |
return NULL; |
} |
} |
Line 830 in6_savemkludge(oia) |
|
Line 826 in6_savemkludge(oia) |
|
struct in6_ifaddr *oia; |
struct in6_ifaddr *oia; |
{ |
{ |
struct in6_ifaddr *ia; |
struct in6_ifaddr *ia; |
struct in6_multi *in6m, *next; |
struct in6_multi *in6m; |
|
|
IFP_TO_IA6(oia->ia_ifp, ia); |
IFP_TO_IA6(oia->ia_ifp, ia); |
if (ia) { /* there is another address */ |
if (ia) { /* there is another address */ |
for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next) { |
KASSERT(ia != oia); |
next = in6m->in6m_entry.le_next; |
while ((in6m = LIST_FIRST(&oia->ia6_multiaddrs)) != NULL) { |
IFAFREE(&in6m->in6m_ia->ia_ifa); |
LIST_REMOVE(in6m, in6m_entry); |
IFAREF(&ia->ia_ifa); |
IFAREF(&ia->ia_ifa); |
|
IFAFREE(&in6m->in6m_ia->ia_ifa); |
in6m->in6m_ia = ia; |
in6m->in6m_ia = ia; |
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry); |
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry); |
} |
} |
} else { /* last address on this if deleted, save */ |
} else { /* last address on this if deleted, save */ |
struct multi6_kludge *mk; |
struct multi6_kludge *mk; |
|
|
for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) { |
LIST_FOREACH(mk, &in6_mk, mk_entry) { |
if (mk->mk_ifp == oia->ia_ifp) |
if (mk->mk_ifp == oia->ia_ifp) |
break; |
break; |
} |
} |
if (mk == NULL) /* this should not happen! */ |
if (mk == NULL) /* this should not happen! */ |
panic("in6_savemkludge: no kludge space"); |
panic("in6_savemkludge: no kludge space"); |
|
|
for (in6m = oia->ia6_multiaddrs.lh_first; in6m; in6m = next) { |
while ((in6m = LIST_FIRST(&oia->ia6_multiaddrs)) != NULL) { |
next = in6m->in6m_entry.le_next; |
LIST_REMOVE(in6m, in6m_entry); |
IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ |
IFAFREE(&in6m->in6m_ia->ia_ifa); /* release reference */ |
in6m->in6m_ia = NULL; |
in6m->in6m_ia = NULL; |
LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry); |
LIST_INSERT_HEAD(&mk->mk_head, in6m, in6m_entry); |
Line 871 in6_restoremkludge(ia, ifp) |
|
Line 868 in6_restoremkludge(ia, ifp) |
|
struct ifnet *ifp; |
struct ifnet *ifp; |
{ |
{ |
struct multi6_kludge *mk; |
struct multi6_kludge *mk; |
|
struct in6_multi *in6m; |
|
|
for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) { |
LIST_FOREACH(mk, &in6_mk, mk_entry) { |
if (mk->mk_ifp == ifp) { |
if (mk->mk_ifp == ifp) |
struct in6_multi *in6m, *next; |
|
|
|
for (in6m = mk->mk_head.lh_first; in6m; in6m = next) { |
|
next = in6m->in6m_entry.le_next; |
|
in6m->in6m_ia = ia; |
|
IFAREF(&ia->ia_ifa); |
|
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, |
|
in6m, in6m_entry); |
|
} |
|
LIST_INIT(&mk->mk_head); |
|
break; |
break; |
} |
} |
|
if (mk == NULL) |
|
return; |
|
while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL) { |
|
LIST_REMOVE(in6m, in6m_entry); |
|
in6m->in6m_ia = ia; |
|
IFAREF(&ia->ia_ifa); |
|
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry); |
} |
} |
} |
} |
|
|
Line 906 in6_createmkludge(ifp) |
|
Line 901 in6_createmkludge(ifp) |
|
{ |
{ |
struct multi6_kludge *mk; |
struct multi6_kludge *mk; |
|
|
for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) { |
LIST_FOREACH(mk, &in6_mk, mk_entry) { |
/* If we've already had one, do not allocate. */ |
/* If we've already had one, do not allocate. */ |
if (mk->mk_ifp == ifp) |
if (mk->mk_ifp == ifp) |
return; |
return; |
Line 925 in6_purgemkludge(ifp) |
|
Line 920 in6_purgemkludge(ifp) |
|
struct ifnet *ifp; |
struct ifnet *ifp; |
{ |
{ |
struct multi6_kludge *mk; |
struct multi6_kludge *mk; |
struct in6_multi *in6m; |
struct in6_multi *in6m, *next; |
|
|
for (mk = in6_mk.lh_first; mk; mk = mk->mk_entry.le_next) { |
LIST_FOREACH(mk, &in6_mk, mk_entry) { |
if (mk->mk_ifp != ifp) |
if (mk->mk_ifp == ifp) |
continue; |
break; |
|
} |
/* leave from all multicast groups joined */ |
if (mk == NULL) |
while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL) { |
return; |
in6_delmulti(in6m); |
|
} |
/* leave from all multicast groups joined */ |
LIST_REMOVE(mk, mk_entry); |
for (in6m = LIST_FIRST(&mk->mk_head); in6m != NULL; in6m = next) { |
free(mk, M_IPMADDR); |
next = LIST_NEXT(in6m, in6m_entry); |
break; |
in6_delmulti(in6m); |
} |
} |
|
LIST_REMOVE(mk, mk_entry); |
|
free(mk, M_IPMADDR); |
} |
} |