From 8f08909c509370681725dd7c966a106539ce8081 Mon Sep 17 00:00:00 2001 From: Gavin Xin Date: Fri, 9 Aug 2024 02:22:51 +0800 Subject: [PATCH] Match dstIP in Classifier to address windows promiscuous mode issue (#6528) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When promiscuous mode is enabled, OVS incorrectly forwards packets destined for non-local IP addresses from the uplink to the host interface. Due to IP forwarding being enabled, these packets are re-sent to br-int according to the default route and are eventually forwarded to the uplink. Since the source MAC of these packets has been changed to the local host’s MAC, this can potentially cause errors on the switch. This patch matches dstIP field in ClassifierTable to ensure proper packet handling and preventing unintended forwarding. Signed-off-by: Gavin Xin --- pkg/agent/openflow/pipeline.go | 5 ++--- pkg/agent/openflow/pipeline_other.go | 4 ++++ pkg/agent/openflow/pipeline_windows.go | 5 +++++ pkg/agent/openflow/pod_connectivity_test.go | 4 ++-- 4 files changed, 13 insertions(+), 5 deletions(-) diff --git a/pkg/agent/openflow/pipeline.go b/pkg/agent/openflow/pipeline.go index b5f75df9327..601e910f186 100644 --- a/pkg/agent/openflow/pipeline.go +++ b/pkg/agent/openflow/pipeline.go @@ -2967,9 +2967,8 @@ func (f *featurePodConnectivity) hostBridgeLocalFlows() []binding.Flow { cookieID := f.cookieAllocator.Request(f.category).Raw() return []binding.Flow{ // This generates the flow to forward the packets from uplink port to bridge local port. - ClassifierTable.ofTable.BuildFlow(priorityNormal). - Cookie(cookieID). - MatchInPort(f.uplinkPort). + f.matchUplinkInPortInClassifierTable(ClassifierTable.ofTable.BuildFlow(priorityNormal). + Cookie(cookieID)). Action().Output(f.hostIfacePort). Done(), // This generates the flow to forward the packets from bridge local port to uplink port. diff --git a/pkg/agent/openflow/pipeline_other.go b/pkg/agent/openflow/pipeline_other.go index 60459fba878..44df8f357ba 100644 --- a/pkg/agent/openflow/pipeline_other.go +++ b/pkg/agent/openflow/pipeline_other.go @@ -25,6 +25,10 @@ import ( binding "antrea.io/antrea/pkg/ovs/openflow" ) +func (f *featurePodConnectivity) matchUplinkInPortInClassifierTable(flowBuilder binding.FlowBuilder) binding.FlowBuilder { + return flowBuilder.MatchInPort(f.uplinkPort) +} + // hostBridgeUplinkFlows generates the flows that forward traffic between the bridge local port and the uplink port to // support the host traffic. // TODO(gran): sync latest changes from pipeline_windows.go diff --git a/pkg/agent/openflow/pipeline_windows.go b/pkg/agent/openflow/pipeline_windows.go index 2557d3f6ffb..fb2fe300ad0 100644 --- a/pkg/agent/openflow/pipeline_windows.go +++ b/pkg/agent/openflow/pipeline_windows.go @@ -23,6 +23,11 @@ import ( binding "antrea.io/antrea/pkg/ovs/openflow" ) +// matchUplinkInPortInClassifierTable matches dstIP field to prevent unintended forwarding when promiscuous mode is enabled on Windows. +func (f *featurePodConnectivity) matchUplinkInPortInClassifierTable(flowBuilder binding.FlowBuilder) binding.FlowBuilder { + return flowBuilder.MatchInPort(f.uplinkPort).MatchProtocol(binding.ProtocolIP).MatchDstIP(f.nodeConfig.NodeTransportIPv4Addr.IP) +} + // hostBridgeUplinkFlows generates the flows that forward traffic between the bridge local port and the uplink port to // support the host traffic with outside. func (f *featurePodConnectivity) hostBridgeUplinkFlows() []binding.Flow { diff --git a/pkg/agent/openflow/pod_connectivity_test.go b/pkg/agent/openflow/pod_connectivity_test.go index 327372ebb08..77e3aba9a73 100644 --- a/pkg/agent/openflow/pod_connectivity_test.go +++ b/pkg/agent/openflow/pod_connectivity_test.go @@ -90,7 +90,7 @@ func podConnectivityInitFlows( flows = append(flows, "cookie=0x1010000000000, table=ARPSpoofGuard, priority=200,in_port=32770 actions=output:4294967294", "cookie=0x1010000000000, table=ARPSpoofGuard, priority=200,in_port=4294967294 actions=output:32770", - "cookie=0x1010000000000, table=Classifier, priority=200,in_port=32770 actions=output:4294967294", + "cookie=0x1010000000000, table=Classifier, priority=200,ip,in_port=32770,nw_dst=192.168.77.100 actions=output:4294967294", "cookie=0x1010000000000, table=Classifier, priority=200,in_port=4294967294 actions=output:32770", "cookie=0x1010000000000, table=IngressSecurityClassifier, priority=210,ct_state=-rpl+trk,ip,nw_src=10.10.0.1 actions=goto_table:ConntrackCommit", ) @@ -161,7 +161,7 @@ func podConnectivityInitFlows( "cookie=0x1010000000000, table=ARPSpoofGuard, priority=200,in_port=32770 actions=output:4294967294", "cookie=0x1010000000000, table=ARPSpoofGuard, priority=200,in_port=4294967294 actions=output:32770", "cookie=0x1010000000000, table=Classifier, priority=210,ip,in_port=32770,nw_dst=10.10.0.0/24 actions=set_field:0x4/0xf->reg0,set_field:0x200/0x200->reg0,goto_table:UnSNAT", - "cookie=0x1010000000000, table=Classifier, priority=200,in_port=32770 actions=output:4294967294", + "cookie=0x1010000000000, table=Classifier, priority=200,ip,in_port=32770,nw_dst=192.168.77.100 actions=output:4294967294", "cookie=0x1010000000000, table=Classifier, priority=200,in_port=4294967294 actions=output:32770", "cookie=0x1010000000000, table=SpoofGuard, priority=200,ip,in_port=32769 actions=goto_table:UnSNAT", "cookie=0x1010000000000, table=ConntrackZone, priority=200,ip actions=ct(table=ConntrackState,zone=65520,nat)",