Cosmetic: use LIST_ macros. Shorten some staircases.
Defensive programming: set an in6_multi's ifaddr reference to NULL after releasing it, to protect against reuse.
This commit is contained in:
parent
df200b9f49
commit
3df10e0d11
@ -1,4 +1,4 @@
|
|||||||
/* $NetBSD: mld6.c,v 1.34 2006/11/16 01:33:45 christos Exp $ */
|
/* $NetBSD: mld6.c,v 1.35 2006/11/20 04:26:22 dyoung Exp $ */
|
||||||
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
|
/* $KAME: mld6.c,v 1.25 2001/01/16 14:14:18 itojun Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -102,7 +102,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.34 2006/11/16 01:33:45 christos Exp $");
|
__KERNEL_RCSID(0, "$NetBSD: mld6.c,v 1.35 2006/11/20 04:26:22 dyoung Exp $");
|
||||||
|
|
||||||
#include "opt_inet.h"
|
#include "opt_inet.h"
|
||||||
|
|
||||||
@ -428,10 +428,7 @@ 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)
|
||||||
@ -745,8 +742,9 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -755,8 +753,7 @@ 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;
|
||||||
}
|
}
|
||||||
@ -831,8 +828,10 @@ in6_savemkludge(oia)
|
|||||||
|
|
||||||
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) {
|
for (in6m = LIST_FIRST(&oia->ia6_multiaddrs);
|
||||||
next = in6m->in6m_entry.le_next;
|
in6m != NULL;
|
||||||
|
in6m = next) {
|
||||||
|
next = LIST_NEXT(in6m, in6m_entry);
|
||||||
IFAFREE(&in6m->in6m_ia->ia_ifa);
|
IFAFREE(&in6m->in6m_ia->ia_ifa);
|
||||||
IFAREF(&ia->ia_ifa);
|
IFAREF(&ia->ia_ifa);
|
||||||
in6m->in6m_ia = ia;
|
in6m->in6m_ia = ia;
|
||||||
@ -841,15 +840,17 @@ in6_savemkludge(oia)
|
|||||||
} 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) {
|
for (in6m = LIST_FIRST(&oia->ia6_multiaddrs);
|
||||||
next = in6m->in6m_entry.le_next;
|
in6m != NULL;
|
||||||
|
in6m = next) {
|
||||||
|
next = LIST_NEXT(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);
|
||||||
@ -868,22 +869,21 @@ in6_restoremkludge(ia, ifp)
|
|||||||
struct ifnet *ifp;
|
struct ifnet *ifp;
|
||||||
{
|
{
|
||||||
struct multi6_kludge *mk;
|
struct multi6_kludge *mk;
|
||||||
|
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)
|
||||||
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;
|
||||||
|
for (in6m = LIST_FIRST(&mk->mk_head); in6m != NULL; in6m = next) {
|
||||||
|
next = LIST_NEXT(in6m, in6m_entry);
|
||||||
|
in6m->in6m_ia = ia;
|
||||||
|
IFAREF(&ia->ia_ifa);
|
||||||
|
LIST_INSERT_HEAD(&ia->ia6_multiaddrs, in6m, in6m_entry);
|
||||||
|
}
|
||||||
|
LIST_INIT(&mk->mk_head);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -903,7 +903,7 @@ 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;
|
||||||
@ -924,16 +924,17 @@ in6_purgemkludge(ifp)
|
|||||||
struct multi6_kludge *mk;
|
struct multi6_kludge *mk;
|
||||||
struct in6_multi *in6m;
|
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)
|
||||||
continue;
|
break;
|
||||||
|
|
||||||
/* leave from all multicast groups joined */
|
|
||||||
while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL) {
|
|
||||||
in6_delmulti(in6m);
|
|
||||||
}
|
|
||||||
LIST_REMOVE(mk, mk_entry);
|
|
||||||
free(mk, M_IPMADDR);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
if (mk == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* leave from all multicast groups joined */
|
||||||
|
while ((in6m = LIST_FIRST(&mk->mk_head)) != NULL) {
|
||||||
|
in6_delmulti(in6m);
|
||||||
|
}
|
||||||
|
LIST_REMOVE(mk, mk_entry);
|
||||||
|
free(mk, M_IPMADDR);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user