version 1.38, 2007/05/23 17:15:03 |
version 1.39.6.2, 2007/10/26 15:49:09 |
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 |
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 670 in6_addmulti(struct in6_addr *maddr6, st |
|
Line 659 in6_addmulti(struct in6_addr *maddr6, st |
|
* Ask the network driver to update its multicast reception |
* Ask the network driver to update its multicast reception |
* filter appropriately for the new address. |
* filter appropriately for the new address. |
*/ |
*/ |
memset(&ifr.ifr_addr, 0, sizeof(struct sockaddr_in6)); |
sockaddr_in6_init(&ifr.ifr_addr, maddr6, 0, 0, 0); |
ifr.ifr_addr.sin6_family = AF_INET6; |
|
ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); |
|
ifr.ifr_addr.sin6_addr = *maddr6; |
|
if (ifp->if_ioctl == NULL) |
if (ifp->if_ioctl == NULL) |
*errorp = ENXIO; /* XXX: appropriate? */ |
*errorp = ENXIO; /* XXX: appropriate? */ |
else |
else |
Line 681 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); |
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 738 in6_delmulti(struct in6_multi *in6m) |
|
* Notify the network driver to update its multicast |
* Notify the network driver to update its multicast |
* reception filter. |
* reception filter. |
*/ |
*/ |
memset(&ifr.ifr_addr, 0, sizeof(struct sockaddr_in6)); |
sockaddr_in6_init(&ifr.ifr_addr, &in6m->in6m_addr, 0, 0, 0); |
ifr.ifr_addr.sin6_family = AF_INET6; |
|
ifr.ifr_addr.sin6_len = sizeof(struct sockaddr_in6); |
|
ifr.ifr_addr.sin6_addr = in6m->in6m_addr; |
|
(*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); |