* Record a source as pending for a Source-Group IGMPv3 query. * This lives here as it modifies the shared tree. * * inm is the group descriptor. * naddr is the address of the source to record in network-byte order. * * If the net.inet.igmp.sgalloc sysctl is non-zero, we will * lazy-allocate a source node in response to an SG query. * Otherwise, no allocation is performed. This saves some m
| 695 | * Return <0 if any error occurred (negated errno code). |
| 696 | */ |
| 697 | int |
| 698 | inm_record_source(struct in_multi *inm, const in_addr_t naddr) |
| 699 | { |
| 700 | struct ip_msource find; |
| 701 | struct ip_msource *ims, *nims; |
| 702 | |
| 703 | IN_MULTI_LIST_LOCK_ASSERT(); |
| 704 | |
| 705 | find.ims_haddr = ntohl(naddr); |
| 706 | ims = RB_FIND(ip_msource_tree, &inm->inm_srcs, &find); |
| 707 | if (ims && ims->ims_stp) |
| 708 | return (0); |
| 709 | if (ims == NULL) { |
| 710 | if (inm->inm_nsrc == in_mcast_maxgrpsrc) |
| 711 | return (-ENOSPC); |
| 712 | nims = malloc(sizeof(struct ip_msource), M_IPMSOURCE, |
| 713 | M_NOWAIT | M_ZERO); |
| 714 | if (nims == NULL) |
| 715 | return (-ENOMEM); |
| 716 | nims->ims_haddr = find.ims_haddr; |
| 717 | RB_INSERT(ip_msource_tree, &inm->inm_srcs, nims); |
| 718 | ++inm->inm_nsrc; |
| 719 | ims = nims; |
| 720 | } |
| 721 | |
| 722 | /* |
| 723 | * Mark the source as recorded and update the recorded |
| 724 | * source count. |
| 725 | */ |
| 726 | ++ims->ims_stp; |
| 727 | ++inm->inm_st[1].iss_rec; |
| 728 | |
| 729 | return (1); |
| 730 | } |
| 731 | |
| 732 | /* |
| 733 | * Return a pointer to an in_msource owned by an in_mfilter, |
no test coverage detected