github.com/aporeto-inc/trireme-lib@v10.358.0+incompatible/controller/pkg/pucontext/pucontext.go (about)

     1  package pucontext
     2  
     3  import (
     4  	"context"
     5  	"crypto/ecdsa"
     6  	"fmt"
     7  	"net"
     8  	"strconv"
     9  	"strings"
    10  	"sync"
    11  	"time"
    12  
    13  	"github.com/minio/minio/pkg/wildcard"
    14  	"go.aporeto.io/enforcerd/trireme-lib/common"
    15  	"go.aporeto.io/enforcerd/trireme-lib/controller/constants"
    16  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/acls"
    17  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/lookup"
    18  	"go.aporeto.io/underwater/core/tagutils"
    19  	"go.uber.org/zap"
    20  
    21  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/nfqdatapath/tokenaccessor"
    22  	"go.aporeto.io/enforcerd/trireme-lib/controller/internal/enforcer/utils/ephemeralkeys"
    23  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/claimsheader"
    24  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/counters"
    25  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/packet"
    26  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/secrets"
    27  	"go.aporeto.io/enforcerd/trireme-lib/controller/pkg/tokens"
    28  	"go.aporeto.io/enforcerd/trireme-lib/policy"
    29  	"go.aporeto.io/enforcerd/trireme-lib/utils/cache"
    30  	"go.aporeto.io/enforcerd/trireme-lib/utils/crypto"
    31  )
    32  
    33  type policies struct {
    34  	observeRejectRules *lookup.PolicyDB // Packet: Continue       Report:    Drop
    35  	rejectRules        *lookup.PolicyDB // Packet:     Drop       Report:    Drop
    36  	observeAcceptRules *lookup.PolicyDB // Packet: Continue       Report: Forward
    37  	acceptRules        *lookup.PolicyDB // Packet:  Forward       Report: Forward
    38  	observeApplyRules  *lookup.PolicyDB // Packet:  Forward       Report: Forward
    39  	encryptRules       *lookup.PolicyDB // Packet: Encrypt       Report: Encrypt
    40  }
    41  
    42  type synTokenInfo struct {
    43  	datapathSecret  secrets.Secrets
    44  	privateKey      *ephemeralkeys.PrivateKey
    45  	publicKeyV1     []byte
    46  	publicKeySignV1 []byte
    47  	publicKeyV2     []byte
    48  	publicKeySignV2 []byte
    49  	token           []byte
    50  }
    51  
    52  // PUContext holds data indexed by the PU ID
    53  type PUContext struct {
    54  	id                      string
    55  	hashID                  string
    56  	username                string
    57  	autoport                bool
    58  	managementID            string
    59  	managementNamespace     string
    60  	managementNamespaceHash string
    61  	identity                *policy.TagStore
    62  	annotations             *policy.TagStore
    63  	compressedTags          *policy.TagStore
    64  	txt                     *policies
    65  	rcv                     *policies
    66  	ApplicationACLs         *acls.ACLCache
    67  	networkACLs             *acls.ACLCache
    68  	externalIPCache         cache.DataStore
    69  	DNSACLs                 policy.DNSRuleList
    70  	DNSProxyPort            string
    71  	mark                    string
    72  	tcpPorts                []string
    73  	udpPorts                []string
    74  	puType                  common.PUType
    75  	jwt                     string
    76  	jwtExpiration           time.Time
    77  	scopes                  []string
    78  	Extension               interface{}
    79  	counters                *counters.Counters
    80  	puInfo                  *policy.PUInfo
    81  	synToken                *synTokenInfo
    82  	ctxCancel               context.CancelFunc
    83  	tokenAccessor           tokenaccessor.TokenAccessor
    84  	appDefaultFlowPolicy    *policy.FlowPolicy
    85  	netDefaultFlowPolicy    *policy.FlowPolicy
    86  	sync.RWMutex
    87  }
    88  
    89  // NewPU creates a new PU context
    90  func NewPU(contextID string, puInfo *policy.PUInfo, tokenAccessor tokenaccessor.TokenAccessor, timeout time.Duration) (*PUContext, error) {
    91  
    92  	hashID, err := policy.Fnv32Hash(contextID)
    93  	if err != nil {
    94  		return nil, fmt.Errorf("unable to hash contextID: %v", err)
    95  	}
    96  
    97  	pu := &PUContext{
    98  		id:                   contextID,
    99  		hashID:               hashID,
   100  		username:             puInfo.Runtime.Options().UserID,
   101  		autoport:             puInfo.Runtime.Options().AutoPort,
   102  		managementID:         puInfo.Policy.ManagementID(),
   103  		managementNamespace:  puInfo.Policy.ManagementNamespace(),
   104  		puType:               puInfo.Runtime.PUType(),
   105  		identity:             puInfo.Policy.Identity(),
   106  		annotations:          puInfo.Policy.Annotations(),
   107  		compressedTags:       puInfo.Policy.CompressedTags(),
   108  		externalIPCache:      cache.NewCacheWithExpiration("External IP Cache", timeout),
   109  		ApplicationACLs:      acls.NewACLCache(),
   110  		networkACLs:          acls.NewACLCache(),
   111  		DNSACLs:              puInfo.Policy.DNSNameACLs(),
   112  		mark:                 puInfo.Runtime.Options().CgroupMark,
   113  		scopes:               puInfo.Policy.Scopes(),
   114  		counters:             counters.NewCounters(),
   115  		puInfo:               puInfo,
   116  		tokenAccessor:        tokenAccessor,
   117  		appDefaultFlowPolicy: &policy.FlowPolicy{Action: puInfo.Policy.AppDefaultPolicyAction(), PolicyID: "default", ServiceID: "default"},
   118  		netDefaultFlowPolicy: &policy.FlowPolicy{Action: puInfo.Policy.NetDefaultPolicyAction(), PolicyID: "default", ServiceID: "default"},
   119  	}
   120  
   121  	pu.CreateRcvRules(puInfo.Policy.ReceiverRules())
   122  
   123  	pu.CreateTxtRules(puInfo.Policy.TransmitterRules())
   124  
   125  	tcpPorts, udpPorts := common.ConvertServicesToProtocolPortList(puInfo.Runtime.Options().Services)
   126  	pu.tcpPorts = strings.Split(tcpPorts, ",")
   127  	pu.udpPorts = strings.Split(udpPorts, ",")
   128  
   129  	if err := pu.UpdateApplicationACLs(puInfo.Policy.ApplicationACLs()); err != nil {
   130  		return nil, err
   131  	}
   132  
   133  	if err := pu.UpdateNetworkACLs(puInfo.Policy.NetworkACLs()); err != nil {
   134  		return nil, err
   135  	}
   136  
   137  	nsHash, err := tagutils.Hash(pu.managementNamespace)
   138  	if err != nil {
   139  		return nil, fmt.Errorf("unable to hash namespace: %w", err)
   140  	}
   141  	pu.managementNamespaceHash = nsHash
   142  
   143  	ctx, cancel := context.WithCancel(context.Background())
   144  	pu.ctxCancel = cancel
   145  
   146  	// tokenAccessor is nil with envoy authorizer enforcer. We
   147  	// don't need our datapath in that case.
   148  	if tokenAccessor != nil {
   149  		pu.synToken = pu.createSynToken(nil, claimsheader.NewClaimsHeader())
   150  
   151  		go func() {
   152  			for {
   153  				select {
   154  				case <-ctx.Done():
   155  					return
   156  				case <-time.After(constants.SynTokenRefreshTime):
   157  
   158  					synToken := pu.createSynToken(nil, claimsheader.NewClaimsHeader())
   159  					pu.Lock()
   160  					pu.synToken = synToken
   161  					pu.Unlock()
   162  				}
   163  			}
   164  		}()
   165  	}
   166  
   167  	return pu, nil
   168  }
   169  
   170  func (p *PUContext) createSynToken(pingPayload *policy.PingPayload, claimsHeader *claimsheader.ClaimsHeader) *synTokenInfo {
   171  
   172  	var datapathKeyPair ephemeralkeys.KeyAccessor
   173  	var err error
   174  	var nonce []byte
   175  
   176  	for {
   177  		datapathKeyPair, err = ephemeralkeys.New()
   178  
   179  		if err != nil {
   180  			// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   181  			time.Sleep(10 * time.Millisecond)
   182  			continue
   183  		}
   184  
   185  		break
   186  	}
   187  
   188  	for {
   189  		// can generate errors only when the urandom io read buffer is full. retry till we succeed.
   190  		nonce, err = crypto.GenerateRandomBytes(16)
   191  		if err != nil {
   192  			continue
   193  		}
   194  
   195  		break
   196  	}
   197  
   198  	claims := &tokens.ConnectionClaims{
   199  		LCL:   nonce,
   200  		DEKV1: datapathKeyPair.DecodingKeyV1(),
   201  		DEKV2: datapathKeyPair.DecodingKeyV2(),
   202  		CT:    p.CompressedTags(),
   203  		ID:    p.ManagementID(),
   204  		P:     pingPayload,
   205  	}
   206  
   207  	datapathSecret := ephemeralkeys.GetDatapathSecret()
   208  	var encodedBuf [tokens.ClaimsEncodedBufSize]byte
   209  
   210  	token, err := p.tokenAccessor.CreateSynPacketToken(claims, encodedBuf[:], nonce, claimsHeader, datapathSecret)
   211  	if err != nil {
   212  		zap.L().Error("Can not create syn packet token", zap.Error(err))
   213  		return nil
   214  	}
   215  
   216  	ephKeySignV1, err := p.tokenAccessor.Sign(datapathKeyPair.DecodingKeyV1(), datapathSecret.EncodingKey().(*ecdsa.PrivateKey))
   217  	if err != nil {
   218  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   219  		return nil
   220  	}
   221  
   222  	ephKeySignV2, err := p.tokenAccessor.Sign(datapathKeyPair.DecodingKeyV2(), datapathSecret.EncodingKey().(*ecdsa.PrivateKey))
   223  	if err != nil {
   224  		zap.L().Error("Can not sign the ephemeral public key", zap.Error(err))
   225  		return nil
   226  	}
   227  
   228  	privateKey := datapathKeyPair.PrivateKey()
   229  	return &synTokenInfo{datapathSecret: datapathSecret,
   230  		privateKey:      privateKey,
   231  		publicKeyV1:     datapathKeyPair.DecodingKeyV1(),
   232  		publicKeySignV1: ephKeySignV1,
   233  		publicKeyV2:     datapathKeyPair.DecodingKeyV2(),
   234  		publicKeySignV2: ephKeySignV2,
   235  		token:           token}
   236  }
   237  
   238  //StopProcessing cancels the context such that all the goroutines can return.
   239  func (p *PUContext) StopProcessing() {
   240  	p.ctxCancel()
   241  }
   242  
   243  //GetSynToken returns the cached syntoken if the datapath secret has not changed or the ping payload is present.
   244  func (p *PUContext) GetSynToken(pingPayload *policy.PingPayload, nonce [16]byte, claimsHeader *claimsheader.ClaimsHeader) (secrets.Secrets, *ephemeralkeys.PrivateKey, []byte) {
   245  
   246  	if pingPayload != nil {
   247  		synToken := p.createSynToken(pingPayload, claimsHeader)
   248  		return synToken.datapathSecret, synToken.privateKey, synToken.token
   249  	}
   250  
   251  	p.RLock()
   252  	synToken := p.synToken
   253  	p.RUnlock()
   254  
   255  	if synToken.datapathSecret != ephemeralkeys.GetDatapathSecret() {
   256  		synToken = p.createSynToken(nil, claimsheader.NewClaimsHeader())
   257  		p.Lock()
   258  		p.synToken = synToken
   259  		p.Unlock()
   260  	}
   261  
   262  	p.tokenAccessor.Randomize(synToken.token, nonce[:]) //nolint
   263  
   264  	return synToken.datapathSecret, synToken.privateKey, synToken.token
   265  }
   266  
   267  //GetSecrets returns the datapath secret and ephemeral public and private key
   268  func (p *PUContext) GetSecrets() (secrets.Secrets, *ephemeralkeys.PrivateKey, []byte, []byte, []byte, []byte) {
   269  	p.RLock()
   270  	synToken := p.synToken
   271  	p.RUnlock()
   272  
   273  	if synToken.datapathSecret != ephemeralkeys.GetDatapathSecret() {
   274  		synToken = p.createSynToken(nil, claimsheader.NewClaimsHeader())
   275  		p.Lock()
   276  		p.synToken = synToken
   277  		p.Unlock()
   278  	}
   279  
   280  	return ephemeralkeys.GetDatapathSecret(), synToken.privateKey, synToken.publicKeyV1, synToken.publicKeySignV1, synToken.publicKeyV2, synToken.publicKeySignV2
   281  }
   282  
   283  // GetPolicyFromFQDN gets the list of policies that are mapped with the hostname
   284  func (p *PUContext) GetPolicyFromFQDN(fqdn string) ([]policy.PortProtocolPolicy, string, error) {
   285  	p.RLock()
   286  	defer p.RUnlock()
   287  
   288  	// If we find a direct match, return policy
   289  	if v, ok := p.DNSACLs[fqdn]; ok {
   290  		return v, fqdn, nil
   291  	}
   292  
   293  	// Try if there is a wildcard match
   294  	for policyName, policy := range p.DNSACLs {
   295  		if wildcard.MatchSimple(policyName, fqdn) {
   296  			return policy, policyName, nil
   297  		}
   298  	}
   299  
   300  	return nil, "", fmt.Errorf("Policy doesn't exist")
   301  }
   302  
   303  // DependentServices searches if the PU has a dependent service on this FQDN. If yes,
   304  // it returns the ports for that service.
   305  func (p *PUContext) DependentServices(fqdn string) []*policy.ApplicationService {
   306  	p.RLock()
   307  	defer p.RUnlock()
   308  
   309  	dependentServices := []*policy.ApplicationService{}
   310  
   311  	for _, dependentService := range p.puInfo.Policy.DependentServices() {
   312  		for _, name := range dependentService.NetworkInfo.FQDNs {
   313  			if fqdn == name {
   314  				dependentServices = append(dependentServices, dependentService)
   315  			}
   316  		}
   317  	}
   318  
   319  	return dependentServices
   320  }
   321  
   322  // UsesFQDN indicates whether this PU policy has an ACL or Service that uses an FQDN
   323  func (p *PUContext) UsesFQDN() bool {
   324  	p.RLock()
   325  	defer p.RUnlock()
   326  
   327  	if len(p.DNSACLs) > 0 {
   328  		return true
   329  	}
   330  
   331  	for _, dependentService := range p.puInfo.Policy.DependentServices() {
   332  		for _, name := range dependentService.NetworkInfo.FQDNs {
   333  			if name != "" {
   334  				return true
   335  			}
   336  		}
   337  	}
   338  
   339  	return false
   340  }
   341  
   342  // ID returns the ID of the PU
   343  func (p *PUContext) ID() string {
   344  	return p.id
   345  }
   346  
   347  // HashID returns the hash of the ID of the PU
   348  func (p *PUContext) HashID() string {
   349  	return p.hashID
   350  }
   351  
   352  // Username returns the ID of the PU
   353  func (p *PUContext) Username() string {
   354  	return p.username
   355  }
   356  
   357  // Autoport returns if auto port feature is set on the PU
   358  func (p *PUContext) Autoport() bool {
   359  	return p.autoport
   360  }
   361  
   362  // ManagementID returns the management ID
   363  func (p *PUContext) ManagementID() string {
   364  	return p.managementID
   365  }
   366  
   367  // ManagementNamespace returns the management namespace
   368  func (p *PUContext) ManagementNamespace() string {
   369  	return p.managementNamespace
   370  }
   371  
   372  // ManagementNamespaceHash returns the management namespace hash
   373  func (p *PUContext) ManagementNamespaceHash() string {
   374  	return p.managementNamespaceHash
   375  }
   376  
   377  // Type return the pu type
   378  func (p *PUContext) Type() common.PUType {
   379  	return p.puType
   380  }
   381  
   382  // Identity returns the indentity
   383  func (p *PUContext) Identity() *policy.TagStore {
   384  	return p.identity
   385  }
   386  
   387  // Mark returns the PU mark
   388  func (p *PUContext) Mark() string {
   389  	return p.mark
   390  }
   391  
   392  // TCPPorts returns the PU TCP ports
   393  func (p *PUContext) TCPPorts() []string {
   394  	return p.tcpPorts
   395  }
   396  
   397  // UDPPorts returns the PU UDP ports
   398  func (p *PUContext) UDPPorts() []string {
   399  	return p.udpPorts
   400  }
   401  
   402  // Annotations returns the annotations
   403  func (p *PUContext) Annotations() *policy.TagStore {
   404  	return p.annotations
   405  }
   406  
   407  // CompressedTags returns the compressed tags.
   408  func (p *PUContext) CompressedTags() *policy.TagStore {
   409  	return p.compressedTags
   410  }
   411  
   412  // RetrieveCachedExternalFlowPolicy returns the policy for an external IP
   413  func (p *PUContext) RetrieveCachedExternalFlowPolicy(id string) (interface{}, error) {
   414  	return p.externalIPCache.Get(id)
   415  }
   416  
   417  // NetworkACLPolicy retrieves the policy based on ACLs
   418  func (p *PUContext) NetworkACLPolicy(packet *packet.Packet) (report *policy.FlowPolicy, action *policy.FlowPolicy, err error) {
   419  	defer p.RUnlock()
   420  	p.RLock()
   421  
   422  	return p.networkACLs.GetMatchingAction(packet.SourceAddress(), packet.DestPort(), packet.IPProto(), p.netDefaultFlowPolicy)
   423  }
   424  
   425  // NetworkACLPolicyFromAddr retrieve the policy given an address and port.
   426  func (p *PUContext) NetworkACLPolicyFromAddr(addr net.IP, port uint16, protocol uint8) (report *policy.FlowPolicy, action *policy.FlowPolicy, err error) {
   427  	defer p.RUnlock()
   428  	p.RLock()
   429  
   430  	return p.networkACLs.GetMatchingAction(addr, port, protocol, p.netDefaultFlowPolicy)
   431  }
   432  
   433  // ApplicationICMPACLPolicy retrieve the policy for ICMP
   434  func (p *PUContext) ApplicationICMPACLPolicy(ip net.IP, icmpType, icmpCode int8) (report *policy.FlowPolicy, action *policy.FlowPolicy, err error) {
   435  	return p.ApplicationACLs.GetMatchingICMPAction(ip, icmpType, icmpCode, p.appDefaultFlowPolicy)
   436  }
   437  
   438  // NetworkICMPACLPolicy retrieve the policy for ICMP
   439  func (p *PUContext) NetworkICMPACLPolicy(ip net.IP, icmpType, icmpCode int8) (report *policy.FlowPolicy, action *policy.FlowPolicy, err error) {
   440  	return p.networkACLs.GetMatchingICMPAction(ip, icmpType, icmpCode, p.netDefaultFlowPolicy)
   441  }
   442  
   443  // ApplicationACLPolicyFromAddr retrieve the policy given an address and port.
   444  func (p *PUContext) ApplicationACLPolicyFromAddr(addr net.IP, port uint16, protocol uint8) (report *policy.FlowPolicy, action *policy.FlowPolicy, err error) {
   445  	defer p.RUnlock()
   446  	p.RLock()
   447  
   448  	return p.ApplicationACLs.GetMatchingAction(addr, port, protocol, p.appDefaultFlowPolicy)
   449  }
   450  
   451  // UpdateApplicationACLs updates the application ACL policy
   452  func (p *PUContext) UpdateApplicationACLs(rules policy.IPRuleList) error {
   453  	defer p.Unlock()
   454  	p.Lock()
   455  
   456  	return p.ApplicationACLs.AddRuleList(rules)
   457  }
   458  
   459  // FlushApplicationACL removes the application ACLs which are indexed with (ip, mask) key for all protocols and ports
   460  func (p *PUContext) FlushApplicationACL(addr net.IP, mask int) {
   461  	defer p.Unlock()
   462  	p.Lock()
   463  	p.ApplicationACLs.RemoveIPMask(addr, mask)
   464  }
   465  
   466  // RemoveApplicationACL removes the application ACLs for a specific IP address for all protocols and ports that match a policy.
   467  // NOTE: Rules need to be a full port/policy match in order to get removed. Partial port matches in ranges will not get removed.
   468  func (p *PUContext) RemoveApplicationACL(ipaddress string, protocols, ports []string, policy *policy.FlowPolicy) error {
   469  	defer p.Unlock()
   470  	p.Lock()
   471  
   472  	address, err := acls.ParseAddress(ipaddress)
   473  	if err != nil {
   474  		return err
   475  	}
   476  
   477  	for _, protocol := range protocols {
   478  		if err := p.ApplicationACLs.RemoveRulesForAddress(address, protocol, ports, policy); err != nil {
   479  			return err
   480  		}
   481  	}
   482  	return nil
   483  }
   484  
   485  // UpdateNetworkACLs updates the network ACL policy
   486  func (p *PUContext) UpdateNetworkACLs(rules policy.IPRuleList) error {
   487  	defer p.Unlock()
   488  	p.Lock()
   489  	return p.networkACLs.AddRuleList(rules)
   490  }
   491  
   492  // CacheExternalFlowPolicy will cache an external flow
   493  func (p *PUContext) CacheExternalFlowPolicy(packet *packet.Packet, plc interface{}) {
   494  	p.externalIPCache.AddOrUpdate(packet.SourceAddress().String()+":"+strconv.Itoa(int(packet.SourcePort())), plc)
   495  }
   496  
   497  // GetProcessKeys returns the cache keys for a process
   498  func (p *PUContext) GetProcessKeys() (string, []string, []string) {
   499  	return p.mark, p.tcpPorts, p.udpPorts
   500  }
   501  
   502  // Scopes returns the scopes.
   503  func (p *PUContext) Scopes() []string {
   504  	p.RLock()
   505  	defer p.RUnlock()
   506  
   507  	return p.scopes
   508  }
   509  
   510  // Counters returns the scopes.
   511  func (p *PUContext) Counters() *counters.Counters {
   512  	p.RLock()
   513  	defer p.RUnlock()
   514  
   515  	return p.counters
   516  }
   517  
   518  // GetJWT retrieves the JWT if it exists in the cache. Returns error otherwise.
   519  func (p *PUContext) GetJWT() (string, error) {
   520  	p.RLock()
   521  	defer p.RUnlock()
   522  
   523  	if p.jwtExpiration.After(time.Now()) && len(p.jwt) > 0 {
   524  		return p.jwt, nil
   525  	}
   526  
   527  	return "", fmt.Errorf("expired token")
   528  }
   529  
   530  // UpdateJWT updates the JWT and provides a new expiration date.
   531  func (p *PUContext) UpdateJWT(jwt string, expiration time.Time) {
   532  	p.Lock()
   533  	defer p.Unlock()
   534  
   535  	p.jwt = jwt
   536  	p.jwtExpiration = expiration
   537  }
   538  
   539  // createRuleDBs creates the database of rules from the policy
   540  func (p *PUContext) createRuleDBs(policyRules policy.TagSelectorList) *policies {
   541  
   542  	policyDB := &policies{
   543  		rejectRules:        lookup.NewPolicyDB(),
   544  		observeRejectRules: lookup.NewPolicyDB(),
   545  		acceptRules:        lookup.NewPolicyDB(),
   546  		observeAcceptRules: lookup.NewPolicyDB(),
   547  		observeApplyRules:  lookup.NewPolicyDB(),
   548  		encryptRules:       lookup.NewPolicyDB(),
   549  	}
   550  
   551  	for _, rule := range policyRules {
   552  		// Add encrypt rule to encrypt table.
   553  		if rule.Policy.Action.Encrypted() {
   554  			policyDB.encryptRules.AddPolicy(rule)
   555  		}
   556  
   557  		if rule.Policy.ObserveAction.ObserveContinue() {
   558  			if rule.Policy.Action.Accepted() {
   559  				policyDB.observeAcceptRules.AddPolicy(rule)
   560  			} else if rule.Policy.Action.Rejected() {
   561  				policyDB.observeRejectRules.AddPolicy(rule)
   562  			}
   563  		} else if rule.Policy.ObserveAction.ObserveApply() {
   564  			policyDB.observeApplyRules.AddPolicy(rule)
   565  		} else if rule.Policy.Action.Accepted() {
   566  			policyDB.acceptRules.AddPolicy(rule)
   567  		} else if rule.Policy.Action.Rejected() {
   568  			policyDB.rejectRules.AddPolicy(rule)
   569  		} else {
   570  			continue
   571  		}
   572  	}
   573  	return policyDB
   574  }
   575  
   576  // CreateRcvRules create receive rules for this PU based on the update of the policy.
   577  func (p *PUContext) CreateRcvRules(policyRules policy.TagSelectorList) {
   578  	p.rcv = p.createRuleDBs(policyRules)
   579  }
   580  
   581  // CreateTxtRules create receive rules for this PU based on the update of the policy.
   582  func (p *PUContext) CreateTxtRules(policyRules policy.TagSelectorList) {
   583  	p.txt = p.createRuleDBs(policyRules)
   584  }
   585  
   586  // searchRules searches all reject, accpet and observed rules and returns reporting and packet forwarding action
   587  func (p *PUContext) searchRules(
   588  	policies *policies,
   589  	tags *policy.TagStore,
   590  	skipRejectPolicies bool,
   591  	defaultFlowReport *policy.FlowPolicy,
   592  ) (report *policy.FlowPolicy, packet *policy.FlowPolicy) {
   593  
   594  	var reportingAction *policy.FlowPolicy
   595  	var packetAction *policy.FlowPolicy
   596  
   597  	if !skipRejectPolicies {
   598  		// Look for rejection rules
   599  		observeIndex, observeAction := policies.observeRejectRules.Search(tags)
   600  		if observeIndex >= 0 {
   601  			reportingAction = observeAction.(*policy.FlowPolicy)
   602  		}
   603  
   604  		index, action := policies.rejectRules.Search(tags)
   605  		if index >= 0 {
   606  			packetAction = action.(*policy.FlowPolicy)
   607  			if reportingAction == nil {
   608  				reportingAction = packetAction
   609  			}
   610  			return reportingAction, packetAction
   611  		}
   612  	}
   613  
   614  	if reportingAction == nil {
   615  		// Look for allow rules
   616  		observeIndex, observeAction := policies.observeAcceptRules.Search(tags)
   617  		if observeIndex >= 0 {
   618  			reportingAction = observeAction.(*policy.FlowPolicy)
   619  		}
   620  	}
   621  
   622  	index, action := policies.acceptRules.Search(tags)
   623  	if index >= 0 {
   624  		packetAction = action.(*policy.FlowPolicy)
   625  		// Look for encrypt rules
   626  		encryptIndex, _ := policies.encryptRules.Search(tags)
   627  		if encryptIndex >= 0 {
   628  			// Do not overwrite the action for accept rules.
   629  			finalAction := action.(*policy.FlowPolicy)
   630  			packetAction = &policy.FlowPolicy{
   631  				Action:    policy.Accept | policy.Encrypt,
   632  				PolicyID:  finalAction.PolicyID,
   633  				ServiceID: finalAction.ServiceID,
   634  			}
   635  			if finalAction.Action.Logged() {
   636  				packetAction.Action = packetAction.Action | policy.Log
   637  			}
   638  		}
   639  		if reportingAction == nil {
   640  			reportingAction = packetAction
   641  		}
   642  		return reportingAction, packetAction
   643  	}
   644  
   645  	// Look for observe apply rules
   646  	observeIndex, observeAction := policies.observeApplyRules.Search(tags)
   647  	if observeIndex >= 0 {
   648  		packetAction = observeAction.(*policy.FlowPolicy)
   649  		if reportingAction == nil {
   650  			reportingAction = packetAction
   651  		}
   652  		return reportingAction, packetAction
   653  	}
   654  
   655  	// Clone the default because someone is changing the returned one
   656  	packetAction = defaultFlowReport.Clone()
   657  
   658  	if reportingAction == nil {
   659  		reportingAction = packetAction
   660  	}
   661  
   662  	return reportingAction, packetAction
   663  }
   664  
   665  // SearchTxtRules searches both receive and observed transmit rules and returns the index and action
   666  func (p *PUContext) SearchTxtRules(
   667  	tags *policy.TagStore,
   668  	skipRejectPolicies bool,
   669  ) (report *policy.FlowPolicy, packet *policy.FlowPolicy) {
   670  	return p.searchRules(p.txt, tags, skipRejectPolicies, p.appDefaultFlowPolicy)
   671  }
   672  
   673  // SearchRcvRules searches both receive and observed receive rules and returns the index and action
   674  func (p *PUContext) SearchRcvRules(
   675  	tags *policy.TagStore,
   676  ) (report *policy.FlowPolicy, packet *policy.FlowPolicy) {
   677  	return p.searchRules(p.rcv, tags, false, p.netDefaultFlowPolicy)
   678  }
   679  
   680  // LookupLogPrefix lookup the log prefix from the key
   681  func (p *PUContext) LookupLogPrefix(key string) (string, bool) {
   682  	p.Lock()
   683  	defer p.Unlock()
   684  	if p.puInfo == nil || p.puInfo.Policy == nil {
   685  		return "", false
   686  	}
   687  	return p.puInfo.Policy.LookupLogPrefix(key)
   688  }