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
Fix reject action on Service traffic #2772
Conversation
Codecov Report
@@ Coverage Diff @@
## main #2772 +/- ##
==========================================
- Coverage 61.61% 60.46% -1.15%
==========================================
Files 283 284 +1
Lines 23810 23878 +68
==========================================
- Hits 14671 14439 -232
- Misses 7558 7913 +355
+ Partials 1581 1526 -55
Flags with carried forward coverage won't be shown. Click here to find out more.
|
ed900d4
to
76fdde1
Compare
76fdde1
to
a94cee2
Compare
a94cee2
to
f36786a
Compare
d1225e6
to
80be246
Compare
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.
LGTM, only two minor nits.
4a2b817
to
ffaee3b
Compare
Fixes issue antrea-io#2699. 1. Change reject response packetOut logic to below: * Pod-to-Pod traffic * Locally: Directly output the packet to the destination OF port. Use src/dstPod's OF port as in/outPort. * Remote to local: Directly output the packet to the destination OF port. Use gateway's OF port as inPort and dstPod's OF port as outPort. * Local to remote: Resubmit packet to l3ForwardingTable(70). Use Pod's OF port as inPort. * Service traffic * AntreaProxy enabled * Locally: Resubmit packet to conntrackTable(30). Use srcPod's OF port as inPort. * Remote to local: Use gateway's OF port as inPort. * Local to remote: Same as Pod-to-Pod traffic local to remote case. * AntreaProxy disabled * Locally: Directly output the packet to gateway's OF port. Use srcPod's OF port as inPort and gateway's OF port as outPort. * Remote to local: Directly output the packet to gateway's OF port. Use tunnel's OF port as inPort and gateway's OF port as outPort. * Local to remote: Same as Pod-to-Pod traffic local to remote case. 2. To decided if it is Service traffic: * AntreaProxy enabled: If EpSelectedRegMark is set in ServiceEPStateField, then it's Service traffic * AntreaProxy disabled: For the destination of the reject response, if dstIP is on local Node, but the dstMAC is the gateway's MAC. We could say this response is heading to kube-proxy, which means it's Service traffic. 3. Removed reject bypass CT logic. 4. Added e2e to test reject action on Service traffic. 5. Change packetOut outPort to uint32. Signed-off-by: wgrayson <wgrayson@vmware.com>
ffaee3b
to
1e918a1
Compare
|
/test-integration |
|
/test-all |
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.
LGTM overall, except for one comments, and no strong opinion to address it in this PR.
pkg/agent/openflow/client.go
Outdated
| if isReject { | ||
| packetOutBuilder = packetOutBuilder.AddLoadRegMark(CustomReasonRejectRegMark) | ||
| } | ||
| packetOutBuilder = addActionsToPacketOut(packetOutBuilder, packetOutType) |
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.
Is it possible to create a new function dedicated for "reject service traffic"? And you can call addActionsToPacketOut once in this new function, then append the "AddResubmitAction" in any flowbuilder which needs it. In this way, you don't need to call addActionsToPacketOut twice, and you don't need to inject this specific function in the general function "SendICMPPacketOut" and "SendTCPPacketOut" which don't require this specific action in other cases.
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 do agree with Wenying that the current code is quite clunky. However, I don't think that these functions (SendTCPPacketOut / SendICMPPacketOut) should be responsible for doing anything which is specific to reject packets. I do not think that having binding.PacketOutType (which is specific to reject packets) as a parameter is a good idea.
Instead I think the last argument to these functions should be an arbitrary "PacketOutBuilder mutator":
func (c *client) SendICMPPacketOut(
srcMAC string,
dstMAC string,
srcIP string,
dstIP string,
inPort uint32,
outPort uint32,
isIPv6 bool,
icmpType uint8,
icmpCode uint8,
icmpData []byte,
mutatePacket func(builder PacketOutBuilder) PacketOutBuilder) error {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 the review. An arbitrary mutator func sounds good to me. I understand what you mean and at the same time, I realized that I didn't express my thoughts clearly. Sorry for the confusion. I'd like to explain a little bit. Then you guys can see if it still doesn't make sense.
I don't want to make SendTCPPacketOut or SendICMPPacketOut specific to reject packet. I'd like to make PacketOutType as a generic type. SendTCPPacketOut or SendICMPPacketOut could add OF Actions to packetOutBuilder based on PacketOutType.
Currently, I only included cases for reject, so I name the type with a generic name PacketOutType and all current types have the prefix Reject. If needed, we could add more packetOutTypes in the future. And at the same time, add OF Actions that new packetOutType need in func addActionsToPacketOut.
Maybe add a normal type PacketOutType which won't do anything in func addActionsToPacketOut could help others understand?
Let me know if this makes sense to you guys. Thanks!
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 think you have too many cases specific to the reject case (7) to make it a good candidate for a generic packet type concept. It would be a bad idea to have such a detailed list of cases that just keeps on growing. It's better to have a specialized "reject packet type" concept, and keep it local to the code dealing with reject packets.
Then you can have a SendRejectICMP function which is going to call c.SendICMPPacketOut with the right parameters (ICMP type / code, packet mutator).
pkg/agent/openflow/client.go
Outdated
| if isReject { | ||
| packetOutBuilder = packetOutBuilder.AddLoadRegMark(CustomReasonRejectRegMark) | ||
| } | ||
| packetOutBuilder = addActionsToPacketOut(packetOutBuilder, packetOutType) |
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 do agree with Wenying that the current code is quite clunky. However, I don't think that these functions (SendTCPPacketOut / SendICMPPacketOut) should be responsible for doing anything which is specific to reject packets. I do not think that having binding.PacketOutType (which is specific to reject packets) as a parameter is a good idea.
Instead I think the last argument to these functions should be an arbitrary "PacketOutBuilder mutator":
func (c *client) SendICMPPacketOut(
srcMAC string,
dstMAC string,
srcIP string,
dstIP string,
inPort uint32,
outPort uint32,
isIPv6 bool,
icmpType uint8,
icmpCode uint8,
icmpData []byte,
mutatePacket func(builder PacketOutBuilder) PacketOutBuilder) error {6dc9638
to
4f31d06
Compare
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.
LGTM
| // 1. When AntreaProxy is enabled, EpSelectedRegMark is set in ServiceEPStateField. | ||
| // 2. When AntreaProxy is disabled, dstIP of reject response is on the local Node | ||
| // and dstMAC of reject response is antrea-gw's MAC. | ||
| isServiceTraffic := func() bool { |
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.
my understanding is that isServiceTraffic only return true if we are at the source Node (reject action in an ingress policy). Is that correct? For Service traffic captured at the destination Node (reject action in a egress policy), how is the traffic classified?
Basically I don't understand how we can classify traffic a RejectNoAPServiceRemoteToLocal with this logic.
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 think I understand a bit better after reading the PR description again. But it still seems to me that in some cases (for egress policies), isServiceTraffic will return false for Service traffic, so it may be worth emphasizing this here with a comment, and explaining again that for such traffic the logic is the same as for Pod-to-Pod traffic (unless I am mistaken).
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.
Actually, it will only return true when the destination of the reject packet is on local Node. No matter in ingress/egress policy.
I made a table for AntreaProxy is disabled hope it could help you understand or discover what I missed:
| Node | Policy | Traffic | Reject Packet | Type |
|---|---|---|---|---|
| Inter-Node | Ingress | Pod-to-Pod | srcMAC: srcPod MAC dstMAC: antrea-gw MAC srcIP: srcPodIP dstIP: dstPodIP(remote) |
RejectLocalToRemote |
| Inter-Node | Ingress | Service | srcMAC: srcPod MAC dstMAC: antrea-gw MAC srcIP: srcPodIP dstIP: dstPodIP(remote) |
RejectLocalToRemote |
| Inter-Node | Egress | Pod-to-Pod | srcMAC: antrea-gw MAC dstMAC: dstPod MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectPodRemoteToLocal |
| Inter-Node | Egress | Service | srcMAC: virtule MAC dstMAC: antrea-gw MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectNoAPServiceRemoteToLocal |
| Intra-Node | Ingress | Pod-to-Pod | srcMAC: srcPod MAC dstMAC: dstPod MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectPodLocal |
| Intra-Node | Ingress | Service | srcMAC: srcPod MAC dstMAC: antrea-gw MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectNoAPServiceLocal |
| Intra-Node | Egress | Pod-to-Pod | srcMAC: srcPod MAC dstMAC: dstPod MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectPodLocal |
| Intra-Node | Egress | Service | srcMAC: srcPod MAC dstMAC: antrea-gw MAC srcIP: srcPodIP dstIP: dstPodIP(local) |
RejectNoAPServiceLocal |
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.
Sorry didn't see that you have replied before I post the table above.
I think I understand a bit better after reading the PR description again. But it still seems to me that in some cases (for egress policies), isServiceTraffic will return false for Service traffic, so it may be worth emphasizing this here with a comment, and explaining again that for such traffic the logic is the same as for Pod-to-Pod traffic (unless I am mistaken).
Do you mean inter-Node ingress cases? Pod-to-Pod traffic and Service traffic have the same logic?
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 added more comments here to explain this. @antoninbas you can take a look to see if it's clear. Thanks.
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.
In my original comment, I switched "ingress" and "egress" so it must have been confusing :/
Actually, it will only return true when the destination of the reject packet is on local Node. No matter in ingress/egress policy.
I see that, but it is always the case for egress policies, and often not the case for ingress policies (inter-Node). Thanks for the table. I think you should copy the source code for the table to the PR description for future reference.
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.
Good idea. Added to the PR description.
4f31d06
to
3947798
Compare
Signed-off-by: wgrayson <wgrayson@vmware.com>
3947798
to
be4ec20
Compare
|
/test-all |
This was introduced by merging antrea-io#2956 and antrea-io#2772 whose code conflict was not detected by git. Signed-off-by: Quan Tian <qtian@vmware.com>
This was introduced by merging antrea-io#2956 and antrea-io#2772 whose code conflict was not detected by git. Signed-off-by: Quan Tian <qtian@vmware.com>
Fixes issue #2699
1. Change reject response packetOut logic to below:
2. To decided if it is Service traffic:
If
EpSelectedRegMarkis set inServiceEPStateField, then it's Service trafficFor the destination of the reject response, if dstIP is on local Node, but the dstMAC is the gateway's MAC. We could say this response is heading to kube-proxy, which means it's Service traffic.
3. Removed reject bypass CT logic.
4. Added e2e to test reject action on Service traffic.
Reference Table of all cases when Antrea Proxy is disabled
dstMAC: antrea-gw MAC
srcIP: srcPodIP
dstIP: dstPodIP(remote)
dstMAC: antrea-gw MAC
srcIP: srcPodIP
dstIP: dstPodIP(remote)
dstMAC: dstPod MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
dstMAC: antrea-gw MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
dstMAC: dstPod MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
dstMAC: antrea-gw MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
dstMAC: dstPod MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
dstMAC: antrea-gw MAC
srcIP: srcPodIP
dstIP: dstPodIP(local)
Signed-off-by: wgrayson wgrayson@vmware.com