Lines Matching defs:ilm

65 static void	ilm_gen_filter(ilm_t *ilm, mcast_record_t *fmode,
71 static void ilm_delete(ilm_t *ilm);
107 * Multicast joins operate on both the ilg and ilm structures. Multiple
112 * ilm simulatenously and need to synchronize on the access to the ilm.
113 * The access and lookup of the ilm, as well as other ill multicast state,
121 * An ilm is an IP data structure used to track multicast join/leave.
122 * An ilm is associated with a <multicast group, ipif> tuple in IPv4 and
124 * referencing the ilm.
125 * The modifications and lookup of ilm entries is serialized using the
127 * of the ilm state.
132 * of threads holding reference to an ilm.
134 * In the cases where we serially access the ilg and ilm, which happens when
138 * the same socket always results in a consistent order for the ilg and ilm
274 ilm_t *ilm = fbld->fbld_ilm;
275 in6_addr_t *v6group = &ilm->ilm_v6addr;
291 * ilm (group, interface match). If so, update the master
298 ASSERT(MUTEX_HELD(&ilm->ilm_ill->ill_mcast_serializer));
307 * that any ilg+ilm operations on this ilm have either
313 if ((ilg->ilg_ill == ilm->ilm_ill) &&
352 ilm_gen_filter(ilm_t *ilm, mcast_record_t *fmode, slist_t *flist)
355 ip_stack_t *ipst = ilm->ilm_ipst;
357 fbld.fbld_ilm = ilm;
400 ilm_update_add(ilm_t *ilm, ilg_stat_t ilgstat, slist_t *ilg_flist)
406 ill_t *ill = ilm->ilm_ill;
409 * There are several cases where the ilm's filter state
415 fdefault = (ilm->ilm_no_ilg_cnt > 0) ||
421 if (!fdefault && ilm->ilm_filter == NULL) {
422 ilm->ilm_filter = l_alloc();
423 if (ilm->ilm_filter == NULL) {
430 ilm->ilm_refcnt++;
433 ilm->ilm_no_ilg_cnt++;
439 * ilm filter.
445 ilm_gen_filter(ilm, &fmode, flist);
449 if ((ilm->ilm_fmode == fmode) &&
450 !lists_are_different(ilm->ilm_filter, flist)) {
458 mld_statechange(ilm, fmode, flist);
460 igmp_statechange(ilm, fmode, flist);
463 /* update the ilm state */
464 ilm->ilm_fmode = fmode;
466 l_copy(flist, ilm->ilm_filter);
468 CLEAR_SLIST(ilm->ilm_filter);
470 ip1dbg(("ilm_update: new if filter mode %d, group %s\n", ilm->ilm_fmode,
471 inet_ntop(AF_INET6, &ilm->ilm_v6addr, buf, sizeof (buf))));
481 ilm_update_del(ilm_t *ilm)
485 ill_t *ill = ilm->ilm_ill;
488 ilm->ilm_refcnt));
496 * now is walk the list to update the ilm filter state.
501 if (ilm->ilm_no_ilg_cnt != 0) {
505 ilm_gen_filter(ilm, &fmode, flist);
509 if ((ilm->ilm_fmode == fmode) &&
510 (!lists_are_different(ilm->ilm_filter, flist))) {
517 mld_statechange(ilm, fmode, flist);
519 igmp_statechange(ilm, fmode, flist);
522 ilm->ilm_fmode = fmode;
524 if (ilm->ilm_filter == NULL) {
525 ilm->ilm_filter = l_alloc();
526 if (ilm->ilm_filter == NULL) {
528 ip1dbg(("ilm_update_del: failed to alloc ilm "
530 inet_ntop(AF_INET6, &ilm->ilm_v6addr,
532 ilm->ilm_fmode = MODE_IS_EXCLUDE;
537 l_copy(flist, ilm->ilm_filter);
539 CLEAR_SLIST(ilm->ilm_filter);
547 * Create/update the ilm for the group/ill. Used by other parts of IP to
549 * Returns with a refhold on the ilm.
560 ilm_t *ilm;
564 ilm = ip_addmulti_serial(v6group, ill, zoneid, ILGSTAT_NONE,
573 return (ilm);
577 * Create/update the ilm for the group/ill. If ILGSTAT_CHANGE is not set
578 * then this returns with a refhold on the ilm.
599 ilm_t *ilm;
642 ilm = ip_addmulti_impl(v6group, ill, zoneid, ilgstat, ilg_fmode,
647 return (ilm);
655 ilm_t *ilm;
662 * An ilm is uniquely identified by the tuple of (group, ill) where
667 ilm = ilm_lookup(ill, v6group, zoneid);
668 if (ilm != NULL) {
670 ret = ilm_update_add(ilm, ilgstat, ilg_flist);
672 return (ilm);
679 * The callers checks on the ilg and the ilg+ilm consistency under
681 * and no ilm.
684 ilm = ilm_add(ill, v6group, ilgstat, ilg_fmode, ilg_flist, zoneid);
685 if (ilm == NULL) {
701 mld_joingroup(ilm);
703 igmp_joingroup(ilm);
719 inet_ntop(AF_INET6, &ilm->ilm_v6addr,
722 ilm_delete(ilm);
726 return (ilm);
908 * Delete the ilm. Used by other parts of IP for the case of no_ilg/leaving
912 ip_delmulti(ilm_t *ilm)
914 ill_t *ill = ilm->ilm_ill;
919 error = ip_delmulti_serial(ilm, B_TRUE, B_TRUE);
932 * Delete the ilm.
938 ip_delmulti_serial(ilm_t *ilm, boolean_t no_ilg, boolean_t leaving)
940 ill_t *ill = ilm->ilm_ill;
947 ret = ip_delmulti_impl(ilm, no_ilg, leaving);
954 ip_delmulti_impl(ilm_t *ilm, boolean_t no_ilg, boolean_t leaving)
956 ill_t *ill = ilm->ilm_ill;
964 ilm->ilm_no_ilg_cnt--;
967 ilm->ilm_refcnt--;
969 if (ilm->ilm_refcnt > 0)
970 return (ilm_update_del(ilm));
972 v6group = ilm->ilm_v6addr;
974 if (IN6_IS_ADDR_UNSPECIFIED(&ilm->ilm_v6addr)) {
975 ilm_delete(ilm);
990 mld_leavegroup(ilm);
992 igmp_leavegroup(ilm);
995 ilm_delete(ilm);
1150 ilm_t *ilm;
1177 ilm = ip_addmulti(&ipv6_all_zeros, ill, ill->ill_zoneid, &ret);
1178 if (ilm == NULL) {
1187 (void) ip_delmulti(ilm);
1192 ill->ill_ipallmulti_ilm = ilm;
1204 ilm_t *ilm;
1224 ilm = ill->ill_ipallmulti_ilm;
1227 ilm = NULL;
1230 if (ilm != NULL)
1231 (void) ip_delmulti(ilm);
1245 ilm_t *ilm;
1250 ilm = ill->ill_ipallmulti_ilm;
1255 if (ilm != NULL)
1256 (void) ip_delmulti(ilm);
1345 * change is invisible to the ilm. Other interface changes are handled
1351 ilm_t *ilm;
1357 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1359 * If we have more then one ilm for the group (e.g., with
1361 * to join unless this is the first ilm for the group.
1363 if (ilm_numentries(ill, &ilm->ilm_v6addr) > 1 &&
1364 ilm_lookup(ill, &ilm->ilm_v6addr, ALL_ZONES) != ilm) {
1369 &ilm->ilm_v6addr, addrbuf, sizeof (addrbuf))));
1371 if (IN6_IS_ADDR_UNSPECIFIED(&ilm->ilm_v6addr)) {
1375 mld_joingroup(ilm);
1377 igmp_joingroup(ilm);
1379 (void) ip_ll_multireq(ill, &ilm->ilm_v6addr,
1395 * change is invisible to the ilm. Other interface changes are handled
1401 ilm_t *ilm;
1407 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1409 * If we have more then one ilm for the group (e.g., with
1411 * to leave unless this is the first ilm for the group.
1413 if (ilm_numentries(ill, &ilm->ilm_v6addr) > 1 &&
1414 ilm_lookup(ill, &ilm->ilm_v6addr, ALL_ZONES) != ilm) {
1419 &ilm->ilm_v6addr, addrbuf, sizeof (addrbuf))));
1421 if (IN6_IS_ADDR_UNSPECIFIED(&ilm->ilm_v6addr)) {
1425 mld_leavegroup(ilm);
1427 igmp_leavegroup(ilm);
1429 (void) ip_ll_multireq(ill, &ilm->ilm_v6addr,
1447 ilm_t *ilm;
1450 ilm = ilm_lookup(ill, v6group, ALL_ZONES);
1452 return (ilm != NULL);
1479 ilm_t *ilm;
1482 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1483 if (IN6_ARE_ADDR_EQUAL(&ilm->ilm_v6addr, v6group) &&
1484 ilm->ilm_zoneid != skipzone) {
1524 ilm_t *ilm;
1527 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1528 if (IN6_ARE_ADDR_EQUAL(&ilm->ilm_v6addr, v6group) &&
1529 ilm->ilm_zoneid > zoneid) {
1530 zoneid = ilm->ilm_zoneid;
1558 * Find an ilm matching the ill, group, and zoneid.
1563 ilm_t *ilm;
1567 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1568 if (!IN6_ARE_ADDR_EQUAL(&ilm->ilm_v6addr, v6group))
1570 if (zoneid != ALL_ZONES && zoneid != ilm->ilm_zoneid)
1573 ASSERT(ilm->ilm_ill == ill);
1574 return (ilm);
1581 * Since each shared-IP zone has a separate ilm for the same group/ill
1587 ilm_t *ilm;
1591 for (ilm = ill->ill_ilm; ilm; ilm = ilm->ilm_next) {
1592 if (IN6_ARE_ADDR_EQUAL(&ilm->ilm_v6addr, v6group)) {
1604 ilm_t *ilm;
1609 ilm = GETSTRUCT(ilm_t, 1);
1610 if (ilm == NULL)
1613 ilm->ilm_filter = l_alloc();
1614 if (ilm->ilm_filter == NULL) {
1615 mi_free(ilm);
1619 ilm->ilm_v6addr = *v6group;
1620 ilm->ilm_refcnt = 1;
1621 ilm->ilm_zoneid = zoneid;
1622 ilm->ilm_timer = INFINITY;
1623 ilm->ilm_rtx.rtx_timer = INFINITY;
1625 ilm->ilm_ill = ill;
1627 (char *), "ilm", (void *), ilm);
1631 ilm->ilm_ipst = ill->ill_ipst; /* No netstack_hold */
1641 while (ilm_cur != NULL && ilm_cur->ilm_zoneid < ilm->ilm_zoneid) {
1645 ilm->ilm_next = ilm_cur;
1646 *ilm_ptpn = ilm;
1654 l_copy(ilg_flist, ilm->ilm_filter);
1655 ilm->ilm_fmode = ilg_fmode;
1657 ilm->ilm_no_ilg_cnt = 1;
1658 ilm->ilm_fmode = MODE_IS_EXCLUDE;
1661 return (ilm);
1665 ilm_inactive(ilm_t *ilm)
1667 FREE_SLIST(ilm->ilm_filter);
1668 FREE_SLIST(ilm->ilm_pendsrcs);
1669 FREE_SLIST(ilm->ilm_rtx.rtx_allow);
1670 FREE_SLIST(ilm->ilm_rtx.rtx_block);
1671 ilm->ilm_ipst = NULL;
1672 mi_free((char *)ilm);
1676 * Unlink ilm and free it.
1679 ilm_delete(ilm_t *ilm)
1681 ill_t *ill = ilm->ilm_ill;
1691 for (ilmp = &ill->ill_ilm; *ilmp != ilm; ilmp = &(*ilmp)->ilm_next)
1694 *ilmp = ilm->ilm_next;
1704 (char *), "ilm", (void *), ilm);
1710 ilm_inactive(ilm); /* frees this ilm */
1933 ilm_t *ilm;
2000 ilm = ilg->ilg_ilm;
2005 if (ilm != NULL)
2006 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);
2098 ilm = ip_addmulti_serial(group, ill, connp->conn_zoneid, ilgstat,
2111 if (ilm != NULL) {
2112 (void) ip_delmulti_serial(ilm, B_FALSE,
2119 if (ilm != NULL) {
2123 (void) ip_delmulti_serial(ilm, B_FALSE,
2128 /* Succeeded. Update the ilg to point at the ilm */
2131 ilg->ilg_ilm = ilm;
2132 ilm->ilm_ifaddr = ifaddr; /* For netstat */
2136 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);
2142 * ip_addmulti didn't get a held ilm for
2145 ASSERT(ilg->ilg_ilm == ilm);
2150 * Failed to allocate the ilm.
2524 ilm_t *ilm;
2595 ilm = ilg->ilg_ilm;
2604 if (ilm != NULL) {
2606 (void) ip_delmulti_serial(ilm, B_FALSE, leaving);
2704 ilm_t *ilm;
2814 ilm = ip_addmulti_serial(v6group, ill, connp->conn_zoneid, ilgstat,
2827 if (ilm != NULL) {
2828 (void) ip_delmulti_serial(ilm, B_FALSE,
2834 if (ilm != NULL) {
2838 (void) ip_delmulti_serial(ilm, B_FALSE,
2843 /* Succeeded. Update the ilg to point at the ilm */
2846 ilg->ilg_ilm = ilm;
2847 ilm->ilm_ifaddr = ifaddr; /* For netstat */
2851 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);
2857 * ip_addmulti didn't get a held ilm for
2860 ASSERT(ilg->ilg_ilm == ilm);
2865 * Failed to allocate the ilm.
3066 * proceed with the ilm part of the delete we hold a reference on both the ill
3074 * has disappeared when ip_addmulti returns, so it will discard the ilm it just
3081 ilm_t *ilm;
3116 * check that we still have an ilm.
3134 ilm = ilg->ilg_ilm;
3141 if (ilm != NULL)
3142 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);
3164 * Attach the ilg to an ilm on the ill. If it fails we leave ilg_ill as NULL so
3176 ilm_t *ilm;
3203 ilm = ip_addmulti_serial(&v6group, ill, connp->conn_zoneid, ilgstat,
3217 if (ilm != NULL) {
3219 (void) ip_delmulti_serial(ilm, B_FALSE,
3225 if (ilm == NULL) {
3229 ilg->ilg_ilm = ilm;
3230 ilm->ilm_ifaddr = ifaddr; /* For netstat */
3257 * proceed with the ilm part of the delete we hold a reference on both the ill
3263 * a NULL ilg_ill to an ill/ilm.
3305 ilm_t *ilm;
3323 /* Detach this ilg from the ill/ilm */
3324 ilm = ilg->ilg_ilm;
3327 if (ilm == NULL)
3335 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);
3362 ilm_t *ilm;
3380 * ilm.
3441 ilm = ilg->ilg_ilm;
3445 ilm = NULL;
3450 if (ilm != NULL)
3451 (void) ip_delmulti_serial(ilm, B_FALSE, B_TRUE);