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  }