diff --git a/go-controller/pkg/node/bridgeconfig/bridgeconfig_testutil.go b/go-controller/pkg/node/bridgeconfig/bridgeconfig_testutil.go index d13568a529..a87826ddb7 100644 --- a/go-controller/pkg/node/bridgeconfig/bridgeconfig_testutil.go +++ b/go-controller/pkg/node/bridgeconfig/bridgeconfig_testutil.go @@ -18,6 +18,7 @@ import ( func TestDefaultBridgeConfig() *BridgeConfiguration { defaultNetConfig := &BridgeUDNConfiguration{ OfPortPatch: "patch-breth0_ov", + MasqCTMark: "0x1", } return &BridgeConfiguration{ netConfig: map[string]*BridgeUDNConfiguration{ diff --git a/go-controller/pkg/node/gateway_localnet_linux_test.go b/go-controller/pkg/node/gateway_localnet_linux_test.go index 49e4d1ee13..9bca1f642c 100644 --- a/go-controller/pkg/node/gateway_localnet_linux_test.go +++ b/go-controller/pkg/node/gateway_localnet_linux_test.go @@ -1193,6 +1193,10 @@ var _ = Describe("Node Operations", func() { } expectedNodePortFlows := []string{ "cookie=0x453ae29bcbbc08bd, priority=110, in_port=eth0, tcp, tp_dst=31111, actions=output:patch-breth0_ov", + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=109, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, actions=drop", + gwMAC), + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, ip, nw_src=%s, actions=ct(commit, zone=64000, exec(set_field:0x1->ct_mark)), output:NORMAL", + gwMAC, v4localnetGatewayIP), fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_src=31111, actions=output:eth0", gwMAC), } @@ -2306,6 +2310,10 @@ var _ = Describe("Node Operations", func() { expectedFlows := []string{ // default "cookie=0x453ae29bcbbc08bd, priority=110, in_port=eth0, tcp, tp_dst=31111, actions=output:patch-breth0_ov", + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=109, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, actions=drop", + gwMAC), + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, ip, nw_src=%s, actions=ct(commit, zone=64000, exec(set_field:0x1->ct_mark)), output:NORMAL", + gwMAC, v4localnetGatewayIP), fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_src=31111, actions=output:eth0", gwMAC), } @@ -2596,6 +2604,10 @@ var _ = Describe("Node Operations", func() { expectedFlows := []string{ // default "cookie=0x453ae29bcbbc08bd, priority=110, in_port=eth0, tcp, tp_dst=31111, actions=output:patch-breth0_ov", + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=109, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, actions=drop", + gwMAC), + fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_dst=31111, ip, nw_src=%s, actions=ct(commit, zone=64000, exec(set_field:0x1->ct_mark)), output:NORMAL", + gwMAC, v4localnetGatewayIP), fmt.Sprintf("cookie=0x453ae29bcbbc08bd, priority=110, in_port=patch-breth0_ov, dl_src=%s, tcp, tp_src=31111, actions=output:eth0", gwMAC), } diff --git a/go-controller/pkg/node/gateway_shared_intf.go b/go-controller/pkg/node/gateway_shared_intf.go index 773671b0ff..8ce75fcb0d 100644 --- a/go-controller/pkg/node/gateway_shared_intf.go +++ b/go-controller/pkg/node/gateway_shared_intf.go @@ -329,11 +329,31 @@ func (npw *nodePortWatcher) updateServiceFlowCache(service *corev1.Service, netI npw.ofm.updateFlowCacheEntry(key, nodeportFlows) } else if config.Gateway.Mode == config.GatewayModeShared { // case2 (see function description for details) + var ipProtocol, gwIP string + if strings.Contains(flowProtocol, "6") { + ipProtocol = "ip6" + gwIP = npw.gatewayIPv6 + } else { + ipProtocol = "ip" + gwIP = npw.gatewayIPv4 + } + npw.ofm.updateFlowCacheEntry(key, []string{ // table=0, matches on service traffic towards nodePort and sends it to OVN pipeline fmt.Sprintf("cookie=%s, priority=110, in_port=%s, %s, tp_dst=%d, "+ "actions=%s", cookie, npw.ofportPhys, flowProtocol, svcPort.NodePort, actions), + // table=0, matches on service traffic towards nodePort from OVN and drops it, to prevent the ingress traffic goes to the host. + // This is to prevent ingress traffic to nodePort from being forwarded to the host accidentally during GR OVN LB resyncs. + fmt.Sprintf("cookie=%s, priority=109, in_port=%s, dl_src=%s, %s, tp_dst=%d, "+ + "actions=drop", + cookie, netConfig.OfPortPatch, npw.ofm.getDefaultBridgeMAC(), flowProtocol, svcPort.NodePort), + // table=0, matches on local host/pods egress traffic to service nodePort and sends it out to physical network. + // This is needed for the case where a local pod/host is trying to access the service via nodePort. It gets higher + // priority than the previous rule to allow local traffic to nodePort to be sent out. + fmt.Sprintf("cookie=%s, priority=110, in_port=%s, dl_src=%s, %s, tp_dst=%d, %s, nw_src=%s, "+ + "actions=ct(commit, zone=%d, exec(set_field:%s->ct_mark)), output:NORMAL", + cookie, netConfig.OfPortPatch, npw.ofm.getDefaultBridgeMAC(), flowProtocol, svcPort.NodePort, ipProtocol, gwIP, config.Default.ConntrackZone, netConfig.MasqCTMark), // table=0, matches on return traffic from service nodePort and sends it out to primary node interface (br-ex) fmt.Sprintf("cookie=%s, priority=110, in_port=%s, dl_src=%s, %s, tp_src=%d, "+ "actions=output:%s",