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)
}
}
}