-
Notifications
You must be signed in to change notification settings - Fork 376
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 bidirectional packet capture #6882
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Aryan Bakliwal <[email protected]>
Signed-off-by: Aryan Bakliwal <[email protected]>
@hangyan please let me know what you think about this |
…antrea-io#6877) Bumps the golang-org-x group with 1 update: [golang.org/x/net](https://github.com/golang/net). Updates `golang.org/x/net` from 0.32.0 to 0.33.0 - [Commits](golang/net@v0.32.0...v0.33.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production update-type: version-update:semver-minor dependency-group: golang-org-x ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…oup (antrea-io#6880) Bumps the ginkgo group with 1 update: [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo). Updates `github.com/onsi/ginkgo/v2` from 2.22.0 to 2.22.1 - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](onsi/ginkgo@v2.22.0...v2.22.1) --- updated-dependencies: - dependency-name: github.com/onsi/ginkgo/v2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ginkgo ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Signed-off-by: Aryan Bakliwal <[email protected]>
Hey @hangyan @antoninbas, I made the changes in the bpf code according to the one generated by tcpdump. When I try to test the bidirectional packet capture, it fails with this log
Could you please take a look and help me identify what might be going wrong? Also, golangci-lint is giving me this error even though I have changed the
|
this error was reported by golangci on windows, we have a |
Signed-off-by: Aryan Bakliwal <[email protected]>
I’ve added the Please let me know if any adjustments are needed or if there's anything else I should update or add. Captured packets |
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.
could we add an e2e test with the Both
direction?
Signed-off-by: Aryan Bakliwal <[email protected]>
7b17816
to
7eb34de
Compare
@antoninbas @hangyan I have refactored the |
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.
thanks for your ongoing work on this
// (004) ld [26] # Load 4B at 26 (source address) | ||
// (005) jeq #0xaf40102 jt 6 jf 15 # If bytes match(10.244.0.2), goto #6, else #15 | ||
// (006) ld [30] # Load 4B at 30 (dest address) | ||
// (007) jeq #0xaf40103 jt 8 jf 26 # If bytes match(10.244.0.3), goto #8, else #26 |
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.
would the code be easier to generate if we jumped to (015) in case this instruction (007) was not a match?
the fact that we know we can skip the second or
operand in this case is an optimization. Not saying it's not a good optimization, but if using a "fixed" offset makes code generation much easier, maybe we should do it for now.
I'm thinking about the discussion we just had during the community meeting. That being said, I can see why generating the same code as tcpdump is valuable.
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.
@AryanBakliwal Please take a look at this ^
Taking a concrete example:
tcpdump -d "ip proto 6 and ((src host 10.244.1.2 and dst host 10.244.1.3) or (src host 10.244.1.3 and dst host 10.244.1.2))"
This is the code generated by tcpdump:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 12
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 12
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 8
(006) ld [30]
(007) jeq #0xaf40103 jt 11 jf 12
(008) jeq #0xaf40103 jt 9 jf 12
(009) ld [30]
(010) jeq #0xaf40102 jt 11 jf 12
(011) ret #262144
(012) ret #0
If we generate this code instead, I believe it will be simpler:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 12
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 12
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 8
(006) ld [30]
(007) jeq #0xaf40103 jt 11 jf 8 <- less efficient than tcpdump's version but easier to implement?
(008) jeq #0xaf40103 jt 9 jf 12
(009) ld [30]
(010) jeq #0xaf40102 jt 11 jf 12
(011) ret #262144
(012) ret #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.
@antoninbas Actually, the real problem is the calculation of skipTrue
(for which I created the function calculateSkipTrue
) when we want to accept the packet. But calculateSkipTrue
depends on many parameters [srcPort
, dstPort
, direction
, which port is loaded in the register (srcPort
or dstPort
) and if we are calling this function from the first half (instructions that check request) or the second half (instructions that check response)] to calculate the number of instructions to skip to jump to the returnKeep
instruction. This makes the code generation very complex if generating instruction set exactly like tcpdump.
Taking each case:
- ICMP (both
srcPort
anddstPort
are 0)
tcpdump -d "ip proto 6 and ((src host 10.244.1.2 and dst host 10.244.1.3) or (src host 10.244.1.3 and dst host 10.244.1.2))"
Code generated by tcpdump:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 12
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 12
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 8
(006) ld [30]
(007) jeq #0xaf40103 jt 11 jf 12 <- need to jump to 11 from 7, difference to calculate = 3
(008) jeq #0xaf40103 jt 9 jf 12
(009) ld [30]
(010) jeq #0xaf40102 jt 11 jf 12 <- skipTrue = 0
(011) ret #262144
(012) ret #0
- TCP (
srcPort
= 0 anddstPort
> 0)
tcpdump -d "ip proto 6 and ((src host 10.244.1.2 and dst host 10.244.1.3 and dst port 80) or (src host 10.244.1.3 and dst host 10.244.1.2 and src port 80))"
Code generated by tcpdump:
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 22
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 22
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 13
(006) ld [30]
(007) jeq #0xaf40103 jt 8 jf 22 <- jump to next instruction since port(s) not zero
(008) ldh [20]
(009) jset #0x1fff jt 22 jf 10
(010) ldxb 4*([14]&0xf)
(011) ldh [x + 16]
(012) jeq #0x50 jt 21 jf 22 <- need to jump to 21 from 12, difference to calculate = 8
(013) jeq #0xaf40103 jt 14 jf 22
(014) ld [30]
(015) jeq #0xaf40102 jt 16 jf 22
(016) ldh [20]
(017) jset #0x1fff jt 22 jf 18
(018) ldxb 4*([14]&0xf)
(019) ldh [x + 14]
(020) jeq #0x50 jt 21 jf 22 <- skipTrue = 0
(021) ret #262144
(022) ret #0
Note that this is similar to when (srcPort
> 0 and dstPort
= 0) and (srcPort
> 0 and dstPort
> 0).
Since the problem is to jump to the returnKeep
instruction, why not add it again to mitigate this complex calculation and jump to it easily. For example:
- ICMP:
Code that can be generated more simply
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 12
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 12
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 8
(006) ld [30]
(007) jeq #0xaf40103 jt 8 jf 13 <- just skip to next instruction if true
(008) ret #262144
(009) jeq #0xaf40103 jt 10 jf 13
(010) ld [30]
(011) jeq #0xaf40102 jt 12 jf 13
(012) ret #262144
(013) ret #0
- TCP (
srcPort
= 0 anddstPort
> 0)
Code that can be generated more simply
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 23
(002) ldb [23]
(003) jeq #0x6 jt 4 jf 23
(004) ld [26]
(005) jeq #0xaf40102 jt 6 jf 13
(006) ld [30]
(007) jeq #0xaf40103 jt 8 jf 23
(008) ldh [20]
(009) jset #0x1fff jt 23 jf 10
(010) ldxb 4*([14]&0xf)
(011) ldh [x + 16]
(012) jeq #0x50 jt 13 jf 23 <- just skip to next instruction if true
(013) ret #262144
(014) jeq #0xaf40103 jt 15 jf 23
(015) ld [30]
(016) jeq #0xaf40102 jt 17 jf 23
(017) ldh [20]
(018) jset #0x1fff jt 23 jf 19
(019) ldxb 4*([14]&0xf)
(020) ldh [x + 14]
(021) jeq #0x50 jt 22 jf 23
(022) ret #262144
(023) ret #0
Let me know what you think about this approach
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.
Adding an extra return instruction sounds fine to me.
I think what we are going for is some code that looks like this in the end:
if direction == SourceToDest {
generateFilters(offset, srcIP, dstIP, srcPort, dstPort)
} else if direction == DestToSource {
generateFilters(offset, dstIP, srcIP, dstPort, srcPort)
} else {
generateFilters(offset, srcIP, dstIP, srcPort, dstPort)
// ...
generateFilters(offset, dstIP, srcIP, dstPort, srcPort)
}
So if we can get there and have some generate code that looks reasonable and works, that would be good.
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.
@antoninbas I have made the requested changes and refactored the code as you suggested and as per our discussion. PTAL and let me know if there is anything else to update or add.
Signed-off-by: Aryan Bakliwal <[email protected]>
fixes: #6862
Added
bidirectional
field in packet capture CR spec.For testing, I created two pods and pinged one from the other.
Screenshot of the
.pcapng
output file.