* Respond to a pending IGMPv3 General Query. */
| 3356 | * Respond to a pending IGMPv3 General Query. |
| 3357 | */ |
| 3358 | static void |
| 3359 | igmp_v3_dispatch_general_query(struct igmp_ifsoftc *igi) |
| 3360 | { |
| 3361 | struct ifmultiaddr *ifma; |
| 3362 | struct ifnet *ifp; |
| 3363 | struct in_multi *inm; |
| 3364 | int retval __unused, loop; |
| 3365 | |
| 3366 | IN_MULTI_LIST_LOCK_ASSERT(); |
| 3367 | IGMP_LOCK_ASSERT(); |
| 3368 | NET_EPOCH_ASSERT(); |
| 3369 | |
| 3370 | KASSERT(igi->igi_version == IGMP_VERSION_3, |
| 3371 | ("%s: called when version %d", __func__, igi->igi_version)); |
| 3372 | |
| 3373 | /* |
| 3374 | * Check that there are some packets queued. If so, send them first. |
| 3375 | * For large number of groups the reply to general query can take |
| 3376 | * many packets, we should finish sending them before starting of |
| 3377 | * queuing the new reply. |
| 3378 | */ |
| 3379 | if (mbufq_len(&igi->igi_gq) != 0) |
| 3380 | goto send; |
| 3381 | |
| 3382 | ifp = igi->igi_ifp; |
| 3383 | |
| 3384 | CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { |
| 3385 | if (ifma->ifma_addr->sa_family != AF_INET || |
| 3386 | ifma->ifma_protospec == NULL) |
| 3387 | continue; |
| 3388 | |
| 3389 | inm = (struct in_multi *)ifma->ifma_protospec; |
| 3390 | KASSERT(ifp == inm->inm_ifp, |
| 3391 | ("%s: inconsistent ifp", __func__)); |
| 3392 | |
| 3393 | switch (inm->inm_state) { |
| 3394 | case IGMP_NOT_MEMBER: |
| 3395 | case IGMP_SILENT_MEMBER: |
| 3396 | break; |
| 3397 | case IGMP_REPORTING_MEMBER: |
| 3398 | case IGMP_IDLE_MEMBER: |
| 3399 | case IGMP_LAZY_MEMBER: |
| 3400 | case IGMP_SLEEPING_MEMBER: |
| 3401 | case IGMP_AWAKENING_MEMBER: |
| 3402 | inm->inm_state = IGMP_REPORTING_MEMBER; |
| 3403 | retval = igmp_v3_enqueue_group_record(&igi->igi_gq, |
| 3404 | inm, 0, 0, 0); |
| 3405 | CTR2(KTR_IGMPV3, "%s: enqueue record = %d", |
| 3406 | __func__, retval); |
| 3407 | break; |
| 3408 | case IGMP_G_QUERY_PENDING_MEMBER: |
| 3409 | case IGMP_SG_QUERY_PENDING_MEMBER: |
| 3410 | case IGMP_LEAVING_MEMBER: |
| 3411 | break; |
| 3412 | } |
| 3413 | } |
| 3414 | |
| 3415 | send: |
no test coverage detected