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

Function in6m_merge

freebsd/netinet6/in6_mcast.c:997–1120  ·  view source on GitHub ↗

* Atomically update the global in6_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 spac

Source from the content-addressed store, hash-verified

995 * and return a non-zero value.
996 */
997static int
998in6m_merge(struct in6_multi *inm, /*const*/ struct in6_mfilter *imf)
999{
1000 struct ip6_msource *ims, *nims;
1001 struct in6_msource *lims;
1002 int schanged, error;
1003 int nsrc0, nsrc1;
1004
1005 schanged = 0;
1006 error = 0;
1007 nsrc1 = nsrc0 = 0;
1008 IN6_MULTI_LIST_LOCK_ASSERT();
1009
1010 /*
1011 * Update the source filters first, as this may fail.
1012 * Maintain count of in-mode filters at t0, t1. These are
1013 * used to work out if we transition into ASM mode or not.
1014 * Maintain a count of source filters whose state was
1015 * actually modified by this operation.
1016 */
1017 RB_FOREACH(ims, ip6_msource_tree, &imf->im6f_sources) {
1018 lims = (struct in6_msource *)ims;
1019 if (lims->im6sl_st[0] == imf->im6f_st[0]) nsrc0++;
1020 if (lims->im6sl_st[1] == imf->im6f_st[1]) nsrc1++;
1021 if (lims->im6sl_st[0] == lims->im6sl_st[1]) continue;
1022 error = in6m_get_source(inm, &lims->im6s_addr, 0, &nims);
1023 ++schanged;
1024 if (error)
1025 break;
1026 im6s_merge(nims, lims, 0);
1027 }
1028 if (error) {
1029 struct ip6_msource *bims;
1030
1031 RB_FOREACH_REVERSE_FROM(ims, ip6_msource_tree, nims) {
1032 lims = (struct in6_msource *)ims;
1033 if (lims->im6sl_st[0] == lims->im6sl_st[1])
1034 continue;
1035 (void)in6m_get_source(inm, &lims->im6s_addr, 1, &bims);
1036 if (bims == NULL)
1037 continue;
1038 im6s_merge(bims, lims, 1);
1039 }
1040 goto out_reap;
1041 }
1042
1043 CTR3(KTR_MLD, "%s: imf filters in-mode: %d at t0, %d at t1",
1044 __func__, nsrc0, nsrc1);
1045
1046 /* Handle transition between INCLUDE {n} and INCLUDE {} on socket. */
1047 if (imf->im6f_st[0] == imf->im6f_st[1] &&
1048 imf->im6f_st[1] == MCAST_INCLUDE) {
1049 if (nsrc1 == 0) {
1050 CTR1(KTR_MLD, "%s: --in on inm at t1", __func__);
1051 --inm->in6m_st[1].iss_in;
1052 }
1053 }
1054

Callers 6

in6_joingroup_lockedFunction · 0.85
in6_leavegroup_lockedFunction · 0.85
in6p_join_groupFunction · 0.85
in6p_leave_groupFunction · 0.85
in6p_set_source_filtersFunction · 0.85

Calls 4

in6m_get_sourceFunction · 0.85
im6s_mergeFunction · 0.85
in6m_printFunction · 0.85
in6m_reapFunction · 0.85

Tested by

no test coverage detected