igmp.c (80dbff4e99ba37534b40803a1ddff842f5ebdd58) | igmp.c (137f91e80f3802084bd96586d09961a846b91665) |
---|---|
1/*- 2 * Copyright (c) 2007-2009 Bruce Simpson. 3 * Copyright (c) 1988 Stephen Deering. 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Stephen Deering of Stanford University. --- 604 unchanged lines hidden (view full) --- 613 614 CTR3(KTR_IGMPV3, "%s: called for ifp %p(%s)", __func__, ifp, 615 ifp->if_xname); 616 617 IGMP_LOCK(); 618 619 igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp; 620 if (igi->igi_version == IGMP_VERSION_3) { | 1/*- 2 * Copyright (c) 2007-2009 Bruce Simpson. 3 * Copyright (c) 1988 Stephen Deering. 4 * Copyright (c) 1992, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * This code is derived from software contributed to Berkeley by 8 * Stephen Deering of Stanford University. --- 604 unchanged lines hidden (view full) --- 613 614 CTR3(KTR_IGMPV3, "%s: called for ifp %p(%s)", __func__, ifp, 615 ifp->if_xname); 616 617 IGMP_LOCK(); 618 619 igi = ((struct in_ifinfo *)ifp->if_afdata[AF_INET])->ii_igmp; 620 if (igi->igi_version == IGMP_VERSION_3) { |
621 IF_ADDR_LOCK(ifp); | 621 IF_ADDR_RLOCK(ifp); |
622 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 623 if (ifma->ifma_addr->sa_family != AF_INET || 624 ifma->ifma_protospec == NULL) 625 continue; 626#if 0 627 KASSERT(ifma->ifma_protospec != NULL, 628 ("%s: ifma_protospec is NULL", __func__)); 629#endif 630 inm = (struct in_multi *)ifma->ifma_protospec; 631 if (inm->inm_state == IGMP_LEAVING_MEMBER) { 632 SLIST_INSERT_HEAD(&igi->igi_relinmhead, 633 inm, inm_nrele); 634 } 635 inm_clear_recorded(inm); 636 } | 622 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 623 if (ifma->ifma_addr->sa_family != AF_INET || 624 ifma->ifma_protospec == NULL) 625 continue; 626#if 0 627 KASSERT(ifma->ifma_protospec != NULL, 628 ("%s: ifma_protospec is NULL", __func__)); 629#endif 630 inm = (struct in_multi *)ifma->ifma_protospec; 631 if (inm->inm_state == IGMP_LEAVING_MEMBER) { 632 SLIST_INSERT_HEAD(&igi->igi_relinmhead, 633 inm, inm_nrele); 634 } 635 inm_clear_recorded(inm); 636 } |
637 IF_ADDR_UNLOCK(ifp); | 637 IF_ADDR_RUNLOCK(ifp); |
638 /* 639 * Free the in_multi reference(s) for this IGMP lifecycle. 640 */ 641 SLIST_FOREACH_SAFE(inm, &igi->igi_relinmhead, inm_nrele, 642 tinm) { 643 SLIST_REMOVE_HEAD(&igi->igi_relinmhead, inm_nrele); 644 inm_release_locked(inm); 645 } --- 100 unchanged lines hidden (view full) --- 746 747 CTR2(KTR_IGMPV3, "process v1 query on ifp %p(%s)", ifp, ifp->if_xname); 748 749 /* 750 * Start the timers in all of our group records 751 * for the interface on which the query arrived, 752 * except those which are already running. 753 */ | 638 /* 639 * Free the in_multi reference(s) for this IGMP lifecycle. 640 */ 641 SLIST_FOREACH_SAFE(inm, &igi->igi_relinmhead, inm_nrele, 642 tinm) { 643 SLIST_REMOVE_HEAD(&igi->igi_relinmhead, inm_nrele); 644 inm_release_locked(inm); 645 } --- 100 unchanged lines hidden (view full) --- 746 747 CTR2(KTR_IGMPV3, "process v1 query on ifp %p(%s)", ifp, ifp->if_xname); 748 749 /* 750 * Start the timers in all of our group records 751 * for the interface on which the query arrived, 752 * except those which are already running. 753 */ |
754 IF_ADDR_LOCK(ifp); | 754 IF_ADDR_RLOCK(ifp); |
755 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 756 if (ifma->ifma_addr->sa_family != AF_INET || 757 ifma->ifma_protospec == NULL) 758 continue; 759 inm = (struct in_multi *)ifma->ifma_protospec; 760 if (inm->inm_timer != 0) 761 continue; 762 switch (inm->inm_state) { --- 11 unchanged lines hidden (view full) --- 774 inm->inm_timer = IGMP_RANDOM_DELAY( 775 IGMP_V1V2_MAX_RI * PR_FASTHZ); 776 V_current_state_timers_running = 1; 777 break; 778 case IGMP_LEAVING_MEMBER: 779 break; 780 } 781 } | 755 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 756 if (ifma->ifma_addr->sa_family != AF_INET || 757 ifma->ifma_protospec == NULL) 758 continue; 759 inm = (struct in_multi *)ifma->ifma_protospec; 760 if (inm->inm_timer != 0) 761 continue; 762 switch (inm->inm_state) { --- 11 unchanged lines hidden (view full) --- 774 inm->inm_timer = IGMP_RANDOM_DELAY( 775 IGMP_V1V2_MAX_RI * PR_FASTHZ); 776 V_current_state_timers_running = 1; 777 break; 778 case IGMP_LEAVING_MEMBER: 779 break; 780 } 781 } |
782 IF_ADDR_UNLOCK(ifp); | 782 IF_ADDR_RUNLOCK(ifp); |
783 784out_locked: 785 IGMP_UNLOCK(); 786 IN_MULTI_UNLOCK(); 787 788 return (0); 789} 790 --- 56 unchanged lines hidden (view full) --- 847 848 if (is_general_query) { 849 /* 850 * For each reporting group joined on this 851 * interface, kick the report timer. 852 */ 853 CTR2(KTR_IGMPV3, "process v2 general query on ifp %p(%s)", 854 ifp, ifp->if_xname); | 783 784out_locked: 785 IGMP_UNLOCK(); 786 IN_MULTI_UNLOCK(); 787 788 return (0); 789} 790 --- 56 unchanged lines hidden (view full) --- 847 848 if (is_general_query) { 849 /* 850 * For each reporting group joined on this 851 * interface, kick the report timer. 852 */ 853 CTR2(KTR_IGMPV3, "process v2 general query on ifp %p(%s)", 854 ifp, ifp->if_xname); |
855 IF_ADDR_LOCK(ifp); | 855 IF_ADDR_RLOCK(ifp); |
856 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 857 if (ifma->ifma_addr->sa_family != AF_INET || 858 ifma->ifma_protospec == NULL) 859 continue; 860 inm = (struct in_multi *)ifma->ifma_protospec; 861 igmp_v2_update_group(inm, timer); 862 } | 856 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 857 if (ifma->ifma_addr->sa_family != AF_INET || 858 ifma->ifma_protospec == NULL) 859 continue; 860 inm = (struct in_multi *)ifma->ifma_protospec; 861 igmp_v2_update_group(inm, timer); 862 } |
863 IF_ADDR_UNLOCK(ifp); | 863 IF_ADDR_RUNLOCK(ifp); |
864 } else { 865 /* 866 * Group-specific IGMPv2 query, we need only 867 * look up the single group to process it. 868 */ 869 inm = inm_lookup(ifp, igmp->igmp_group); 870 if (inm != NULL) { 871 CTR3(KTR_IGMPV3, "process v2 query %s on ifp %p(%s)", --- 831 unchanged lines hidden (view full) --- 1703 1704 memset(&qrq, 0, sizeof(struct ifqueue)); 1705 IFQ_SET_MAXLEN(&qrq, IGMP_MAX_G_GS_PACKETS); 1706 1707 memset(&scq, 0, sizeof(struct ifqueue)); 1708 IFQ_SET_MAXLEN(&scq, IGMP_MAX_STATE_CHANGE_PACKETS); 1709 } 1710 | 864 } else { 865 /* 866 * Group-specific IGMPv2 query, we need only 867 * look up the single group to process it. 868 */ 869 inm = inm_lookup(ifp, igmp->igmp_group); 870 if (inm != NULL) { 871 CTR3(KTR_IGMPV3, "process v2 query %s on ifp %p(%s)", --- 831 unchanged lines hidden (view full) --- 1703 1704 memset(&qrq, 0, sizeof(struct ifqueue)); 1705 IFQ_SET_MAXLEN(&qrq, IGMP_MAX_G_GS_PACKETS); 1706 1707 memset(&scq, 0, sizeof(struct ifqueue)); 1708 IFQ_SET_MAXLEN(&scq, IGMP_MAX_STATE_CHANGE_PACKETS); 1709 } 1710 |
1711 IF_ADDR_LOCK(ifp); | 1711 IF_ADDR_RLOCK(ifp); |
1712 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1713 if (ifma->ifma_addr->sa_family != AF_INET || 1714 ifma->ifma_protospec == NULL) 1715 continue; 1716 inm = (struct in_multi *)ifma->ifma_protospec; 1717 switch (igi->igi_version) { 1718 case IGMP_VERSION_1: 1719 case IGMP_VERSION_2: 1720 igmp_v1v2_process_group_timer(inm, 1721 igi->igi_version); 1722 break; 1723 case IGMP_VERSION_3: 1724 igmp_v3_process_group_timers(igi, &qrq, 1725 &scq, inm, uri_fasthz); 1726 break; 1727 } 1728 } | 1712 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 1713 if (ifma->ifma_addr->sa_family != AF_INET || 1714 ifma->ifma_protospec == NULL) 1715 continue; 1716 inm = (struct in_multi *)ifma->ifma_protospec; 1717 switch (igi->igi_version) { 1718 case IGMP_VERSION_1: 1719 case IGMP_VERSION_2: 1720 igmp_v1v2_process_group_timer(inm, 1721 igi->igi_version); 1722 break; 1723 case IGMP_VERSION_3: 1724 igmp_v3_process_group_timers(igi, &qrq, 1725 &scq, inm, uri_fasthz); 1726 break; 1727 } 1728 } |
1729 IF_ADDR_UNLOCK(ifp); | 1729 IF_ADDR_RUNLOCK(ifp); |
1730 1731 if (igi->igi_version == IGMP_VERSION_3) { 1732 struct in_multi *tinm; 1733 1734 igmp_dispatch_queue(&qrq, 0, loop); 1735 igmp_dispatch_queue(&scq, 0, loop); 1736 1737 /* --- 280 unchanged lines hidden (view full) --- 2018 */ 2019 igi->igi_v3_timer = 0; 2020 2021 /* 2022 * Now clear the current-state and state-change report timers 2023 * for all memberships scoped to this link. 2024 */ 2025 ifp = igi->igi_ifp; | 1730 1731 if (igi->igi_version == IGMP_VERSION_3) { 1732 struct in_multi *tinm; 1733 1734 igmp_dispatch_queue(&qrq, 0, loop); 1735 igmp_dispatch_queue(&scq, 0, loop); 1736 1737 /* --- 280 unchanged lines hidden (view full) --- 2018 */ 2019 igi->igi_v3_timer = 0; 2020 2021 /* 2022 * Now clear the current-state and state-change report timers 2023 * for all memberships scoped to this link. 2024 */ 2025 ifp = igi->igi_ifp; |
2026 IF_ADDR_LOCK(ifp); | 2026 IF_ADDR_RLOCK(ifp); |
2027 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2028 if (ifma->ifma_addr->sa_family != AF_INET || 2029 ifma->ifma_protospec == NULL) 2030 continue; 2031 inm = (struct in_multi *)ifma->ifma_protospec; 2032 switch (inm->inm_state) { 2033 case IGMP_NOT_MEMBER: 2034 case IGMP_SILENT_MEMBER: --- 28 unchanged lines hidden (view full) --- 2063 /* 2064 * Always clear state-change and group report timers. 2065 * Free any pending IGMPv3 state-change records. 2066 */ 2067 inm->inm_sctimer = 0; 2068 inm->inm_timer = 0; 2069 _IF_DRAIN(&inm->inm_scq); 2070 } | 2027 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 2028 if (ifma->ifma_addr->sa_family != AF_INET || 2029 ifma->ifma_protospec == NULL) 2030 continue; 2031 inm = (struct in_multi *)ifma->ifma_protospec; 2032 switch (inm->inm_state) { 2033 case IGMP_NOT_MEMBER: 2034 case IGMP_SILENT_MEMBER: --- 28 unchanged lines hidden (view full) --- 2063 /* 2064 * Always clear state-change and group report timers. 2065 * Free any pending IGMPv3 state-change records. 2066 */ 2067 inm->inm_sctimer = 0; 2068 inm->inm_timer = 0; 2069 _IF_DRAIN(&inm->inm_scq); 2070 } |
2071 IF_ADDR_UNLOCK(ifp); | 2071 IF_ADDR_RUNLOCK(ifp); |
2072 SLIST_FOREACH_SAFE(inm, &igi->igi_relinmhead, inm_nrele, tinm) { 2073 SLIST_REMOVE_HEAD(&igi->igi_relinmhead, inm_nrele); 2074 inm_release_locked(inm); 2075 } 2076} 2077 2078/* 2079 * Update the Older Version Querier Present timers for a link. --- 1246 unchanged lines hidden (view full) --- 3326 IN_MULTI_LOCK_ASSERT(); 3327 IGMP_LOCK_ASSERT(); 3328 3329 KASSERT(igi->igi_version == IGMP_VERSION_3, 3330 ("%s: called when version %d", __func__, igi->igi_version)); 3331 3332 ifp = igi->igi_ifp; 3333 | 2072 SLIST_FOREACH_SAFE(inm, &igi->igi_relinmhead, inm_nrele, tinm) { 2073 SLIST_REMOVE_HEAD(&igi->igi_relinmhead, inm_nrele); 2074 inm_release_locked(inm); 2075 } 2076} 2077 2078/* 2079 * Update the Older Version Querier Present timers for a link. --- 1246 unchanged lines hidden (view full) --- 3326 IN_MULTI_LOCK_ASSERT(); 3327 IGMP_LOCK_ASSERT(); 3328 3329 KASSERT(igi->igi_version == IGMP_VERSION_3, 3330 ("%s: called when version %d", __func__, igi->igi_version)); 3331 3332 ifp = igi->igi_ifp; 3333 |
3334 IF_ADDR_LOCK(ifp); | 3334 IF_ADDR_RLOCK(ifp); |
3335 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 3336 if (ifma->ifma_addr->sa_family != AF_INET || 3337 ifma->ifma_protospec == NULL) 3338 continue; 3339 3340 inm = (struct in_multi *)ifma->ifma_protospec; 3341 KASSERT(ifp == inm->inm_ifp, 3342 ("%s: inconsistent ifp", __func__)); --- 14 unchanged lines hidden (view full) --- 3357 __func__, retval); 3358 break; 3359 case IGMP_G_QUERY_PENDING_MEMBER: 3360 case IGMP_SG_QUERY_PENDING_MEMBER: 3361 case IGMP_LEAVING_MEMBER: 3362 break; 3363 } 3364 } | 3335 TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { 3336 if (ifma->ifma_addr->sa_family != AF_INET || 3337 ifma->ifma_protospec == NULL) 3338 continue; 3339 3340 inm = (struct in_multi *)ifma->ifma_protospec; 3341 KASSERT(ifp == inm->inm_ifp, 3342 ("%s: inconsistent ifp", __func__)); --- 14 unchanged lines hidden (view full) --- 3357 __func__, retval); 3358 break; 3359 case IGMP_G_QUERY_PENDING_MEMBER: 3360 case IGMP_SG_QUERY_PENDING_MEMBER: 3361 case IGMP_LEAVING_MEMBER: 3362 break; 3363 } 3364 } |
3365 IF_ADDR_UNLOCK(ifp); | 3365 IF_ADDR_RUNLOCK(ifp); |
3366 3367 loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0; 3368 igmp_dispatch_queue(&igi->igi_gq, IGMP_MAX_RESPONSE_BURST, loop); 3369 3370 /* 3371 * Slew transmission of bursts over 500ms intervals. 3372 */ 3373 if (igi->igi_gq.ifq_head != NULL) { --- 278 unchanged lines hidden --- | 3366 3367 loop = (igi->igi_flags & IGIF_LOOPBACK) ? 1 : 0; 3368 igmp_dispatch_queue(&igi->igi_gq, IGMP_MAX_RESPONSE_BURST, loop); 3369 3370 /* 3371 * Slew transmission of bursts over 500ms intervals. 3372 */ 3373 if (igi->igi_gq.ifq_head != NULL) { --- 278 unchanged lines hidden --- |