version 1.39.2.1, 2007/09/03 10:23:48 |
version 1.39.8.2, 2008/03/23 02:05:07 |
|
|
/* $NetBSD$ */ |
/* mld6.c,v 1.39.8.1 2007/11/06 23:34:07 matt 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 $ */ |
|
|
/* |
/* |
|
|
*/ |
*/ |
|
|
#include <sys/cdefs.h> |
#include <sys/cdefs.h> |
__KERNEL_RCSID(0, "$NetBSD$"); |
__KERNEL_RCSID(0, "mld6.c,v 1.39.8.1 2007/11/06 23:34:07 matt Exp"); |
|
|
#include "opt_inet.h" |
#include "opt_inet.h" |
|
|
Line 163 static struct mld_hdr * mld_allocbuf(str |
|
Line 163 static struct mld_hdr * mld_allocbuf(str |
|
static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *); |
static void mld_sendpkt(struct in6_multi *, int, const struct in6_addr *); |
static void mld_starttimer(struct in6_multi *); |
static void mld_starttimer(struct in6_multi *); |
static void mld_stoptimer(struct in6_multi *); |
static void mld_stoptimer(struct in6_multi *); |
static void mld_timeo(struct in6_multi *); |
|
static u_long mld_timerresid(struct in6_multi *); |
static u_long mld_timerresid(struct in6_multi *); |
|
|
void |
void |
mld_init() |
mld_init(void) |
{ |
{ |
static u_int8_t hbh_buf[8]; |
static u_int8_t hbh_buf[8]; |
struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; |
struct ip6_hbh *hbh = (struct ip6_hbh *)hbh_buf; |
Line 203 mld_starttimer(struct in6_multi *in6m) |
|
Line 202 mld_starttimer(struct in6_multi *in6m) |
|
} |
} |
|
|
/* start or restart the timer */ |
/* start or restart the timer */ |
callout_reset(in6m->in6m_timer_ch, in6m->in6m_timer, |
callout_schedule(&in6m->in6m_timer_ch, in6m->in6m_timer); |
(void (*) __P((void *)))mld_timeo, in6m); |
|
} |
} |
|
|
static void |
static void |
Line 213 mld_stoptimer(struct in6_multi *in6m) |
|
Line 211 mld_stoptimer(struct in6_multi *in6m) |
|
if (in6m->in6m_timer == IN6M_TIMER_UNDEF) |
if (in6m->in6m_timer == IN6M_TIMER_UNDEF) |
return; |
return; |
|
|
callout_stop(in6m->in6m_timer_ch); |
callout_stop(&in6m->in6m_timer_ch); |
|
|
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
} |
} |
|
|
static void |
static void |
mld_timeo(struct in6_multi *in6m) |
mld_timeo(void *arg) |
{ |
{ |
|
struct in6_multi *in6m = arg; |
int s = splsoftnet(); |
int s = splsoftnet(); |
|
|
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
|
|
callout_stop(in6m->in6m_timer_ch); |
|
|
|
switch (in6m->in6m_state) { |
switch (in6m->in6m_state) { |
case MLD_REPORTPENDING: |
case MLD_REPORTPENDING: |
mld_start_listening(in6m); |
mld_start_listening(in6m); |
Line 647 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 644 in6_addmulti(struct in6_addr *maddr6, st |
|
in6m->in6m_ifp = ifp; |
in6m->in6m_ifp = ifp; |
in6m->in6m_refcount = 1; |
in6m->in6m_refcount = 1; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer = IN6M_TIMER_UNDEF; |
in6m->in6m_timer_ch = |
|
malloc(sizeof(*in6m->in6m_timer_ch), M_IPMADDR, M_NOWAIT); |
|
if (in6m->in6m_timer_ch == NULL) { |
|
free(in6m, M_IPMADDR); |
|
splx(s); |
|
return (NULL); |
|
} |
|
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 678 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 667 in6_addmulti(struct in6_addr *maddr6, st |
|
(void *)&ifr); |
(void *)&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); |
return (NULL); |
return (NULL); |
} |
} |
|
|
callout_init(in6m->in6m_timer_ch, 0); |
callout_init(&in6m->in6m_timer_ch, 0); |
|
callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m); |
in6m->in6m_timer = timer; |
in6m->in6m_timer = timer; |
if (in6m->in6m_timer > 0) { |
if (in6m->in6m_timer > 0) { |
in6m->in6m_state = MLD_REPORTPENDING; |
in6m->in6m_state = MLD_REPORTPENDING; |
Line 752 in6_delmulti(struct in6_multi *in6m) |
|
Line 741 in6_delmulti(struct in6_multi *in6m) |
|
sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); |
sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); |
(*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, |
(*in6m->in6m_ifp->if_ioctl)(in6m->in6m_ifp, |
SIOCDELMULTI, (void *)&ifr); |
SIOCDELMULTI, (void *)&ifr); |
free(in6m->in6m_timer_ch, M_IPMADDR); |
callout_destroy(&in6m->in6m_timer_ch); |
free(in6m, M_IPMADDR); |
free(in6m, M_IPMADDR); |
} |
} |
splx(s); |
splx(s); |