Lines Matching refs:in6m

189 mld_starttimer(struct in6_multi *in6m)
194 KASSERTMSG(in6m->in6m_timer != IN6M_TIMER_UNDEF,
195 "in6m_timer=%d", in6m->in6m_timer);
198 in6m->in6m_timer_expire.tv_sec = now.tv_sec + in6m->in6m_timer / hz;
199 in6m->in6m_timer_expire.tv_usec = now.tv_usec +
200 (in6m->in6m_timer % hz) * (1000000 / hz);
201 if (in6m->in6m_timer_expire.tv_usec > 1000000) {
202 in6m->in6m_timer_expire.tv_sec++;
203 in6m->in6m_timer_expire.tv_usec -= 1000000;
207 callout_schedule(&in6m->in6m_timer_ch, in6m->in6m_timer);
212 * The caller must ensure in6m won't be freed while releasing the lock.
215 mld_stoptimer(struct in6_multi *in6m)
220 if (in6m->in6m_timer == IN6M_TIMER_UNDEF)
225 callout_halt(&in6m->in6m_timer_ch, NULL);
229 in6m->in6m_timer = IN6M_TIMER_UNDEF;
235 struct in6_multi *in6m = arg;
237 KASSERTMSG(in6m->in6m_refcount > 0, "in6m_refcount=%d",
238 in6m->in6m_refcount);
242 if (in6m->in6m_timer == IN6M_TIMER_UNDEF)
245 in6m->in6m_timer = IN6M_TIMER_UNDEF;
247 switch (in6m->in6m_state) {
249 mld_start_listening(in6m);
252 mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);
262 mld_timerresid(struct in6_multi *in6m)
268 if (now.tv_sec > in6m->in6m_timer_expire.tv_sec ||
269 (now.tv_sec == in6m->in6m_timer_expire.tv_sec &&
270 now.tv_usec > in6m->in6m_timer_expire.tv_usec)) {
273 diff = in6m->in6m_timer_expire;
286 mld_start_listening(struct in6_multi *in6m)
300 if (in6_setscope(&all_in6, in6m->in6m_ifp, NULL)) {
302 in6m->in6m_timer = 0;
303 in6m->in6m_state = MLD_OTHERLISTENER;
305 if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||
306 IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) < IPV6_ADDR_SCOPE_LINKLOCAL) {
307 in6m->in6m_timer = IN6M_TIMER_UNDEF;
308 in6m->in6m_state = MLD_OTHERLISTENER;
310 mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);
311 in6m->in6m_timer = cprng_fast32() %
313 in6m->in6m_state = MLD_IREPORTEDLAST;
315 mld_starttimer(in6m);
320 mld_stop_listening(struct in6_multi *in6m)
327 if (in6_setscope(&allnode, in6m->in6m_ifp, NULL)) {
332 if (in6_setscope(&allrouter, in6m->in6m_ifp, NULL)) {
337 if (in6m->in6m_state == MLD_IREPORTEDLAST &&
338 (!IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &allnode)) &&
339 IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) >
341 mld_sendpkt(in6m, MLD_LISTENER_DONE, &allrouter);
351 struct in6_multi *in6m = NULL;
412 * In Delaying Listener state, our timer is running (in6m->in6m_timer)
414 * (in6m->in6m_timer==IN6M_TIMER_UNDEF)
416 * The flag is in6m->in6m_state, it is set to MLD_OTHERLISTENER if
452 * temporarily, so we have to prevent in6m from being freed
459 LIST_FOREACH_SAFE(in6m, &ifp->if_multiaddrs, in6m_entry, next) {
460 if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, &all_in6) ||
461 IPV6_ADDR_MC_SCOPE(&in6m->in6m_addr) <
465 if (in6m->in6m_state == MLD_REPORTPENDING)
469 !IN6_ARE_ADDR_EQUAL(&mld_addr, &in6m->in6m_addr))
473 in6m_ref(in6m);
476 mld_stoptimer(in6m);
477 mld_sendpkt(in6m, MLD_LISTENER_REPORT, NULL);
478 in6m->in6m_state = MLD_IREPORTEDLAST;
480 in6m_unref(in6m); /* May free in6m */
481 } else if (in6m->in6m_timer == IN6M_TIMER_UNDEF ||
482 mld_timerresid(in6m) > timer) {
483 in6m->in6m_timer =
485 mld_starttimer(in6m);
513 in6m = in6_lookup_multi(&mld_addr, ifp);
514 if (in6m) {
515 in6m_ref(in6m);
516 mld_stoptimer(in6m); /* transit to idle state */
517 in6m->in6m_state = MLD_OTHERLISTENER; /* clear flag */
518 in6m_unref(in6m);
519 in6m = NULL; /* in6m might be freed */
547 mld_sendpkt(struct in6_multi *in6m, int type, const struct in6_addr *dst)
554 struct ifnet *ifp = in6m->in6m_ifp;
580 mldh = mld_allocbuf(&mh, in6m, type);
590 ip6->ip6_dst = dst ? *dst : in6m->in6m_addr;
594 mldh->mld_addr = in6m->in6m_addr;
635 mld_allocbuf(struct mbuf **mh, struct in6_multi *in6m, int type)
683 in6m_ref(struct in6_multi *in6m)
687 in6m->in6m_refcount++;
691 in6m_unref(struct in6_multi *in6m)
695 if (--in6m->in6m_refcount == 0)
696 in6m_destroy(in6m);
707 struct in6_multi *in6m;
715 in6m = in6_lookup_multi(maddr6, ifp);
716 if (in6m != NULL) {
720 in6m->in6m_refcount++;
726 in6m = malloc(sizeof(*in6m), M_IPMADDR, M_NOWAIT|M_ZERO);
727 if (in6m == NULL) {
732 in6m->in6m_addr = *maddr6;
733 in6m->in6m_ifp = ifp;
734 in6m->in6m_refcount = 1;
735 in6m->in6m_timer = IN6M_TIMER_UNDEF;
736 callout_init(&in6m->in6m_timer_ch, CALLOUT_MPSAFE);
737 callout_setfunc(&in6m->in6m_timer_ch, mld_timeo, in6m);
739 LIST_INSERT_HEAD(&ifp->if_multiaddrs, in6m, in6m_entry);
748 callout_destroy(&in6m->in6m_timer_ch);
749 LIST_REMOVE(in6m, in6m_entry);
750 free(in6m, M_IPMADDR);
751 in6m = NULL;
755 in6m->in6m_timer = timer;
756 if (in6m->in6m_timer > 0) {
757 in6m->in6m_state = MLD_REPORTPENDING;
758 mld_starttimer(in6m);
766 mld_start_listening(in6m);
770 return in6m;
774 in6m_destroy(struct in6_multi *in6m)
779 KASSERTMSG(in6m->in6m_refcount == 0, "in6m_refcount=%d",
780 in6m->in6m_refcount);
785 * someone to look up the removing in6m from the list and add a
788 if (in6_lookup_multi(&in6m->in6m_addr, in6m->in6m_ifp) != NULL)
789 LIST_REMOVE(in6m, in6m_entry);
795 mld_stop_listening(in6m);
801 in6_purge_mcast_references(in6m);
807 sockaddr_in6_init(&sin6, &in6m->in6m_addr, 0, 0, 0);
808 if_mcast_op(in6m->in6m_ifp, SIOCDELMULTI, sin6tosa(&sin6));
811 in6m->in6m_timer = IN6M_TIMER_UNDEF;
814 callout_halt(&in6m->in6m_timer_ch, NULL);
815 callout_destroy(&in6m->in6m_timer_ch);
817 free(in6m, M_IPMADDR);
825 in6_delmulti_locked(struct in6_multi *in6m)
829 KASSERTMSG(in6m->in6m_refcount > 0, "in6m_refcount=%d",
830 in6m->in6m_refcount);
833 * The caller should have a reference to in6m. So we don't need to care
836 mld_stoptimer(in6m);
837 if (--in6m->in6m_refcount == 0)
838 in6m_destroy(in6m);
842 in6_delmulti(struct in6_multi *in6m)
846 in6_delmulti_locked(in6m);
852 * on a given interface. If no matching record is found, "in6m"
858 struct in6_multi *in6m;
862 LIST_FOREACH(in6m, &ifp->if_multiaddrs, in6m_entry) {
863 if (IN6_ARE_ADDR_EQUAL(&in6m->in6m_addr, addr))
866 return in6m;
873 struct in6_multi *in6m;
876 in6m = in6_lookup_multi(addr, ifp);
877 if (in6m != NULL)
878 in6_delmulti_locked(in6m);
900 struct in6_multi *in6m, *next;
903 LIST_FOREACH_SAFE(in6m, &ifp->if_multiaddrs, in6m_entry, next) {
904 LIST_REMOVE(in6m, in6m_entry);
909 * accessed via in6m by removing it from the list of ifp.
911 mld_stoptimer(in6m);
967 struct in6_multi *in6m;
970 in6m = imm->i6mm_maddr;
972 if (in6m != NULL) {
973 in6_delmulti_locked(in6m);
999 struct in6_multi *in6m;
1023 LIST_FOREACH(in6m, &ifp->if_multiaddrs, in6m_entry) {
1046 LIST_FOREACH(in6m, &ifp->if_multiaddrs, in6m_entry) {
1062 error = sysctl_copyout(l, &in6m->in6m_addr,
1068 tmp = in6m->in6m_refcount;