github.com/cilium/cilium@v1.16.2/pkg/monitor/api/types.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package api 5 6 import ( 7 "encoding/json" 8 "fmt" 9 "net" 10 "sort" 11 "strconv" 12 "strings" 13 "time" 14 15 "github.com/cilium/cilium/pkg/monitor/notifications" 16 ) 17 18 // Must be synchronized with <bpf/lib/common.h> 19 const ( 20 // 0-128 are reserved for BPF datapath events 21 MessageTypeUnspec = iota 22 23 // MessageTypeDrop is a BPF datapath notification carrying a DropNotify 24 // which corresponds to drop_notify defined in bpf/lib/drop.h 25 MessageTypeDrop 26 27 // MessageTypeDebug is a BPF datapath notification carrying a DebugMsg 28 // which corresponds to debug_msg defined in bpf/lib/dbg.h 29 MessageTypeDebug 30 31 // MessageTypeCapture is a BPF datapath notification carrying a DebugCapture 32 // which corresponds to debug_capture_msg defined in bpf/lib/dbg.h 33 MessageTypeCapture 34 35 // MessageTypeTrace is a BPF datapath notification carrying a TraceNotify 36 // which corresponds to trace_notify defined in bpf/lib/trace.h 37 MessageTypeTrace 38 39 // MessageTypePolicyVerdict is a BPF datapath notification carrying a PolicyVerdictNotify 40 // which corresponds to policy_verdict_notify defined in bpf/lib/policy_log.h 41 MessageTypePolicyVerdict 42 43 // MessageTypeRecCapture is a BPF datapath notification carrying a RecorderCapture 44 // which corresponds to capture_msg defined in bpf/lib/pcap.h 45 MessageTypeRecCapture 46 47 // MessageTypeTraceSock is a BPF datapath notification carrying a TraceNotifySock 48 // which corresponds to trace_sock_notify defined in bpf/lib/trace_sock.h 49 MessageTypeTraceSock 50 51 // 129-255 are reserved for agent level events 52 53 // MessageTypeAccessLog contains a pkg/proxy/accesslog.LogRecord 54 MessageTypeAccessLog = 129 55 56 // MessageTypeAgent is an agent notification carrying a AgentNotify 57 MessageTypeAgent = 130 58 ) 59 60 const ( 61 MessageTypeNameDrop = "drop" 62 MessageTypeNameDebug = "debug" 63 MessageTypeNameCapture = "capture" 64 MessageTypeNameTrace = "trace" 65 MessageTypeNameL7 = "l7" 66 MessageTypeNameAgent = "agent" 67 MessageTypeNamePolicyVerdict = "policy-verdict" 68 MessageTypeNameRecCapture = "recorder" 69 MessageTypeNameTraceSock = "trace-sock" 70 ) 71 72 type MessageTypeFilter []int 73 74 var ( 75 // MessageTypeNames is a map of all type names 76 MessageTypeNames = map[string]int{ 77 MessageTypeNameDrop: MessageTypeDrop, 78 MessageTypeNameDebug: MessageTypeDebug, 79 MessageTypeNameCapture: MessageTypeCapture, 80 MessageTypeNameTrace: MessageTypeTrace, 81 MessageTypeNameL7: MessageTypeAccessLog, 82 MessageTypeNameAgent: MessageTypeAgent, 83 MessageTypeNamePolicyVerdict: MessageTypePolicyVerdict, 84 MessageTypeNameRecCapture: MessageTypeRecCapture, 85 MessageTypeNameTraceSock: MessageTypeTraceSock, 86 } 87 ) 88 89 // AllMessageTypeNames returns a slice of MessageTypeNames 90 func AllMessageTypeNames() []string { 91 names := make([]string, 0, len(MessageTypeNames)) 92 for name := range MessageTypeNames { 93 names = append(names, name) 94 } 95 96 // Sort by the underlying MessageType 97 sort.SliceStable(names, func(i, j int) bool { 98 return MessageTypeNames[names[i]] < MessageTypeNames[names[j]] 99 }) 100 101 return names 102 } 103 104 // MessageTypeName returns the name for a message type or the numeric value if 105 // the name can't be found 106 func MessageTypeName(typ int) string { 107 for name, value := range MessageTypeNames { 108 if value == typ { 109 return name 110 } 111 } 112 113 return strconv.Itoa(typ) 114 } 115 116 func (m *MessageTypeFilter) String() string { 117 pieces := make([]string, 0, len(*m)) 118 for _, typ := range *m { 119 pieces = append(pieces, MessageTypeName(typ)) 120 } 121 122 return strings.Join(pieces, ",") 123 } 124 125 func (m *MessageTypeFilter) Set(value string) error { 126 i, err := MessageTypeNames[value] 127 if !err { 128 return fmt.Errorf("Unknown type (%s). Please use one of the following ones %v", 129 value, MessageTypeNames) 130 } 131 132 *m = append(*m, i) 133 return nil 134 } 135 136 func (m *MessageTypeFilter) Type() string { 137 return "[]string" 138 } 139 140 func (m *MessageTypeFilter) Contains(typ int) bool { 141 for _, v := range *m { 142 if v == typ { 143 return true 144 } 145 } 146 147 return false 148 } 149 150 // Must be synchronized with <bpf/lib/trace.h> 151 const ( 152 TraceToLxc = iota 153 TraceToProxy 154 TraceToHost 155 TraceToStack 156 TraceToOverlay 157 TraceFromLxc 158 TraceFromProxy 159 TraceFromHost 160 TraceFromStack 161 TraceFromOverlay 162 TraceFromNetwork 163 TraceToNetwork 164 ) 165 166 // TraceObservationPoints is a map of all supported trace observation points 167 var TraceObservationPoints = map[uint8]string{ 168 TraceToLxc: "to-endpoint", 169 TraceToProxy: "to-proxy", 170 TraceToHost: "to-host", 171 TraceToStack: "to-stack", 172 TraceToOverlay: "to-overlay", 173 TraceToNetwork: "to-network", 174 TraceFromLxc: "from-endpoint", 175 TraceFromProxy: "from-proxy", 176 TraceFromHost: "from-host", 177 TraceFromStack: "from-stack", 178 TraceFromOverlay: "from-overlay", 179 TraceFromNetwork: "from-network", 180 } 181 182 // TraceObservationPoint returns the name of a trace observation point 183 func TraceObservationPoint(obsPoint uint8) string { 184 if str, ok := TraceObservationPoints[obsPoint]; ok { 185 return str 186 } 187 return fmt.Sprintf("%d", obsPoint) 188 } 189 190 // AgentNotify is a notification from the agent. The notification is stored 191 // in its JSON-encoded representation 192 type AgentNotify struct { 193 Type AgentNotification 194 Text string 195 } 196 197 // AgentNotifyMessage is a notification from the agent. It is similar to 198 // AgentNotify, but the notification is an unencoded struct. See the *Message 199 // constructors in this package for possible values. 200 type AgentNotifyMessage struct { 201 Type AgentNotification 202 Notification interface{} 203 } 204 205 // ToJSON encodes a AgentNotifyMessage to its JSON-based AgentNotify representation 206 func (m *AgentNotifyMessage) ToJSON() (AgentNotify, error) { 207 repr, err := json.Marshal(m.Notification) 208 if err != nil { 209 return AgentNotify{}, err 210 } 211 return AgentNotify{ 212 Type: m.Type, 213 Text: string(repr), 214 }, nil 215 } 216 217 // AgentNotification specifies the type of agent notification 218 type AgentNotification uint32 219 220 const ( 221 AgentNotifyUnspec AgentNotification = iota 222 AgentNotifyGeneric 223 AgentNotifyStart 224 AgentNotifyEndpointRegenerateSuccess 225 AgentNotifyEndpointRegenerateFail 226 AgentNotifyPolicyUpdated 227 AgentNotifyPolicyDeleted 228 AgentNotifyEndpointCreated 229 AgentNotifyEndpointDeleted 230 AgentNotifyIPCacheUpserted 231 AgentNotifyIPCacheDeleted 232 AgentNotifyServiceUpserted 233 AgentNotifyServiceDeleted 234 ) 235 236 // AgentNotifications is a map of all supported agent notification types. 237 var AgentNotifications = map[AgentNotification]string{ 238 AgentNotifyUnspec: "unspecified", 239 AgentNotifyGeneric: "Message", 240 AgentNotifyStart: "Cilium agent started", 241 AgentNotifyEndpointRegenerateSuccess: "Endpoint regenerated", 242 AgentNotifyEndpointCreated: "Endpoint created", 243 AgentNotifyEndpointDeleted: "Endpoint deleted", 244 AgentNotifyEndpointRegenerateFail: "Failed endpoint regeneration", 245 AgentNotifyIPCacheDeleted: "IPCache entry deleted", 246 AgentNotifyIPCacheUpserted: "IPCache entry upserted", 247 AgentNotifyPolicyUpdated: "Policy updated", 248 AgentNotifyPolicyDeleted: "Policy deleted", 249 AgentNotifyServiceDeleted: "Service deleted", 250 AgentNotifyServiceUpserted: "Service upserted", 251 } 252 253 func resolveAgentType(t AgentNotification) string { 254 if n, ok := AgentNotifications[t]; ok { 255 return n 256 } 257 258 return fmt.Sprintf("%d", t) 259 } 260 261 // DumpInfo dumps an agent notification 262 func (n *AgentNotify) DumpInfo() { 263 fmt.Printf(">> %s: %s\n", resolveAgentType(n.Type), n.Text) 264 } 265 266 func (n *AgentNotify) getJSON() string { 267 return fmt.Sprintf(`{"type":"agent","subtype":"%s","message":%s}`, resolveAgentType(n.Type), n.Text) 268 } 269 270 // DumpJSON prints notification in json format 271 func (n *AgentNotify) DumpJSON() { 272 fmt.Println(n.getJSON()) 273 } 274 275 // PolicyUpdateNotification structures update notification 276 type PolicyUpdateNotification struct { 277 Labels []string `json:"labels,omitempty"` 278 Revision uint64 `json:"revision,omitempty"` 279 RuleCount int `json:"rule_count"` 280 } 281 282 // PolicyUpdateMessage constructs an agent notification message for policy updates 283 func PolicyUpdateMessage(numRules int, labels []string, revision uint64) AgentNotifyMessage { 284 notification := PolicyUpdateNotification{ 285 Labels: labels, 286 Revision: revision, 287 RuleCount: numRules, 288 } 289 290 return AgentNotifyMessage{ 291 Type: AgentNotifyPolicyUpdated, 292 Notification: notification, 293 } 294 } 295 296 // PolicyDeleteMessage constructs an agent notification message for policy deletion 297 func PolicyDeleteMessage(deleted int, labels []string, revision uint64) AgentNotifyMessage { 298 notification := PolicyUpdateNotification{ 299 Labels: labels, 300 Revision: revision, 301 RuleCount: deleted, 302 } 303 304 return AgentNotifyMessage{ 305 Type: AgentNotifyPolicyDeleted, 306 Notification: notification, 307 } 308 } 309 310 // EndpointRegenNotification structures regeneration notification 311 type EndpointRegenNotification struct { 312 ID uint64 `json:"id,omitempty"` 313 Labels []string `json:"labels,omitempty"` 314 Error string `json:"error,omitempty"` 315 } 316 317 // EndpointRegenMessage constructs an agent notification message for endpoint regeneration 318 func EndpointRegenMessage(e notifications.RegenNotificationInfo, err error) AgentNotifyMessage { 319 notification := EndpointRegenNotification{ 320 ID: e.GetID(), 321 Labels: e.GetOpLabels(), 322 } 323 324 typ := AgentNotifyEndpointRegenerateSuccess 325 if err != nil { 326 notification.Error = err.Error() 327 typ = AgentNotifyEndpointRegenerateFail 328 } 329 330 return AgentNotifyMessage{ 331 Type: typ, 332 Notification: notification, 333 } 334 } 335 336 // EndpointNotification structures the endpoint create or delete notification 337 type EndpointNotification struct { 338 EndpointRegenNotification 339 PodName string `json:"pod-name,omitempty"` 340 Namespace string `json:"namespace,omitempty"` 341 } 342 343 // EndpointCreateMessage constructs an agent notification message for endpoint creation 344 func EndpointCreateMessage(e notifications.RegenNotificationInfo) AgentNotifyMessage { 345 notification := EndpointNotification{ 346 EndpointRegenNotification: EndpointRegenNotification{ 347 ID: e.GetID(), 348 Labels: e.GetOpLabels(), 349 }, 350 PodName: e.GetK8sPodName(), 351 Namespace: e.GetK8sNamespace(), 352 } 353 354 return AgentNotifyMessage{ 355 Type: AgentNotifyEndpointCreated, 356 Notification: notification, 357 } 358 } 359 360 // EndpointDeleteMessage constructs an agent notification message for endpoint deletion 361 func EndpointDeleteMessage(e notifications.RegenNotificationInfo) AgentNotifyMessage { 362 notification := EndpointNotification{ 363 EndpointRegenNotification: EndpointRegenNotification{ 364 ID: e.GetID(), 365 Labels: e.GetOpLabels(), 366 }, 367 PodName: e.GetK8sPodName(), 368 Namespace: e.GetK8sNamespace(), 369 } 370 371 return AgentNotifyMessage{ 372 Type: AgentNotifyEndpointDeleted, 373 Notification: notification, 374 } 375 } 376 377 // IPCacheNotification structures ipcache change notifications 378 type IPCacheNotification struct { 379 CIDR string `json:"cidr"` 380 Identity uint32 `json:"id"` 381 OldIdentity *uint32 `json:"old-id,omitempty"` 382 383 HostIP net.IP `json:"host-ip,omitempty"` 384 OldHostIP net.IP `json:"old-host-ip,omitempty"` 385 386 EncryptKey uint8 `json:"encrypt-key"` 387 Namespace string `json:"namespace,omitempty"` 388 PodName string `json:"pod-name,omitempty"` 389 } 390 391 // IPCacheUpsertedMessage constructs an agent notification message for ipcache upsertions 392 func IPCacheUpsertedMessage(cidr string, id uint32, oldID *uint32, hostIP net.IP, oldHostIP net.IP, 393 encryptKey uint8, namespace, podName string) AgentNotifyMessage { 394 notification := IPCacheNotification{ 395 CIDR: cidr, 396 Identity: id, 397 OldIdentity: oldID, 398 HostIP: hostIP, 399 OldHostIP: oldHostIP, 400 EncryptKey: encryptKey, 401 Namespace: namespace, 402 PodName: podName, 403 } 404 405 return AgentNotifyMessage{ 406 Type: AgentNotifyIPCacheUpserted, 407 Notification: notification, 408 } 409 } 410 411 // IPCacheDeletedMessage constructs an agent notification message for ipcache deletions 412 func IPCacheDeletedMessage(cidr string, id uint32, oldID *uint32, hostIP net.IP, oldHostIP net.IP, 413 encryptKey uint8, namespace, podName string) AgentNotifyMessage { 414 notification := IPCacheNotification{ 415 CIDR: cidr, 416 Identity: id, 417 OldIdentity: oldID, 418 HostIP: hostIP, 419 OldHostIP: oldHostIP, 420 EncryptKey: encryptKey, 421 Namespace: namespace, 422 PodName: podName, 423 } 424 425 return AgentNotifyMessage{ 426 Type: AgentNotifyIPCacheDeleted, 427 Notification: notification, 428 } 429 } 430 431 // TimeNotification structures agent start notification 432 type TimeNotification struct { 433 Time string `json:"time"` 434 } 435 436 // StartMessage constructs an agent notification message when the agent starts 437 func StartMessage(t time.Time) AgentNotifyMessage { 438 notification := TimeNotification{ 439 Time: t.Format(time.RFC3339Nano), 440 } 441 442 return AgentNotifyMessage{ 443 Type: AgentNotifyStart, 444 Notification: notification, 445 } 446 } 447 448 // ServiceUpsertNotificationAddr is part of ServiceUpsertNotification 449 type ServiceUpsertNotificationAddr struct { 450 IP net.IP `json:"ip"` 451 Port uint16 `json:"port"` 452 } 453 454 // ServiceUpsertNotification structures service upsert notifications 455 type ServiceUpsertNotification struct { 456 ID uint32 `json:"id"` 457 458 Frontend ServiceUpsertNotificationAddr `json:"frontend-address"` 459 Backends []ServiceUpsertNotificationAddr `json:"backend-addresses"` 460 461 Type string `json:"type,omitempty"` 462 // Deprecated: superseded by ExtTrafficPolicy. 463 TrafficPolicy string `json:"traffic-policy,omitempty"` 464 ExtTrafficPolicy string `json:"ext-traffic-policy,omitempty"` 465 IntTrafficPolicy string `json:"int-traffic-policy,omitempty"` 466 467 Name string `json:"name,omitempty"` 468 Namespace string `json:"namespace,,omitempty"` 469 } 470 471 // ServiceUpsertMessage constructs an agent notification message for service upserts 472 func ServiceUpsertMessage( 473 id uint32, 474 frontend ServiceUpsertNotificationAddr, 475 backends []ServiceUpsertNotificationAddr, 476 svcType, svcExtTrafficPolicy, svcIntTrafficPolicy, svcName, svcNamespace string, 477 ) AgentNotifyMessage { 478 notification := ServiceUpsertNotification{ 479 ID: id, 480 Frontend: frontend, 481 Backends: backends, 482 Type: svcType, 483 TrafficPolicy: svcExtTrafficPolicy, 484 ExtTrafficPolicy: svcExtTrafficPolicy, 485 IntTrafficPolicy: svcIntTrafficPolicy, 486 Name: svcName, 487 Namespace: svcNamespace, 488 } 489 490 return AgentNotifyMessage{ 491 Type: AgentNotifyServiceUpserted, 492 Notification: notification, 493 } 494 } 495 496 // ServiceDeleteNotification structures service delete notifications 497 type ServiceDeleteNotification struct { 498 ID uint32 `json:"id"` 499 } 500 501 // ServiceDeleteMessage constructs an agent notification message for service deletions 502 func ServiceDeleteMessage(id uint32) AgentNotifyMessage { 503 notification := ServiceDeleteNotification{ 504 ID: id, 505 } 506 507 return AgentNotifyMessage{ 508 Type: AgentNotifyServiceDeleted, 509 Notification: notification, 510 } 511 } 512 513 const ( 514 // PolicyIngress is the value of Flags&PolicyNotifyFlagDirection for ingress traffic 515 PolicyIngress = 1 516 517 // PolicyEgress is the value of Flags&PolicyNotifyFlagDirection for egress traffic 518 PolicyEgress = 2 519 520 // PolicyMatchNone is the value of MatchType indicatating no policy match 521 PolicyMatchNone = 0 522 523 // PolicyMatchL3Only is the value of MatchType indicating a L3-only match 524 PolicyMatchL3Only = 1 525 526 // PolicyMatchL3L4 is the value of MatchType indicating a L3+L4 match 527 PolicyMatchL3L4 = 2 528 529 // PolicyMatchL4Only is the value of MatchType indicating a L4-only match 530 PolicyMatchL4Only = 3 531 532 // PolicyMatchAll is the value of MatchType indicating an allow-all match 533 PolicyMatchAll = 4 534 535 // PolicyMatchL3Proto is the value of MatchType indicating a L3 and protocol match 536 PolicyMatchL3Proto = 5 537 538 // PolicyMatchProtoOnly is the value of MatchType indicating only a protocol match 539 PolicyMatchProtoOnly = 6 540 ) 541 542 type PolicyMatchType int 543 544 func (m PolicyMatchType) String() string { 545 switch m { 546 case PolicyMatchL3Only: 547 return "L3-Only" 548 case PolicyMatchL3L4: 549 return "L3-L4" 550 case PolicyMatchL4Only: 551 return "L4-Only" 552 case PolicyMatchAll: 553 return "all" 554 case PolicyMatchNone: 555 return "none" 556 case PolicyMatchL3Proto: 557 return "L3-Proto" 558 case PolicyMatchProtoOnly: 559 return "Proto-Only" 560 } 561 return "unknown" 562 }