func()

in npm/pkg/dataplane/ipsets/ipsetmanager_linux.go [556:662]


func (iMgr *IPSetManager) updateDirtyKernelSets(setsToAddOrUpdate map[string]struct{}, saveFile []byte, creator *ioutil.FileCreator) {
	// map hashed names to prefixed names
	toAddOrUpdateHashedNames := make(map[string]string)
	for prefixedName := range setsToAddOrUpdate {
		hashedName := iMgr.setMap[prefixedName].HashedName
		toAddOrUpdateHashedNames[hashedName] = prefixedName
	}

	// in each iteration, read a create line and any ensuing add lines
	readIndex := 0
	var line []byte
	if readIndex < len(saveFile) {
		line, readIndex = parse.Line(readIndex, saveFile)
		if !hasPrefix(line, createStringWithSpace) {
			metrics.SendErrorLogAndMetric(util.IpsmID, "expected a create line in ipset save file, but got the following line: %s", string(line))
			// TODO send error snapshot
			line, readIndex = nextCreateLine(readIndex, saveFile)
		}
	}
	for readIndex < len(saveFile) {
		// 1. get the hashed name
		lineAfterCreate := string(line[len(createStringWithSpace):])
		spaceSplitLineAfterCreate := strings.Split(lineAfterCreate, space)
		hashedName := spaceSplitLineAfterCreate[0]

		// 2. continue to the next create line if the set isn't in the toAddOrUpdateCache
		prefixedName, shouldModify := toAddOrUpdateHashedNames[hashedName]
		if !shouldModify {
			line, readIndex = nextCreateLine(readIndex, saveFile)
			continue
		}

		// 3. update the set from the kernel
		set := iMgr.setMap[prefixedName]
		// remove from the dirty cache so we don't add it later
		delete(setsToAddOrUpdate, prefixedName)
		// mark the set as in the kernel
		delete(toAddOrUpdateHashedNames, hashedName)

		// 3.1 check for consistent type
		restOfLine := spaceSplitLineAfterCreate[1:]
		if haveTypeProblem(set, restOfLine) {
			// error logging happens in the helper function
			// TODO send error snapshot
			line, readIndex = nextCreateLine(readIndex, saveFile)
			continue
		}

		// 3.2 get desired members from cache
		var membersToAdd map[string]struct{}
		if set.Kind == HashSet {
			membersToAdd = make(map[string]struct{}, len(set.IPPodKey))
			for ip := range set.IPPodKey {
				membersToAdd[ip] = struct{}{}
			}
		} else {
			membersToAdd = make(map[string]struct{}, len(set.IPPodKey))
			for _, member := range set.MemberIPSets {
				membersToAdd[member.HashedName] = struct{}{}
			}
		}

		// 3.4 determine which members to add/delete
		membersToDelete := make(map[string]struct{})
		for readIndex < len(saveFile) {
			line, readIndex = parse.Line(readIndex, saveFile)
			if hasPrefix(line, createStringWithSpace) {
				break
			}
			if !hasPrefix(line, addStringWithSpace) {
				metrics.SendErrorLogAndMetric(util.IpsmID, "expected an add line, but got the following line: %s", string(line))
				// TODO send error snapshot
				line, readIndex = nextCreateLine(readIndex, saveFile)
				break
			}
			lineAfterAdd := string(line[len(addStringWithSpace):])
			spaceSplitLineAfterAdd := strings.Split(lineAfterAdd, space)
			parent := spaceSplitLineAfterAdd[0]
			if len(spaceSplitLineAfterAdd) != 2 || parent != hashedName {
				metrics.SendErrorLogAndMetric(util.IpsmID, "expected an add line for set %s in ipset save file, but got the following line: %s", hashedName, string(line))
				// TODO send error snapshot
				line, readIndex = nextCreateLine(readIndex, saveFile)
				break
			}
			member := spaceSplitLineAfterAdd[1]

			_, shouldKeep := membersToAdd[member]
			if shouldKeep {
				// member already in the kernel, so don't add it later
				delete(membersToAdd, member)
			} else {
				// member should be deleted from the kernel
				membersToDelete[member] = struct{}{}
			}
		}

		// 3.5 delete undesired members from restore file
		sectionID := sectionID(addOrUpdateSectionPrefix, prefixedName)
		for member := range membersToDelete {
			iMgr.deleteMemberForApply(creator, set, sectionID, member)
		}
		// 3.5 add new members to restore file
		for member := range membersToAdd {
			iMgr.addMemberForApply(creator, set, sectionID, member)
		}
	}
}