Skip to content
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

NETOBSERV-1471 gRPC export for packet capture #291

Merged
merged 13 commits into from
Mar 22, 2024

Conversation

jpinsonneau
Copy link
Contributor

@jpinsonneau jpinsonneau commented Mar 6, 2024

Description

Add gRPC export capability for packet capture.
Since I moved flow grpc to flowgrpc package, we will need to update FLP at the same time

I also took the opportunity to reuse the target host / port from flow config since it doesn't make sense to have both here.

Dependencies

n/a

Checklist

If you are not familiar with our processes or don't know what to answer in the list below, let us know in a comment: the maintainers will take care of that.

  • Will this change affect NetObserv / Network Observability operator? If not, you can ignore the rest of this checklist.
  • Is this PR backed with a JIRA ticket? If so, make sure it is written as a title prefix (in general, PRs affecting the NetObserv/Network Observability product should be backed with a JIRA ticket - especially if they bring user facing changes).
  • Does this PR require product documentation?
    • If so, make sure the JIRA epic is labelled with "documentation" and provides a description relevant for doc writers, such as use cases or scenarios. Any required step to activate or configure the feature should be documented there, such as new CRD knobs.
  • Does this PR require a product release notes entry?
    • If so, fill in "Release Note Text" in the JIRA.
  • Is there anything else the QE team should know before testing? E.g: configuration changes, environment setup, etc.
    • If so, make sure it is described in the JIRA ticket.
  • QE requirements (check 1 from the list):
    • Standard QE validation, with pre-merge tests unless stated otherwise.
    • Regression tests only (e.g. refactoring with no user-facing change).
    • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

@@ -163,8 +164,6 @@ type Config struct {
// PCAFilters set the filters to determine packets to filter using Packet Capture Agent (PCA). It is a comma separated set.
// The format is [protocol], [port number] Example: PCA_FILTER = "tcp,80". Currently, we support 'tcp','udp','sctp' for protocol.
PCAFilters string `env:"PCA_FILTER"`
// PCAServerPort is the port PCA Server starts at, when ENABLE_PCA variable is set to true.
PCAServerPort int `env:"PCA_SERVER_PORT" envDefault:"9990"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I remember we had this discussion with Shachee previously, that reusing the FLOWS_TARGET_PORT env for pcap was misleading, and for two reasons: first because it has "FLOWS" in the name, and second because in the case of the TCP impl, if I remember correctly, this isn't a target port (ie. a remote host port) but it's a server port, uses to listen for clients who want to poll data. So that's why we ended up with this new env.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well in that case we can remove both flows and target mentions. The final output will be:

	// Host is the host name or IP of the Flow collector
	Host string `env:"HOST"`
	// Port is the port of the Flow collector
	Port int `env:"PORT"`

There is no point keeping these separated unless we plan to have both packets + flows export at the same time. WDYT ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI I addressed this in that way in:
8cbecaf
3e86b43

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

idk it still bother me to mix server and client config into a single configuration ; you kept "target" which IMO is still misleading for a server configuration, it really looks like we are configuring a client. idk if it's just me, @msherif1234 what do you think? I defer to you :-)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well if we get rid of pcap w/ tcp , hence we have no server mode anyway, then I guess it answers the question

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As mention above I changed the config to get rid of these mentions. That's more generic for future implementations.
On top of that I removed tcp export for packet capture.

Let me know if the current state match your expectations

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, sorry but, now that it's clearly only a client connection there's no reason to remove "target" from the names? It was inconsistent if we were mixing client & server, but now that we don't, it's fine and more precise than just "host" / "port"
Anyway I don't want to block this PR indefinitely, we can do that later

Copy link

codecov bot commented Mar 12, 2024

Codecov Report

Attention: Patch coverage is 38.57143% with 172 lines in your changes are missing coverage. Please review.

Project coverage is 34.04%. Comparing base (6e00a92) to head (df212a7).

Files Patch % Lines
pkg/exporter/grpc_packets.go 0.00% 49 Missing ⚠️
pkg/pbpacket/packet.pb.go 52.08% 44 Missing and 2 partials ⚠️
pkg/exporter/packets_proto.go 0.00% 21 Missing ⚠️
pkg/agent/packets_agent.go 0.00% 16 Missing ⚠️
pkg/agent/config.go 8.33% 8 Missing and 3 partials ⚠️
pkg/pbpacket/packet_grpc.pb.go 70.00% 7 Missing and 2 partials ⚠️
pkg/grpc/packet/server.go 73.33% 6 Missing and 2 partials ⚠️
pkg/agent/agent.go 30.00% 7 Missing ⚠️
pkg/grpc/packet/client.go 68.75% 4 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #291      +/-   ##
==========================================
+ Coverage   32.79%   34.04%   +1.25%     
==========================================
  Files          41       47       +6     
  Lines        3653     3836     +183     
==========================================
+ Hits         1198     1306     +108     
- Misses       2379     2444      +65     
- Partials       76       86      +10     
Flag Coverage Δ
unittests 34.04% <38.57%> (+1.25%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jpinsonneau
Copy link
Contributor Author

/retest

@jpinsonneau jpinsonneau reopened this Mar 13, 2024
examples/packetcapture-dump/README.md Outdated Show resolved Hide resolved
pkg/agent/config.go Show resolved Hide resolved
pkg/agent/packets_agent.go Outdated Show resolved Hide resolved
pkg/agent/packets_agent.go Outdated Show resolved Hide resolved
pkg/exporter/grpc_packets.go Outdated Show resolved Hide resolved
pkg/exporter/grpc_packets.go Outdated Show resolved Hide resolved
pkg/exporter/tcp_packets.go Outdated Show resolved Hide resolved
CaptureLength: len(packetStream),
Length: len(packetStream),
}
err := writeGRPCPacket(captureInfo, packetStream, p.clientConn)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we can define grpc as array of pcap and write all the record at once instead of writing every packet this will probably be more efficient WDYT?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can give a try indeed. What would be the maximum acceptable total size here ?

A single packet can be huge so I may need to check about the next(s) before sending

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u can make the max configurable like we do today with flows IIRC for flows its 10000 do we send the entire packet or its just max of 256 bytes ? we should set an upper limit in ebpf code, I can provide a patch for this

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the collector side, it doesn't make sense to get half of a packet here. It would require extra work to sync and avoid concurrency

We should keep this simple and write packets entirely; but allowing array of them with a reasonnable upper limit

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are we ok to limit the packet header size from the ebpf to say 256 bytes max if the packet is fragmented or has encrypted data it has no value copy all of that to user space WDYT ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed today, it's still interesting to capture the payload for non encrypted packets. Giving the ability to get only the firsts 256 bytes is still interesting if wireshark manages that seamlessly but in that case, flows already cover these informations.


// The request message containing the Packet
message Packet {
google.protobuf.Any pcap = 1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we decided to send multiple pcaps then we need to add repeated at the definition above

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we keep that for a followup improvment ? That raise more questions about the total size of the message.

The goal here was just to implement gRPC for security reasons to productize CLI.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure sounds good to me!!

proto/packet.proto Outdated Show resolved Hide resolved
@@ -9,7 +9,7 @@ import (
"github.com/netobserv/flowlogs-pipeline/pkg/operational"
"github.com/netobserv/flowlogs-pipeline/pkg/pipeline/utils"
"github.com/netobserv/netobserv-ebpf-agent/pkg/decode"
"github.com/netobserv/netobserv-ebpf-agent/pkg/grpc"
grpc "github.com/netobserv/netobserv-ebpf-agent/pkg/grpc/flow"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👆 that cross import will require FLP update

@jpinsonneau
Copy link
Contributor Author

Rebased + removed tcp packet capture
6e65e79

// Deprecated FlowsTargetPort replaced by TargetPort
FlowsTargetPort int `env:"FLOWS_TARGET_PORT"`
// Deprecated PCAServerPort replaced by TargetPort
PCAServerPort int `env:"PCA_SERVER_PORT"`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we have case like we have both agent and pca running at the same node reaching out to host but using different port with the above proposed config that seems impossible right ?
i.e with this new config changes we can run either agent or pca but not both at the same time as it was b4 this change ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't have both flow + pca capture as it rely on ENABLE_PCA bool config
https://github.com/netobserv/netobserv-ebpf-agent/blob/main/cmd/netobserv-ebpf-agent.go#L56

}

func manageDeprecatedConfigs(cfg *Config) {
if len(cfg.FlowsTargetHost) > 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: u are doing !=0 below so why not be consistent ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Host is a string whereas Port is a number

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i meant len() != 0 as oppose to len() > 0

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok sure, 64c9c2a

"google.golang.org/protobuf/types/known/anypb"

"github.com/netobserv/netobserv-ebpf-agent/pkg/flow"
grpc "github.com/netobserv/netobserv-ebpf-agent/pkg/grpc/packet"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: this is the import order used in the agent
1- standard libs
2- netobserv pkg
3- external packages
this applies here and in all newly created files

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, 111c915

}
err := writeGRPCPacket(captureInfo, packetStream, p.clientConn)
if err != nil {
gplog.Error(err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lets aggregate the errors here and return error in this function and use the return err from here in the caller not the err from StartGRPCPacketSend

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to get your point here. Do you mean adding error as returned value of ExportGRPCPackets ?
I'm expecting to log with error each packet not sent here.

The approach is very similar to flows one here:
https://github.com/netobserv/netobserv-ebpf-agent/blob/main/pkg/exporter/grpc_proto.go#L59-L62

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if u look at the caller it return error from startGRPC right but not reflecting errors because of export
so what I am suggesting return an error here and inside the loop just log and aggr the errors

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is that what you had in mind ?

0ccc69b

"time"

"github.com/mariomac/guara/pkg/test"
"github.com/netobserv/netobserv-ebpf-agent/pkg/pbpacket"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: import order

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in beef4dd

"google.golang.org/grpc"
"google.golang.org/grpc/reflection"

"github.com/netobserv/netobserv-ebpf-agent/pkg/pbpacket"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in beef4dd

"os"
"time"

"github.com/google/gopacket/layers"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import order

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done in beef4dd

@msherif1234
Copy link
Contributor

msherif1234 commented Mar 22, 2024

I am good with the changes few nit left other than that LGTM up to u fixing them
/LGTM

@msherif1234
Copy link
Contributor

/lgtm

@msherif1234
Copy link
Contributor

@msherif1234
Copy link
Contributor

/approve

Copy link

openshift-ci bot commented Mar 22, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: msherif1234

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit 08030df into netobserv:main Mar 22, 2024
11 checks passed
jotak added a commit to jotak/netobserv-agent that referenced this pull request Mar 25, 2024
As discussed here: netobserv#291 (comment)
HOST and PORT are very generic and don't provide the meaning about what
they are for; An uninformed user would probably think this would be for
a server, of for the agent host itself, rather than a target of
flow/packet collectors.
openshift-merge-bot bot pushed a commit that referenced this pull request Mar 25, 2024
As discussed here: #291 (comment)
HOST and PORT are very generic and don't provide the meaning about what
they are for; An uninformed user would probably think this would be for
a server, of for the agent host itself, rather than a target of
flow/packet collectors.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants