github.com/fafucoder/cilium@v1.6.11/pkg/monitor/datapath_trace.go (about) 1 // Copyright 2016-2018 Authors of Cilium 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package monitor 16 17 import ( 18 "encoding/json" 19 "fmt" 20 ) 21 22 const ( 23 // TraceNotifyLen is the amount of packet data provided in a trace notification 24 TraceNotifyLen = 32 25 // TraceReasonEncryptMask is the bit used to indicate encryption or not 26 TraceReasonEncryptMask uint8 = 0x80 27 ) 28 29 // TraceNotify is the message format of a trace notification in the BPF ring buffer 30 type TraceNotify struct { 31 Type uint8 32 ObsPoint uint8 33 Source uint16 34 Hash uint32 35 OrigLen uint32 36 CapLen uint32 37 SrcLabel uint32 38 DstLabel uint32 39 DstID uint16 40 Reason uint8 41 Pad uint8 42 Ifindex uint32 43 // data 44 } 45 46 // Available observation points. 47 const ( 48 TraceToLxc = iota 49 TraceToProxy 50 TraceToHost 51 TraceToStack 52 TraceToOverlay 53 TraceFromLxc 54 TraceFromProxy 55 TraceFromHost 56 TraceFromStack 57 TraceFromOverlay 58 TraceFromNetwork 59 ) 60 61 var traceObsPoints = map[uint8]string{ 62 TraceToLxc: "to-endpoint", 63 TraceToProxy: "to-proxy", 64 TraceToHost: "to-host", 65 TraceToStack: "to-stack", 66 TraceToOverlay: "to-overlay", 67 TraceFromLxc: "from-endpoint", 68 TraceFromProxy: "from-proxy", 69 TraceFromHost: "from-host", 70 TraceFromStack: "from-stack", 71 TraceFromOverlay: "from-overlay", 72 TraceFromNetwork: "from-network", 73 } 74 75 func obsPoint(obsPoint uint8) string { 76 if str, ok := traceObsPoints[obsPoint]; ok { 77 return str 78 } 79 return fmt.Sprintf("%d", obsPoint) 80 } 81 82 // Reasons for forwarding a packet. 83 const ( 84 TraceReasonPolicy = iota 85 TraceReasonCtEstablished 86 TraceReasonCtReply 87 TraceReasonCtRelated 88 ) 89 90 var traceReasons = map[uint8]string{ 91 TraceReasonPolicy: "new", 92 TraceReasonCtEstablished: "established", 93 TraceReasonCtReply: "reply", 94 TraceReasonCtRelated: "related", 95 } 96 97 func connState(reason uint8) string { 98 r := reason & ^TraceReasonEncryptMask 99 if str, ok := traceReasons[r]; ok { 100 return str 101 } 102 return fmt.Sprintf("%d", reason) 103 } 104 105 func (n *TraceNotify) encryptReason() string { 106 if (n.Reason & TraceReasonEncryptMask) != 0 { 107 return fmt.Sprintf("encrypted ") 108 } 109 return "" 110 } 111 112 func (n *TraceNotify) traceReason() string { 113 return connState(n.Reason) 114 } 115 116 func (n *TraceNotify) traceSummary() string { 117 switch n.ObsPoint { 118 case TraceToLxc: 119 return fmt.Sprintf("-> endpoint %d", n.DstID) 120 case TraceToProxy: 121 return "-> proxy" 122 case TraceToHost: 123 return "-> host from" 124 case TraceToStack: 125 return "-> stack" 126 case TraceToOverlay: 127 return "-> overlay" 128 case TraceFromLxc: 129 return fmt.Sprintf("<- endpoint %d", n.Source) 130 case TraceFromProxy: 131 return "<- proxy" 132 case TraceFromHost: 133 return "<- host" 134 case TraceFromStack: 135 return "<- stack" 136 case TraceFromOverlay: 137 return "<- overlay" 138 case TraceFromNetwork: 139 return "<- network" 140 default: 141 return "unknown trace" 142 } 143 } 144 145 // DumpInfo prints a summary of the trace messages. 146 func (n *TraceNotify) DumpInfo(data []byte) { 147 if n.encryptReason() != "" { 148 fmt.Printf("%s %s flow %#x identity %d->%d state %s ifindex %s: %s\n", 149 n.traceSummary(), n.encryptReason(), n.Hash, n.SrcLabel, n.DstLabel, 150 n.traceReason(), ifname(int(n.Ifindex)), GetConnectionSummary(data[TraceNotifyLen:])) 151 } else { 152 fmt.Printf("%s flow %#x identity %d->%d state %s ifindex %s: %s\n", 153 n.traceSummary(), n.Hash, n.SrcLabel, n.DstLabel, 154 n.traceReason(), ifname(int(n.Ifindex)), GetConnectionSummary(data[TraceNotifyLen:])) 155 } 156 } 157 158 // DumpVerbose prints the trace notification in human readable form 159 func (n *TraceNotify) DumpVerbose(dissect bool, data []byte, prefix string) { 160 fmt.Printf("%s MARK %#x FROM %d %s: %d bytes (%d captured), state %s", 161 prefix, n.Hash, n.Source, obsPoint(n.ObsPoint), n.OrigLen, n.CapLen, connState(n.Reason)) 162 163 if n.Ifindex != 0 { 164 fmt.Printf(", interface %s", ifname(int(n.Ifindex))) 165 } 166 167 if n.SrcLabel != 0 || n.DstLabel != 0 { 168 fmt.Printf(", identity %d->%d", n.SrcLabel, n.DstLabel) 169 } 170 171 if n.DstID != 0 { 172 fmt.Printf(", to endpoint %d\n", n.DstID) 173 } else { 174 fmt.Printf("\n") 175 } 176 177 if n.CapLen > 0 && len(data) > TraceNotifyLen { 178 Dissect(dissect, data[TraceNotifyLen:]) 179 } 180 } 181 182 func (n *TraceNotify) getJSON(data []byte, cpuPrefix string) (string, error) { 183 v := TraceNotifyToVerbose(n) 184 v.CPUPrefix = cpuPrefix 185 if n.CapLen > 0 && len(data) > TraceNotifyLen { 186 v.Summary = GetDissectSummary(data[TraceNotifyLen:]) 187 } 188 189 ret, err := json.Marshal(v) 190 return string(ret), err 191 } 192 193 // DumpJSON prints notification in json format 194 func (n *TraceNotify) DumpJSON(data []byte, cpuPrefix string) { 195 resp, err := n.getJSON(data, cpuPrefix) 196 if err == nil { 197 fmt.Println(resp) 198 } 199 } 200 201 // TraceNotifyVerbose represents a json notification printed by monitor 202 type TraceNotifyVerbose struct { 203 CPUPrefix string `json:"cpu,omitempty"` 204 Type string `json:"type,omitempty"` 205 Mark string `json:"mark,omitempty"` 206 Ifindex string `json:"ifindex,omitempty"` 207 State string `json:"state,omitempty"` 208 ObservationPoint string `json:"observationPoint"` 209 TraceSummary string `json:"traceSummary"` 210 211 Source uint16 `json:"source"` 212 Bytes uint32 `json:"bytes"` 213 SrcLabel uint32 `json:"srcLabel"` 214 DstLabel uint32 `json:"dstLabel"` 215 DstID uint16 `json:"dstID"` 216 217 Summary *DissectSummary `json:"summary,omitempty"` 218 } 219 220 // TraceNotifyToVerbose creates verbose notification from base TraceNotify 221 func TraceNotifyToVerbose(n *TraceNotify) TraceNotifyVerbose { 222 return TraceNotifyVerbose{ 223 Type: "trace", 224 Mark: fmt.Sprintf("%#x", n.Hash), 225 Ifindex: ifname(int(n.Ifindex)), 226 State: connState(n.Reason), 227 ObservationPoint: obsPoint(n.ObsPoint), 228 TraceSummary: n.traceSummary(), 229 Source: n.Source, 230 Bytes: n.OrigLen, 231 SrcLabel: n.SrcLabel, 232 DstLabel: n.DstLabel, 233 DstID: n.DstID, 234 } 235 }