diff --git a/northd/northd.c b/northd/northd.c
index 4751feab4..07fb0ab9a 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -3362,7 +3362,12 @@ ovn_port_update_sbrec(struct northd_input *input_data,
             }
             smap_add(&new, "distributed-port", op->nbrp->name);
 
-            bool always_redirect = !op->od->has_distributed_nat;
+            bool always_redirect = !(
+                op->od->has_distributed_nat ||
+                (op->l3dgw_port->peer &&
+                 op->l3dgw_port->peer->od->has_vtep_lports)
+            );
+
             if (redirect_type) {
                 smap_add(&new, "redirect-type", redirect_type);
                 /* XXX Why can't we enable always-redirect when redirect-type
@@ -12815,6 +12820,15 @@ build_gateway_redirect_flows_for_lrouter(
         return;
     }
     for (size_t i = 0; i < od->n_l3dgw_ports; i++) {
+        if (od->l3dgw_ports[i]->peer &&
+            od->l3dgw_ports[i]->peer->od->has_vtep_lports) {
+            /* Skip adding redirect rule for vtep-enabled l3dgw ports.
+               Traffic from hypervisor to VTEP (ramp) switch should go in
+               distributed manner. Only returning routed traffic must go
+               through centralized gateway (or ha-chassis-group). */
+            continue;
+        }
+
         const struct ovsdb_idl_row *stage_hint = NULL;
         bool add_def_flow = true;
 
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 56c1e6c2e..72f7c3e2d 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -6074,7 +6074,7 @@ AT_CLEANUP
 ])
 
 OVN_FOR_EACH_NORTHD_NO_HV([
-AT_SETUP([ovn-northd -- lr admission with vtep lports])
+AT_SETUP([ovn-northd -- lrp with chassis-redirect and ls with vtep lport])
 AT_KEYWORDS([multiple-l3dgw-ports])
 ovn_start NORTHD_TYPE
 check ovn-sbctl chassis-add ch1 geneve 127.0.0.2
@@ -6098,6 +6098,11 @@ AT_CHECK([grep lr_in_admission lrflows | grep lrp1 | sed 's/table=../table=??/'
   table=??(lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lrp1"), action=(xreg0[[0..47]] = 00:00:00:00:00:01; next;)
 ])
 
+# Check the flows in lr_in_gw_redirect stage
+AT_CHECK([grep lr_in_gw_redirect lrflows | grep lrp1 | sed 's/table=../table=??/' | sort], [0], [])
+
+wait_row_count Port_Binding 0 logical_port=cr-lrp1 options:always-redirect="true"
+
 # make lrp a cr-port and check its flows
 check ovn-nbctl lrp-set-gateway-chassis lrp1 ch1
 
@@ -6111,6 +6116,13 @@ AT_CHECK([grep lr_in_admission lrflows | grep lrp1 | sed 's/table=../table=??/'
   table=??(lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lrp1"), action=(xreg0[[0..47]] = 00:00:00:00:00:01; next;)
 ])
 
+# Check the flows in lr_in_gw_redirect stage
+AT_CHECK([grep lr_in_gw_redirect lrflows | grep lrp1 | sed 's/table=../table=??/' | sort], [0], [dnl
+  table=??(lr_in_gw_redirect  ), priority=50   , match=(outport == "lrp1"), action=(outport = "cr-lrp1"; next;)
+])
+
+wait_row_count Port_Binding 1 logical_port=cr-lrp1 options:always-redirect="true"
+
 # attach vtep logical port to logical switch and check flows.
 # there should not be is_chassis_resident part.
 check ovn-nbctl lsp-add ls1 lsp-vtep -- lsp-set-type lsp-vtep vtep
@@ -6125,6 +6137,11 @@ AT_CHECK([grep lr_in_admission lrflows | grep lrp1 | sed 's/table=../table=??/'
   table=??(lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lrp1"), action=(xreg0[[0..47]] = 00:00:00:00:00:01; next;)
 ])
 
+# Check the flows in lr_in_gw_redirect stage
+AT_CHECK([grep lr_in_gw_redirect lrflows | grep lrp1 | sed 's/table=../table=??/' | sort], [0], [])
+
+wait_row_count Port_Binding 0 logical_port=cr-lrp1 options:always-redirect="true"
+
 # delete vtep lport and check lrp has is_chassis_resident match part again.
 check ovn-nbctl lsp-del lsp-vtep
 
@@ -6138,6 +6155,13 @@ AT_CHECK([grep lr_in_admission lrflows | grep lrp1 | sed 's/table=../table=??/'
   table=??(lr_in_admission    ), priority=50   , match=(eth.mcast && inport == "lrp1"), action=(xreg0[[0..47]] = 00:00:00:00:00:01; next;)
 ])
 
+# Check the flows in lr_in_gw_redirect stage
+AT_CHECK([grep lr_in_gw_redirect lrflows | grep lrp1 | sed 's/table=../table=??/' | sort], [0], [dnl
+  table=??(lr_in_gw_redirect  ), priority=50   , match=(outport == "lrp1"), action=(outport = "cr-lrp1"; next;)
+])
+
+wait_row_count Port_Binding 1 logical_port=cr-lrp1 options:always-redirect="true"
+
 AT_CLEANUP
 ])
 
