MCPcopy Create free account
hub / github.com/F-Stack/f-stack / igmp_input_v2_report

Function igmp_input_v2_report

freebsd/netinet/igmp.c:1367–1466  ·  view source on GitHub ↗

* Process a received IGMPv2 host membership report. * * NOTE: 0.0.0.0 workaround breaks const correctness. */

Source from the content-addressed store, hash-verified

1365 * NOTE: 0.0.0.0 workaround breaks const correctness.
1366 */
1367static int
1368igmp_input_v2_report(struct ifnet *ifp, /*const*/ struct ip *ip,
1369 /*const*/ struct igmp *igmp)
1370{
1371 struct rm_priotracker in_ifa_tracker;
1372 struct in_ifaddr *ia;
1373 struct in_multi *inm;
1374
1375 /*
1376 * Make sure we don't hear our own membership report. Fast
1377 * leave requires knowing that we are the only member of a
1378 * group.
1379 */
1380 IFP_TO_IA(ifp, ia, &in_ifa_tracker);
1381 if (ia != NULL && in_hosteq(ip->ip_src, IA_SIN(ia)->sin_addr)) {
1382 return (0);
1383 }
1384
1385 IGMPSTAT_INC(igps_rcv_reports);
1386
1387 if (ifp->if_flags & IFF_LOOPBACK) {
1388 return (0);
1389 }
1390
1391 if (!IN_MULTICAST(ntohl(igmp->igmp_group.s_addr)) ||
1392 !in_hosteq(igmp->igmp_group, ip->ip_dst)) {
1393 IGMPSTAT_INC(igps_rcv_badreports);
1394 return (EINVAL);
1395 }
1396
1397 /*
1398 * RFC 3376, Section 4.2.13, 9.2, 9.3:
1399 * Booting clients may use the source address 0.0.0.0. Some
1400 * IGMP daemons may not know how to use IP_RECVIF to determine
1401 * the interface upon which this message was received.
1402 * Replace 0.0.0.0 with the subnet address if told to do so.
1403 */
1404 if (V_igmp_recvifkludge && in_nullhost(ip->ip_src)) {
1405 if (ia != NULL)
1406 ip->ip_src.s_addr = htonl(ia->ia_subnet);
1407 }
1408
1409 CTR3(KTR_IGMPV3, "process v2 report 0x%08x on ifp %p(%s)",
1410 ntohl(igmp->igmp_group.s_addr), ifp, ifp->if_xname);
1411
1412 /*
1413 * IGMPv2 report suppression.
1414 * If we are a member of this group, and our membership should be
1415 * reported, and our group timer is pending or about to be reset,
1416 * stop our group timer by transitioning to the 'lazy' state.
1417 */
1418 IN_MULTI_LIST_LOCK();
1419 inm = inm_lookup(ifp, igmp->igmp_group);
1420 if (inm != NULL) {
1421 struct igmp_ifsoftc *igi;
1422
1423 igi = inm->inm_igi;
1424 KASSERT(igi != NULL, ("%s: no igi for ifp %p", __func__, ifp));

Callers 1

igmp_inputFunction · 0.85

Calls 2

inm_lookupFunction · 0.85

Tested by

no test coverage detected