github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/utils/frontman/rulecleanup_windows.go (about) 1 // +build windows 2 3 package frontman 4 5 import ( 6 "strings" 7 ) 8 9 type ruleCleanup interface { 10 mapIpsetToRule(ipsetName string, filterName, criteriaName string) 11 deleteRulesForIpset(wrapDriver WrapDriver, ipsetName string) error 12 deleteRuleForIpsetByPrefix(wrapDriver WrapDriver, prefix string) error 13 deleteRuleFromIpsetMap(filterName, criteriaName string) 14 getRulesForIpset(ipsetName string) []*filterRulePair 15 } 16 17 type ruleCleaner struct { 18 ipsetToRule map[string][]*filterRulePair 19 } 20 21 type filterRulePair struct { 22 filterName string 23 ruleCriteria string 24 } 25 26 func newRuleCleanup() ruleCleanup { 27 return &ruleCleaner{ 28 ipsetToRule: make(map[string][]*filterRulePair), 29 } 30 } 31 32 // We keep a map of ipset name to rules. This is a safeguard to ensure that rules are deleted. 33 // Normally, during policy update, rules and ipsets are deleted explicitly and all works well. 34 // There are some instances though (Discovery Mode) where criteria name strings use in deletion 35 // do not align with criteria name strings used during addition. This will result in rules 36 // stranded in our driver, which is really bad for multiple reasons. 37 // Since deletion of ipsets is more orderly than deletion of rules by criteria name, and since 38 // the rules that are subject to being stranded are all so far associated with an ephemeral ipset, 39 // we can use the deletion of an ipset to trigger a cleanup of all rules associated with it. 40 41 func (r *ruleCleaner) mapIpsetToRule(ipsetName string, filterName, criteriaName string) { 42 r.ipsetToRule[ipsetName] = append(r.ipsetToRule[ipsetName], &filterRulePair{filterName: filterName, ruleCriteria: criteriaName}) 43 } 44 45 func (r *ruleCleaner) deleteRulesForIpset(wrapDriver WrapDriver, ipsetName string) error { 46 for _, frpair := range r.ipsetToRule[ipsetName] { 47 // In recent changes, these rule are already gone, so don't log an error if this fails. 48 wrapDriver.DeleteFilterCriteria(frpair.filterName, frpair.ruleCriteria) //nolint 49 } 50 delete(r.ipsetToRule, ipsetName) 51 return nil 52 } 53 54 func (r *ruleCleaner) deleteRuleForIpsetByPrefix(wrapDriver WrapDriver, prefix string) error { 55 56 ipsets, err := wrapDriver.ListIpsets() 57 if err != nil { 58 return err 59 } 60 for _, ipsetName := range ipsets { 61 if strings.HasPrefix(ipsetName, prefix) { 62 if err := r.deleteRulesForIpset(wrapDriver, ipsetName); err != nil { 63 return err 64 } 65 } 66 } 67 return nil 68 } 69 70 func (r *ruleCleaner) deleteRuleFromIpsetMap(filterName, criteriaName string) { 71 // quadratic for now, optimize later if we need to 72 for ipsetName, frpairs := range r.ipsetToRule { 73 for i, frpair := range frpairs { 74 if frpair.filterName == filterName && frpair.ruleCriteria == criteriaName { 75 // delete pair from slice 76 frpairs[i] = frpairs[len(frpairs)-1] 77 r.ipsetToRule[ipsetName] = frpairs[:len(frpairs)-1] 78 // rule can be mapped from multiple ipsets, so continue our outer loop 79 break 80 } 81 } 82 } 83 } 84 85 func (r *ruleCleaner) getRulesForIpset(ipsetName string) []*filterRulePair { 86 frpairs := r.ipsetToRule[ipsetName] 87 result := make([]*filterRulePair, len(frpairs)) 88 copy(result, frpairs) 89 return result 90 }