github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/internal/enforcer/acls/aclcache.go (about) 1 package acls 2 3 import ( 4 "errors" 5 "net" 6 7 "go.aporeto.io/enforcerd/trireme-lib/policy" 8 ) 9 10 // ACLCache holds all the ACLS in an internal DB 11 // map[prefixes][subnets] -> list of ports with their actions 12 type ACLCache struct { 13 reject *acl 14 accept *acl 15 observe *acl 16 } 17 18 // NewACLCache a new ACL cache 19 func NewACLCache() *ACLCache { 20 return &ACLCache{ 21 reject: newACL(), 22 accept: newACL(), 23 observe: newACL(), 24 } 25 } 26 27 // AddRule adds a single rule to the ACL Cache 28 func (c *ACLCache) AddRule(rule policy.IPRule) (err error) { 29 30 if rule.Policy.ObserveAction.ObserveApply() { 31 return c.observe.addRule(rule) 32 } 33 34 if rule.Policy.Action.Accepted() { 35 return c.accept.addRule(rule) 36 } 37 38 return c.reject.addRule(rule) 39 } 40 41 // AddRuleList adds a list of rules to the cache 42 func (c *ACLCache) AddRuleList(rules policy.IPRuleList) (err error) { 43 44 for _, rule := range rules { 45 if err = c.AddRule(rule); err != nil { 46 return 47 } 48 } 49 50 return 51 } 52 53 // RemoveRulesForAddress is going to remove all rules for the provided address, protocol and ports. 54 func (c *ACLCache) RemoveRulesForAddress(address *Address, protocol string, ports []string, policy *policy.FlowPolicy) error { 55 56 if err := c.reject.removeFromCache(address.IP, address.Mask, address.NoMatch, protocol, ports, policy); err != nil { 57 return err 58 } 59 if err := c.accept.removeFromCache(address.IP, address.Mask, address.NoMatch, protocol, ports, policy); err != nil { 60 return err 61 } 62 if err := c.observe.removeFromCache(address.IP, address.Mask, address.NoMatch, protocol, ports, policy); err != nil { 63 return err 64 } 65 return nil 66 } 67 68 // RemoveIPMask removes the entries indexed with (ip, mask). This is an idempotent operation 69 // and thus does not returns an error 70 func (c *ACLCache) RemoveIPMask(ip net.IP, mask int) { 71 72 c.reject.removeIPMask(ip, mask) 73 c.accept.removeIPMask(ip, mask) 74 c.observe.removeIPMask(ip, mask) 75 } 76 77 // GetMatchingAction gets the action from the acl cache 78 func (c *ACLCache) GetMatchingAction(ip net.IP, port uint16, proto uint8, defaultFlowPolicy *policy.FlowPolicy) (report *policy.FlowPolicy, packet *policy.FlowPolicy, err error) { 79 80 report, packet, err = c.reject.getMatchingAction(ip, port, proto, report) 81 if err == nil { 82 return 83 } 84 85 report, packet, err = c.accept.getMatchingAction(ip, port, proto, report) 86 if err == nil { 87 return 88 } 89 90 report, packet, err = c.observe.getMatchingAction(ip, port, proto, report) 91 if err == nil { 92 return 93 } 94 95 if report == nil { 96 report = defaultFlowPolicy 97 } 98 99 if packet == nil { 100 packet = defaultFlowPolicy 101 } 102 103 if defaultFlowPolicy.Action.Accepted() { 104 return report, packet, nil 105 } 106 107 return report, packet, errors.New("no match") 108 } 109 110 // GetMatchingICMPAction gets the action based on icmp policy 111 func (c *ACLCache) GetMatchingICMPAction(ip net.IP, icmpType, icmpCode int8, defaultFlowPolicy *policy.FlowPolicy) (report *policy.FlowPolicy, packet *policy.FlowPolicy, err error) { 112 113 report, packet, err = c.reject.matchICMPRule(ip, icmpType, icmpCode) 114 if err == nil { 115 return 116 } 117 118 report, packet, err = c.accept.matchICMPRule(ip, icmpType, icmpCode) 119 if err == nil { 120 return 121 } 122 123 report, packet, err = c.observe.matchICMPRule(ip, icmpType, icmpCode) 124 if err == nil { 125 return 126 } 127 128 if report == nil { 129 report = defaultFlowPolicy 130 } 131 132 if packet == nil { 133 packet = defaultFlowPolicy 134 } 135 136 if defaultFlowPolicy.Action.Accepted() { 137 return report, packet, nil 138 } 139 140 return report, packet, errors.New("no match") 141 }