* Process a received IGMPv3 group-specific or group-and-source-specific * query. * Return <0 if any error occurred. Currently this is ignored. */
| 1154 | * Return <0 if any error occurred. Currently this is ignored. |
| 1155 | */ |
| 1156 | static int |
| 1157 | igmp_input_v3_group_query(struct in_multi *inm, struct igmp_ifsoftc *igi, |
| 1158 | int timer, /*const*/ struct igmpv3 *igmpv3) |
| 1159 | { |
| 1160 | int retval; |
| 1161 | uint16_t nsrc; |
| 1162 | |
| 1163 | IN_MULTI_LIST_LOCK_ASSERT(); |
| 1164 | IGMP_LOCK_ASSERT(); |
| 1165 | |
| 1166 | retval = 0; |
| 1167 | |
| 1168 | switch (inm->inm_state) { |
| 1169 | case IGMP_NOT_MEMBER: |
| 1170 | case IGMP_SILENT_MEMBER: |
| 1171 | case IGMP_SLEEPING_MEMBER: |
| 1172 | case IGMP_LAZY_MEMBER: |
| 1173 | case IGMP_AWAKENING_MEMBER: |
| 1174 | case IGMP_IDLE_MEMBER: |
| 1175 | case IGMP_LEAVING_MEMBER: |
| 1176 | return (retval); |
| 1177 | break; |
| 1178 | case IGMP_REPORTING_MEMBER: |
| 1179 | case IGMP_G_QUERY_PENDING_MEMBER: |
| 1180 | case IGMP_SG_QUERY_PENDING_MEMBER: |
| 1181 | break; |
| 1182 | } |
| 1183 | |
| 1184 | nsrc = ntohs(igmpv3->igmp_numsrc); |
| 1185 | |
| 1186 | /* |
| 1187 | * Deal with group-specific queries upfront. |
| 1188 | * If any group query is already pending, purge any recorded |
| 1189 | * source-list state if it exists, and schedule a query response |
| 1190 | * for this group-specific query. |
| 1191 | */ |
| 1192 | if (nsrc == 0) { |
| 1193 | if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER || |
| 1194 | inm->inm_state == IGMP_SG_QUERY_PENDING_MEMBER) { |
| 1195 | inm_clear_recorded(inm); |
| 1196 | timer = min(inm->inm_timer, timer); |
| 1197 | } |
| 1198 | inm->inm_state = IGMP_G_QUERY_PENDING_MEMBER; |
| 1199 | inm->inm_timer = IGMP_RANDOM_DELAY(timer); |
| 1200 | V_current_state_timers_running = 1; |
| 1201 | return (retval); |
| 1202 | } |
| 1203 | |
| 1204 | /* |
| 1205 | * Deal with the case where a group-and-source-specific query has |
| 1206 | * been received but a group-specific query is already pending. |
| 1207 | */ |
| 1208 | if (inm->inm_state == IGMP_G_QUERY_PENDING_MEMBER) { |
| 1209 | timer = min(inm->inm_timer, timer); |
| 1210 | inm->inm_timer = IGMP_RANDOM_DELAY(timer); |
| 1211 | V_current_state_timers_running = 1; |
| 1212 | return (retval); |
| 1213 | } |
no test coverage detected