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

Function inm_merge

freebsd/netinet/in_mcast.c:1027–1150  ·  view source on GitHub ↗

* Atomically update the global in_multi state, when a membership's * filter list is being updated in any way. * * imf is the per-inpcb-membership group filter pointer. * A fake imf may be passed for in-kernel consumers. * * XXX This is a candidate for a set-symmetric-difference style loop * which would eliminate the repeated lookup from root of ims nodes, * as they share the same key space

Source from the content-addressed store, hash-verified

1025 * and return a non-zero value.
1026 */
1027static int
1028inm_merge(struct in_multi *inm, /*const*/ struct in_mfilter *imf)
1029{
1030 struct ip_msource *ims, *nims;
1031 struct in_msource *lims;
1032 int schanged, error;
1033 int nsrc0, nsrc1;
1034
1035 schanged = 0;
1036 error = 0;
1037 nsrc1 = nsrc0 = 0;
1038 IN_MULTI_LIST_LOCK_ASSERT();
1039
1040 /*
1041 * Update the source filters first, as this may fail.
1042 * Maintain count of in-mode filters at t0, t1. These are
1043 * used to work out if we transition into ASM mode or not.
1044 * Maintain a count of source filters whose state was
1045 * actually modified by this operation.
1046 */
1047 RB_FOREACH(ims, ip_msource_tree, &imf->imf_sources) {
1048 lims = (struct in_msource *)ims;
1049 if (lims->imsl_st[0] == imf->imf_st[0]) nsrc0++;
1050 if (lims->imsl_st[1] == imf->imf_st[1]) nsrc1++;
1051 if (lims->imsl_st[0] == lims->imsl_st[1]) continue;
1052 error = inm_get_source(inm, lims->ims_haddr, 0, &nims);
1053 ++schanged;
1054 if (error)
1055 break;
1056 ims_merge(nims, lims, 0);
1057 }
1058 if (error) {
1059 struct ip_msource *bims;
1060
1061 RB_FOREACH_REVERSE_FROM(ims, ip_msource_tree, nims) {
1062 lims = (struct in_msource *)ims;
1063 if (lims->imsl_st[0] == lims->imsl_st[1])
1064 continue;
1065 (void)inm_get_source(inm, lims->ims_haddr, 1, &bims);
1066 if (bims == NULL)
1067 continue;
1068 ims_merge(bims, lims, 1);
1069 }
1070 goto out_reap;
1071 }
1072
1073 CTR3(KTR_IGMPV3, "%s: imf filters in-mode: %d at t0, %d at t1",
1074 __func__, nsrc0, nsrc1);
1075
1076 /* Handle transition between INCLUDE {n} and INCLUDE {} on socket. */
1077 if (imf->imf_st[0] == imf->imf_st[1] &&
1078 imf->imf_st[1] == MCAST_INCLUDE) {
1079 if (nsrc1 == 0) {
1080 CTR1(KTR_IGMPV3, "%s: --in on inm at t1", __func__);
1081 --inm->inm_st[1].iss_in;
1082 }
1083 }
1084

Callers 6

in_joingroup_lockedFunction · 0.85
in_leavegroup_lockedFunction · 0.85
inp_block_unblock_sourceFunction · 0.85
inp_join_groupFunction · 0.85
inp_leave_groupFunction · 0.85
inp_set_source_filtersFunction · 0.85

Calls 4

inm_get_sourceFunction · 0.85
ims_mergeFunction · 0.85
inm_printFunction · 0.85
inm_reapFunction · 0.85

Tested by

no test coverage detected