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 }