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

feat(dns-gadget): Add more fields to DNS gadget #1943

Conversation

anubhabMajumdar
Copy link
Contributor

@anubhabMajumdar anubhabMajumdar commented Aug 8, 2023

Add more fields to DNS gadget event

Add the following fields to DNS gadget event:

  • SrcIP
  • DstIP
  • SrcPort
  • DstPort
  • Protocol

How to use

$ ./kubectl-gadget trace dns -n default                                                                                                                                                                                                                                                                                                            ok | 6s | 17:26:02
NODE                                                        NAMESPACE                                                   POD                                                         PID        TID        COMM             SRCIP                          DSTIP                          SRCP… DSTP… PROTO QR TYPE      QTYPE      NAME                                                       RCODE                          NUMANSW…
minikube-docker                                             default                                                     alpine                                                      2661242    2661242    nslookup         10.244.0.5                     10.96.0.10                     51025 53    udp   Q  OUTGOING  A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.5                     10.96.0.10                     51025 53    udp   Q  OTHERHOST A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.5                     10.244.0.2                     51025 53    udp   Q  OUTGOING  A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.2                     192.168.65.2                   46205 53    udp   Q  OTHERHOST A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.2                     127.0.0.11                     46205 40648 udp   Q  HOST      A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     2582       2703       dockerd          192.168.49.2                   192.168.65.7                   54400 53    udp   Q  OUTGOING  A          bing.com.                                                                                 0
minikube-docker                                                                                                                                                                     2582       2703       dockerd          192.168.65.7                   192.168.49.2                   53    54400 udp   R  HOST      A          bing.com.                                                  NoError                        2
minikube-docker                                                                                                                                                                     0          0                           192.168.65.2                   10.244.0.2                     53    46205 udp   R  OUTGOING  A          bing.com.                                                  NoError                        2
minikube-docker                                                                                                                                                                     0          0                           192.168.65.2                   10.244.0.2                     53    46205 udp   R  OUTGOING  A          bing.com.                                                  NoError                        2
minikube-docker                                                                                                                                                                     0          0                           10.244.0.2                     10.244.0.5                     53    51025 udp   R  OTHERHOST A          bing.com.                                                  NoError                        2
minikube-docker                                                                                                                                                                     0          0                           10.96.0.10                     10.244.0.5                     53    51025 udp   R  OUTGOING  A          bing.com.                                                  NoError                        2
minikube-docker                                             default                                                     alpine                                                      2661242    2661242    nslookup         10.96.0.10                     10.244.0.5                     53    51025 udp   R  HOST      A          bing.com.                                                  NoError                        2
minikube-docker                                             default                                                     alpine                                                      2661601    2661601    nslookup         10.244.0.5                     10.96.0.10                     46024 53    udp   Q  OUTGOING  AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.5                     10.96.0.10                     46024 53    udp   Q  OTHERHOST AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.5                     10.244.0.2                     46024 53    udp   Q  OUTGOING  AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     0          0                           10.244.0.2                     192.168.65.2                   38867 53    udp   Q  OTHERHOST AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     2582       1959886    dockerd          10.244.0.2                     127.0.0.11                     38867 40648 udp   Q  HOST      AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     2582       1959886    dockerd          192.168.49.2                   192.168.65.7                   43901 53    udp   Q  OUTGOING  AAAA       google.com.                                                                               0
minikube-docker                                                                                                                                                                     2582       1959886    dockerd          192.168.65.7                   192.168.49.2                   53    43901 udp   R  HOST      AAAA       google.com.                                                NoError                        1
minikube-docker                                                                                                                                                                     0          0                           192.168.65.2                   10.244.0.2                     53    38867 udp   R  OUTGOING  AAAA       google.com.                                                NoError                        1
minikube-docker                                                                                                                                                                     0          0                           192.168.65.2                   10.244.0.2                     53    38867 udp   R  OUTGOING  AAAA       google.com.                                                NoError                        1
minikube-docker                                                                                                                                                                     0          0                           10.244.0.2                     10.244.0.5                     53    46024 udp   R  OTHERHOST AAAA       google.com.                                                NoError                        1
minikube-docker                                                                                                                                                                     0          0                           10.96.0.10                     10.244.0.5                     53    46024 udp   R  OUTGOING  AAAA       google.com.                                                NoError                        1
minikube-docker                                             default                                                     alpine                                                      2661601    2661601    nslookup         10.96.0.10                     10.244.0.5                     53    46024 udp   R  HOST      AAAA       google.com.                                                NoError                        1

Testing done

  • Unit tests are passing
  • Modified the DNS integration test to test for the new fields
  • Manually verified in a minikube cluster, snippet added above

@anubhabMajumdar anubhabMajumdar changed the title Topic/anmajumdar/five tuple dns feat(dns-gadget): Add more fields to DNS gadget Aug 8, 2023
Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

Hi.

Thank you for working on this.
I have some initials comments, particularly regarding integration tests.
I will test the gadget itself later today and if everything is OK, I will run the CI.

Do not hesitate if you have any questions or point you do not understand.

Best regards.

integration/inspektor-gadget/trace_dns_test.go Outdated Show resolved Hide resolved
pkg/gadgets/helpers.go Outdated Show resolved Hide resolved
pkg/gadgets/helpers.go Outdated Show resolved Hide resolved
integration/helpers.go Outdated Show resolved Hide resolved
@anubhabMajumdar
Copy link
Contributor Author

Hi.

Thank you for working on this. I have some initials comments, particularly regarding integration tests. I will test the gadget itself later today and if everything is OK, I will run the CI.

Do not hesitate if you have any questions or point you do not understand.

Best regards.

Thanks for the review, addressed your comments. Let me know if the gadget works for you!

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

I tested it and it works fine:

RUNTIME.CONTAINERNAME PID         TID         COMM        SRCIP           DSTIP           SRCP… DSTP… PROTO QR TYPE      QTYPE       NAME                  RCODE      NUMA…
                      60299       60300       isc-net-00… 192.168.0.12    8.8.4.4         34905 53    udp   Q  OUTGOING  A           inspektor-gadget.io.             0    
                      60299       60300       isc-net-00… 8.8.4.4         192.168.0.12    53    34905 udp   R  HOST      A           inspektor-gadget.io.  NoError    2 

Nonetheless, we can polish it, I advise you to do the following:

  1. Rebase everything on top of latest main.
  2. Split your initial commit in two commits: one for the fields addition, the other for the integration test.
    2.5 Drop the bpf_htons() call in eBPF code and HtoNs() call in golang, load_half() will convert the network endianness to the host one for you, so no need to add extra conversion here:
diff --git a/pkg/gadgets/trace/dns/tracer/bpf/dns.c b/pkg/gadgets/trace/dns/tracer/bpf/dns.c
index 7357d3bb..222371c5 100644
--- a/pkg/gadgets/trace/dns/tracer/bpf/dns.c
+++ b/pkg/gadgets/trace/dns/tracer/bpf/dns.c
@@ -211,13 +211,13 @@ static __always_inline int output_dns_event(struct __sk_buff *skb,
       // Check network protocol.
       event->proto = load_byte(skb, ETH_HLEN + offsetof(struct iphdr, protocol));
       if (event->proto == IPPROTO_TCP) {
-               event->sport = bpf_htons(load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, source)));
-               event->dport = bpf_htons(load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest)));
+               event->sport = load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, source));
+               event->dport = load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct tcphdr, dest));
       } else if (event->proto == IPPROTO_UDP) {
-               event->sport = bpf_htons(load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct udphdr, source)));
-               event->dport = bpf_htons(load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct udphdr, dest)));
+               event->sport = load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct udphdr, source));
+               event->dport = load_half(skb, ETH_HLEN + sizeof(struct iphdr) + offsetof(struct udphdr, dest));
       }
-       
+
       event->qr = flags.qr;

       if (flags.qr == 1) {
diff --git a/pkg/gadgets/trace/dns/tracer/dns_bpfel.o b/pkg/gadgets/trace/dns/tracer/dns_bpfel.o
index fc5a4068..e1475189 100644
Binary files a/pkg/gadgets/trace/dns/tracer/dns_bpfel.o and b/pkg/gadgets/trace/dns/tracer/dns_bpfel.o differ
diff --git a/pkg/gadgets/trace/dns/tracer/tracer.go b/pkg/gadgets/trace/dns/tracer/tracer.go
index b942466b..644e2f65 100644
--- a/pkg/gadgets/trace/dns/tracer/tracer.go
+++ b/pkg/gadgets/trace/dns/tracer/tracer.go
@@ -230,8 +230,8 @@ func bpfEventToDNSEvent(bpfEvent *dnsEventT, netns uint64) (*types.Event, error)
               event.Nameserver = event.DstIP
       }

-       event.SrcPort = gadgets.Htons(bpfEvent.Sport)
-       event.DstPort = gadgets.Htons(bpfEvent.Dport)
+       event.SrcPort = bpfEvent.Sport
+       event.DstPort = bpfEvent.Dport
       event.Protocol = gadgets.ProtoString(int(bpfEvent.Proto))

       // Convert name into a string with dots
  1. Try to use normalize() to set to 0 things you do not care in the integration test. I think this will permit you to avoid adding the compFn() argument.
  2. Update the documentation in docs/gadgets/trace/dns.md for the kubernetes part (I will deal with the ig part once merged).

Feel free to ask for clarification and again thank you for working on this!

Copy link
Member

@blanquicet blanquicet left a comment

Choose a reason for hiding this comment

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

Thanks @anubhabMajumdar for this contribution! I have a couple of comments but it already looks good.

pkg/gadgets/helpers.go Outdated Show resolved Hide resolved
pkg/gadgets/trace/dns/types/dns.go Outdated Show resolved Hide resolved
integration/inspektor-gadget/trace_dns_test.go Outdated Show resolved Hide resolved
integration/inspektor-gadget/trace_dns_test.go Outdated Show resolved Hide resolved
@anubhabMajumdar
Copy link
Contributor Author

Thanks @anubhabMajumdar for this contribution! I have a couple of comments but it already looks good.

@eiffel-fl @blanquicet
Thanks for all the feedback and suggestions! I have addressed all of them. Let me know if this looks OK!

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

It looks good, you just need to polish the git history.
I will run the CI but I expect it to pass.

pkg/gadgets/trace/dns/types/dns.go Show resolved Hide resolved
Copy link
Member

@burak-ok burak-ok left a comment

Choose a reason for hiding this comment

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

Hi,

as the others already said the changes look good, thanks for that :)

Another improvement could be using the KubeIPResolver so that IP addresses will be automatically resolved to pod names or service names.
I experimented with it in burak-ok@315746c . Feel free to cherry-pick and modify it.

$ ./kubectl-gadget trace dns -n default -o columns=node,namespace,pod,name,qr,qtype,src
NODE                  NAMESPACE             POD                   NAME                  QR QTYPE      SRC                        
minikube-docker       default               test-pod              google.de.            Q  A          p/default/test-pod:56088   
minikube-docker       default               test-pod              google.de.            Q  AAAA       p/default/test-pod:56088   
minikube-docker       default               test-pod              google.de.            R  AAAA       s/kube-system/kube-dns:53  
minikube-docker       default               test-pod              google.de.            R  A          s/kube-system/kube-dns:53

@anubhabMajumdar
Copy link
Contributor Author

It looks good, you just need to polish the git history. I will run the CI but I expect it to pass.

A couple of CI pipelines failed due to small typo in the test and formatting issues. I have fixed those.

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

Let's run the CI again but I think we are near the truth!

pkg/gadgets/trace/dns/types/dns.go Show resolved Hide resolved
@blanquicet
Copy link
Member

Another improvement could be using the KubeIPResolver so that IP addresses will be automatically resolved to pod names or service names. I experimented with it in burak-ok@315746c . Feel free to cherry-pick and modify it.

Nice one! Yeah, we should definitely do it. However, I think it could be done in another PR as this one, IMO, is ready to go!

Copy link
Member

@alban alban left a comment

Choose a reason for hiding this comment

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

Thanks for the PR. I am adding my comments (some are redundant with previous comments).

pkg/gadgets/helpers.go Outdated Show resolved Hide resolved
pkg/gadgets/helpers.go Outdated Show resolved Hide resolved
pkg/gadgets/trace/dns/tracer/bpf/dns.c Show resolved Hide resolved
pkg/gadgets/trace/dns/tracer/bpf/dns.c Show resolved Hide resolved
pkg/gadgets/trace/dns/tracer/tracer.go Outdated Show resolved Hide resolved
pkg/gadgets/trace/dns/tracer/tracer.go Outdated Show resolved Hide resolved
pkg/gadgets/trace/dns/types/dns.go Show resolved Hide resolved
@anubhabMajumdar
Copy link
Contributor Author

Another improvement could be using the KubeIPResolver so that IP addresses will be automatically resolved to pod names or service names. I experimented with it in burak-ok@315746c . Feel free to cherry-pick and modify it.

Nice one! Yeah, we should definitely do it. However, I think it could be done in another PR as this one, IMO, is ready to go!

Hey, addressed Alban's comments and fixed one more issue with the integration test. Hopefully it will pass this time!

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

Can you please rebase and clean the whole history?
It will make it easier to review.
I will run the CI again meanwhile.

@alban alban mentioned this pull request Aug 16, 2023
2 tasks
@anubhabMajumdar
Copy link
Contributor Author

Can you please rebase and clean the whole history? It will make it easier to review. I will run the CI again meanwhile.

Pipelines have passed, can I squash and merge from Github?

@eiffel-fl
Copy link
Member

Can you please rebase and clean the whole history? It will make it easier to review. I will run the CI again meanwhile.

Pipelines have passed, can I squash and merge from Github?

What do you mean by squash?
If you mean squashing all your commits into one, then I do not agree, one PR is not composed of one commit but of several which represent each one semantic changes (adding the features, adding the test, adding the documentation, etc.).

So, reworking your history would be welcomed.
Once done, I will review it again, potentially give my approval and I will merge it.
I would nonetheless like to have another green review before merging.

Copy link
Member

@alban alban left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

So far in this project, we've used the merge button with the 'Merge commit' option without squashing commits from the web UI, so contributors can write the commit messages for individual commits, and I prefer to keep it this way for consistency.

For this PR, I think one commit is enough: the changes in the tests are not new tests but necessary changes to make the existing tests pass. Could you rebase the history in one patch?

@eiffel-fl
Copy link
Member

Can you please rebase and clean the whole history? It will make it easier to review. I will run the CI again meanwhile.

Pipelines have passed, can I squash and merge from Github?

What do you mean by squash? If you mean squashing all your commits into one, then I do not agree, one PR is not composed of one commit but of several which represent each one semantic changes (adding the features, adding the test, adding the documentation, etc.).

So, reworking your history would be welcomed. Once done, I will review it again, potentially give my approval and I will merge it. I would nonetheless like to have another green review before merging.

As the only modifications you bring to the tests are modifications meant for it to pass, it can be part of the same commit than the one adding the feature.
Otherwise, we would end in a red and green commit.

Nonetheless, we will not use GitHub feature to squash everything before we merge.

Add the following fields to DNS gadget event:

SrcIP
DstIP
SrcPort
DstPort
Protocol

Also, enhance the intergration tests to test the changes.

Signed-off-by: Anubhab Majumdar <anmajumdar@microsoft.com>
@anubhabMajumdar
Copy link
Contributor Author

Can you please rebase and clean the whole history? It will make it easier to review. I will run the CI again meanwhile.

Pipelines have passed, can I squash and merge from Github?

What do you mean by squash? If you mean squashing all your commits into one, then I do not agree, one PR is not composed of one commit but of several which represent each one semantic changes (adding the features, adding the test, adding the documentation, etc.).
So, reworking your history would be welcomed. Once done, I will review it again, potentially give my approval and I will merge it. I would nonetheless like to have another green review before merging.

As the only modifications you bring to the tests are modifications meant for it to pass, it can be part of the same commit than the one adding the feature. Otherwise, we would end in a red and green commit.

Nonetheless, we will not use GitHub feature to squash everything before we merge.

Cleaned up the commits; let me know if this works! Thanks!

Copy link
Member

@eiffel-fl eiffel-fl left a comment

Choose a reason for hiding this comment

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

Awesome! Thank you for this contribution!

protoStr := fmt.Sprintf("UNKNOWN#%d", proto)
switch proto {
case unix.IPPROTO_TCP:
protoStr = "TCP"
Copy link
Member

Choose a reason for hiding this comment

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

I am wondering if this change has consequences regarding the documentation.
If so, I will tackle them in a follow-up PR.

@@ -34,6 +34,11 @@ struct event_t {
};
__u16 af; // AF_INET or AF_INET6

// Internet protocol and port numbers.
Copy link
Member

Choose a reason for hiding this comment

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

We should definitely check this structure padding.

@eiffel-fl eiffel-fl merged commit d68c5c3 into inspektor-gadget:main Aug 23, 2023
46 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants