-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for filtering events and minor related changes #673
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall this is great. It would be even better if we can support a --related-to ID
which takes an endpoint ID and then prints everything which has the endpoint ID in either the from
to to
. This would show everything in and out of a particular endpoint.
cilium/cmd/monitor.go
Outdated
// checkFilter does some input validation to give the user feedback if they | ||
// wrote something close that did not match for example 'srop' instead of | ||
// 'drop'. | ||
func checkFilter() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rename this to validateEventTypeFilter
cilium/cmd/monitor.go
Outdated
@@ -59,40 +63,97 @@ var ( | |||
SampleType: bpf.PERF_SAMPLE_RAW, | |||
WakeupEvents: 1, | |||
} | |||
eventTypeIdx = -1 // for integer comparison | |||
eventType = "" | |||
eventTypes = []string{"drop", "debug", "capture"} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Consider writing this as a map instead:
eventTypes := map[string]int {
"debug": bpfdebug.MessageTypeDebug,
"drop": bpfdebug.MessageTypeDrop,
"capture": bpfdebug.MessageTypeCapture,
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also makes it clear which names corresponds to which message type without depending on order
cilium/cmd/monitor.go
Outdated
func checkFilter() { | ||
for i, e := range eventTypes { | ||
if eventType == e { | ||
eventTypeIdx = i + 1 // 0 == .MessageTypeUnspec, but we only want valid ones. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can then just check the type against the map:
if eventTypeIdx, ok = eventTypes[eventType]; !ok {
err := "Unknown type (%s). Please use one of the following ones %s\n"
[...]
}
cilium/cmd/monitor.go
Outdated
// are supplied. If either one of them is less than zero, then it is assumed user did | ||
// use them. | ||
func match(messageType int, src uint16, dst uint32) bool { | ||
if eventTypeIdx > bpfdebug.MessageTypeUnspec && messageType != eventTypeIdx { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The >
is misleading, write this as:
if eventTypeIdx != bpfdebug.MessageTypeUnspec && messageType != eventTypeIdx {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scanf was this addressed?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aanm meant my comment above which is still not addressed. It's a cosmetic thing though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@aanm ah, must have left this on a different machine. It was marked as outdated so I just assumed it was addressed since Github automatically collapses these. Will follow up. Thanks!
cilium/cmd/monitor.go
Outdated
eventTypeIdx = -1 // for integer comparison | ||
eventType = "" | ||
eventTypes = []string{"drop", "debug", "capture"} | ||
fromSource = 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initialize them to uint16 so you don't have to cast later on:
fromSource = uint16(0)
cilium/cmd/monitor.go
Outdated
@@ -43,11 +43,19 @@ programs attached to endpoints and devices. This includes: | |||
}, | |||
} | |||
|
|||
func listEventTypes() string { | |||
return "[ drop, debug, capture ]" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine, if you want to generate it:
types := []string{}
for _, v := range eventTypes {
types = append(types, v)
}
return types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great additions. I've one question. Is it possible do multiple filters at the same time?
cilium/cmd/monitor.go
Outdated
func init() { | ||
RootCmd.AddCommand(monitorCmd) | ||
monitorCmd.Flags().IntVarP(&eventConfig.NumCpus, "num-cpus", "c", runtime.NumCPU(), "Number of CPUs") | ||
monitorCmd.Flags().IntVarP(&eventConfig.NumPages, "num-pages", "n", 64, "Number of pages for ring buffer") | ||
monitorCmd.Flags().BoolVarP(&dissect, "dissect", "d", false, "Dissect packet data") | ||
monitorCmd.Flags().StringVarP(&eventType, "type", "t", "", fmt.Sprintf("Filter by event types %v", listEventTypes())) | ||
monitorCmd.Flags().Uint16Var(&fromSource, "from", 0, "filter by source endpoint id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
filter
- > Filter
The same goes with the next 2 liness
cilium/cmd/monitor.go
Outdated
func init() { | ||
RootCmd.AddCommand(monitorCmd) | ||
monitorCmd.Flags().IntVarP(&eventConfig.NumCpus, "num-cpus", "c", runtime.NumCPU(), "Number of CPUs") | ||
monitorCmd.Flags().IntVarP(&eventConfig.NumPages, "num-pages", "n", 64, "Number of pages for ring buffer") | ||
monitorCmd.Flags().BoolVarP(&dissect, "dissect", "d", false, "Dissect packet data") | ||
monitorCmd.Flags().StringVarP(&eventType, "type", "t", "", fmt.Sprintf("Filter by event types %v", listEventTypes())) | ||
monitorCmd.Flags().Uint16Var(&fromSource, "from", 0, "filter by source endpoint id") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why Uint16Var
and the others have Uint32Var
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To match the existing message format. Using other types would generate compile
time errors. The source fields from the message types define the
.Source
format as uint16
.
See
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/drop.go#L30
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/debug.go#L129
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/debug.go#L229
also for DstID
or Arg1
(uint32
) see
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/drop.go#L36
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/debug.go#L131
https://github.com/cilium/cilium/blob/master/pkg/bpfdebug/debug.go#L233
The ctypes are in
https://github.com/cilium/cilium/blob/master/bpf/lib/common.h
https://github.com/cilium/cilium/blob/master/bpf/lib/dbg.h
but @borkmann and @tgraf can probably give a much better explanation on why
those fields are uint16 and uint32.
cilium/cmd/monitor.go
Outdated
return false | ||
} else if toDst > 0 && toDst != dst { | ||
return false | ||
} else if uint16(related) != src && related > 0 && related != dst { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this be related > 0 && uint16(related) != src && related != dst
?
@aanm yes combining options should work fine, but please try out. If you discover something doesn't work. Let me know, so I can fix and add a test for it. Thanks. |
@scanf How does the |
@aanm |
@scanf why Policy needs to be set to true? |
cilium/cmd/monitor.go
Outdated
if err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &dm); err != nil { | ||
fmt.Printf("Error while parsing debug message: %s\n", err) | ||
} | ||
if match(bpfdebug.MessageTypeDebug, dm.Source, dm.Arg1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passing dm.Arg1
as destination ID is wrong. In most cases, that is not the destination. We can't support --to
for debug messages. Let's just pass in0
for now.
cilium/cmd/monitor.go
Outdated
if err := binary.Read(bytes.NewReader(data), binary.LittleEndian, &dc); err != nil { | ||
fmt.Printf("Error while parsing debug capture message: %s\n", err) | ||
} | ||
if match(bpfdebug.MessageTypeCapture, dc.Source, dc.Arg1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here, we would need to extend the BPF progs to always specify the destination ID before we can pass that in. dc.Arg1
will mean something different depending on the actual message being sent.
This will be used for testing the new filtering arguments in a follow up commit. Related-to: #473 (Feature: Add filtering to cilium monitor) Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
monitor_resume is useful because it behaves the same as monitor_start() but instead does not overwrite DUMP_FILE. This will be used in follow up to test multiple runs of the monitor. Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
cilium/cmd/monitor.go
Outdated
) | ||
|
||
func lostEvent(lost *bpf.PerfEventLost, cpu int) { | ||
fmt.Printf("Lost %d events\n", lost.Lost) | ||
fmt.Printf("CPU %02d: Lost %d events\n", lost.Lost, cpu) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ordering seems incorrect here - it should be:
fmt.Printf("CPU: %02d: Lost %d events\n", cpu, lost.Lost)
cilium/cmd/monitor.go
Outdated
return true | ||
} | ||
|
||
func dropEvents(prefix string, data []byte) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation needed for this function.
cilium/cmd/monitor.go
Outdated
} | ||
} | ||
|
||
func debugEvents(prefix string, data []byte) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation needed for this function.
cilium/cmd/monitor.go
Outdated
} | ||
} | ||
|
||
func captureEvents(prefix string, data []byte) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation needed for this function.
cilium/cmd/monitor.go
Outdated
} | ||
} | ||
|
||
func receiveEvent(msg *bpf.PerfEventSample, cpu int) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Documentation needed for this function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mainly nits on my part, but please add the requested documentation.
We are already printing it in func receiveEvent(...). To be consistent print it here as well, and maybe this will be useful for future debugging. Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
The new filtering support consists of `--type`, `--to` and `--from`. The `cilium help monitor` output now looks like this: The monitor displays notifications and events omitted by the BPF programs attached to endpoints and devices. This includes: * Dropped packet notifications * Captured packet traces * Debugging information Usage: cilium monitor [flags] Flags: -d, --dissect Dissect packet data --from uint16 filter by source endpoint id -c, --num-cpus int Number of CPUs (default 2) -n, --num-pages int Number of pages for ring buffer (default 64) --related-to uint32 filter by either source or destination endpoint id --to uint32 filter by destination endpoint id -t, --type string Filter by event types [drop debug capture] Global Flags: --config string config file (default is $HOME/.cilium.yaml) -D, --debug Enable debug messages -H, --host string URI to server-side API Some example usage: - `cilium monitor --type drop` will only show you messages for packets being dropped. - `cilium monitor --type drop --from 173` is same as above but will only match when the source has the provided id. - `cilium monitor --type drop --to 123` should match when we get a drop event and the destination has the provided id. - `cilium monitor --type drop --related-to 749` shows drop notifications where the source or destination has the provided id. Closes: #473 (Feature: Add filtering to cilium monitor) Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
@aanm sorry, the policy part can be ignored. Please try again to see if you still have issues. |
@ianvernon fixed, let me know what to reword. Thanks! |
cilium/cmd/monitor.go
Outdated
// are supplied. If either one of them is less than zero, then it is assumed user did | ||
// use them. | ||
func match(messageType int, src uint16, dst uint32) bool { | ||
if eventTypeIdx > bpfdebug.MessageTypeUnspec && messageType != eventTypeIdx { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@scanf was this addressed?
@aanm I am not sure what you mean in the last comment. Could you elaborate on what should have been addressed? Thanks. |
Let's merge as-is, we can fix stlye afterwards.
@scanf I was referring this comment #673 (comment) |
Thomas says: >The > is misleading Related-to: #673 (Add support for filtering events and minor related changes) Suggested-by: Thomas Graf <thomas@cilium.io> Suggested-by: André Martins <andre@cilium.io> Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
The new filtering support consists of
--type
,--to
and--from
.The
cilium help monitor
output now looks like this:Some example usage:
cilium monitor --type drop
will only show you messages for packets beingdropped.
cilium monitor --type drop --from 173
is same as above but will only matchwhen the source has the provided id.
cilium monitor --type drop --to 123
should match when we get a drop eventand the destination has the provided id.
cilium monitor --type drop --related-to 749
shows drop notifications wherethe source or destination has the provided id.
Closes: #473 (Feature: Add filtering to cilium monitor)