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

Fix reject action on Service traffic #2772

Merged
merged 2 commits into from Nov 3, 2021
Merged

Conversation

GraysonWu
Copy link
Contributor

@GraysonWu GraysonWu commented Sep 13, 2021

Fixes issue #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.


Reference Table of all cases when Antrea Proxy is disabled

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

Signed-off-by: wgrayson wgrayson@vmware.com

@codecov-commenter
Copy link

codecov-commenter commented Sep 13, 2021

Codecov Report

Merging #2772 (be4ec20) into main (12f8395) will decrease coverage by 1.14%.
The diff coverage is 70.07%.

Impacted file tree graph

@@            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     
Flag Coverage Δ
kind-e2e-tests 47.70% <68.61%> (-1.55%) ⬇️
unit-tests 40.43% <2.18%> (-0.19%) ⬇️

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

Impacted Files Coverage Δ
pkg/agent/controller/networkpolicy/packetin.go 67.15% <ø> (-4.85%) ⬇️
pkg/agent/openflow/pipeline.go 77.83% <ø> (-0.58%) ⬇️
pkg/agent/openflow/client.go 58.44% <37.50%> (+0.11%) ⬆️
pkg/agent/controller/networkpolicy/reject.go 70.24% <70.24%> (ø)
pkg/agent/controller/networkpolicy/fqdn.go 75.97% <100.00%> (+0.12%) ⬆️
...ntroller/networkpolicy/networkpolicy_controller.go 71.03% <100.00%> (-0.22%) ⬇️
pkg/ovs/openflow/ofctrl_packetout.go 85.65% <100.00%> (+1.03%) ⬆️
...g/agent/apiserver/handlers/featuregates/handler.go 0.00% <0.00%> (-82.36%) ⬇️
...kg/apiserver/registry/system/supportbundle/rest.go 19.54% <0.00%> (-55.18%) ⬇️
pkg/support/dump_others.go 0.00% <0.00%> (-51.73%) ⬇️
... and 34 more

@GraysonWu GraysonWu force-pushed the fix-svc-reject branch 6 times, most recently from ed900d4 to 76fdde1 Compare September 25, 2021 06:57
@GraysonWu GraysonWu changed the title [WIP]Fix reject action on Service traffic Fix reject action on Service traffic Sep 25, 2021
pkg/ovs/openflow/ofctrl_packetout.go Outdated Show resolved Hide resolved
pkg/ovs/openflow/interfaces.go Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/openflow/client.go Outdated Show resolved Hide resolved
@GraysonWu GraysonWu force-pushed the fix-svc-reject branch 2 times, most recently from d1225e6 to 80be246 Compare September 29, 2021 20:16
Copy link
Contributor

@wenyingd wenyingd left a 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.

pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
@GraysonWu GraysonWu force-pushed the fix-svc-reject branch 3 times, most recently from 4a2b817 to ffaee3b Compare October 21, 2021 20:14
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>
@GraysonWu
Copy link
Contributor Author

/test-integration

@GraysonWu
Copy link
Contributor Author

/test-all

Copy link
Contributor

@wenyingd wenyingd left a 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.

if isReject {
packetOutBuilder = packetOutBuilder.AddLoadRegMark(CustomReasonRejectRegMark)
}
packetOutBuilder = addActionsToPacketOut(packetOutBuilder, packetOutType)
Copy link
Contributor

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.

Copy link
Contributor

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 {

Copy link
Contributor Author

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!

Copy link
Contributor

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/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/packetin.go Outdated Show resolved Hide resolved
pkg/ovs/openflow/ofctrl_packetout.go Outdated Show resolved Hide resolved
if isReject {
packetOutBuilder = packetOutBuilder.AddLoadRegMark(CustomReasonRejectRegMark)
}
packetOutBuilder = addActionsToPacketOut(packetOutBuilder, packetOutType)
Copy link
Contributor

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 {

wenyingd
wenyingd previously approved these changes Nov 2, 2021
Copy link
Contributor

@wenyingd wenyingd left a comment

Choose a reason for hiding this comment

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

LGTM

pkg/agent/controller/networkpolicy/reject.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/reject.go Outdated Show resolved Hide resolved
pkg/agent/controller/networkpolicy/reject.go Outdated Show resolved Hide resolved
// 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 {
Copy link
Contributor

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.

Copy link
Contributor

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).

Copy link
Contributor Author

@GraysonWu GraysonWu Nov 2, 2021

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

Copy link
Contributor Author

@GraysonWu GraysonWu Nov 2, 2021

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?

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 added more comments here to explain this. @antoninbas you can take a look to see if it's clear. Thanks.

Copy link
Contributor

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.

Copy link
Contributor Author

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.

test/e2e/k8s_util.go Outdated Show resolved Hide resolved
Signed-off-by: wgrayson <wgrayson@vmware.com>
@GraysonWu
Copy link
Contributor Author

/test-all

@tnqn tnqn merged commit 8ca720d into antrea-io:main Nov 3, 2021
tnqn added a commit to tnqn/antrea that referenced this pull request Nov 3, 2021
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>
tnqn added a commit that referenced this pull request Nov 3, 2021
This was introduced by merging #2956 and #2772 whose code conflict was
not detected by git.

Signed-off-by: Quan Tian <qtian@vmware.com>
tnqn added a commit to tnqn/antrea that referenced this pull request Nov 3, 2021
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>
tnqn added a commit that referenced this pull request Nov 3, 2021
This was introduced by merging #2956 and #2772 whose code conflict was
not detected by git.

Signed-off-by: Quan Tian <qtian@vmware.com>
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