* Look up a source filter entry for a multicast group. * * inm is the group descriptor to work with. * haddr is the host-byte-order IPv4 address to look up. * noalloc may be non-zero to suppress allocation of sources. * *pims will be set to the address of the retrieved or allocated source. * * SMPng: NOTE: may be called with locks held. * Return 0 if successful, otherwise return a non-zero
| 950 | * Return 0 if successful, otherwise return a non-zero error code. |
| 951 | */ |
| 952 | static int |
| 953 | inm_get_source(struct in_multi *inm, const in_addr_t haddr, |
| 954 | const int noalloc, struct ip_msource **pims) |
| 955 | { |
| 956 | struct ip_msource find; |
| 957 | struct ip_msource *ims, *nims; |
| 958 | |
| 959 | find.ims_haddr = haddr; |
| 960 | ims = RB_FIND(ip_msource_tree, &inm->inm_srcs, &find); |
| 961 | if (ims == NULL && !noalloc) { |
| 962 | if (inm->inm_nsrc == in_mcast_maxgrpsrc) |
| 963 | return (ENOSPC); |
| 964 | nims = malloc(sizeof(struct ip_msource), M_IPMSOURCE, |
| 965 | M_NOWAIT | M_ZERO); |
| 966 | if (nims == NULL) |
| 967 | return (ENOMEM); |
| 968 | nims->ims_haddr = haddr; |
| 969 | RB_INSERT(ip_msource_tree, &inm->inm_srcs, nims); |
| 970 | ++inm->inm_nsrc; |
| 971 | ims = nims; |
| 972 | #ifdef KTR |
| 973 | CTR3(KTR_IGMPV3, "%s: allocated 0x%08x as %p", __func__, |
| 974 | haddr, ims); |
| 975 | #endif |
| 976 | } |
| 977 | |
| 978 | *pims = ims; |
| 979 | return (0); |
| 980 | } |
| 981 | |
| 982 | /* |
| 983 | * Merge socket-layer source into IGMP-layer source. |