diff --git a/controller/binding.c b/controller/binding.c
index 8020d052f..d15dc20c3 100644
--- a/controller/binding.c
+++ b/controller/binding.c
@@ -1909,6 +1909,18 @@ consider_localnet_lport(const struct sbrec_port_binding *pb,
     if (!ld) {
         return;
     }
+
+    bool pb_localnet_learn_fdb = smap_get_bool(&pb->options,
+                                               "localnet_learn_fdb", false);
+    if (pb_localnet_learn_fdb != b_ctx_out->localnet_learn_fdb) {
+        b_ctx_out->localnet_learn_fdb = pb_localnet_learn_fdb;
+        if (b_ctx_out->tracked_dp_bindings) {
+            b_ctx_out->localnet_learn_fdb_changed = true;
+            tracked_datapath_lport_add(pb, TRACKED_RESOURCE_UPDATED,
+                                       b_ctx_out->tracked_dp_bindings);
+        }
+    }
+
     /* Add all localnet ports to local_ifaces so that we allocate ct zones
      * for them. */
     update_local_lports(pb->logical_port, b_ctx_out);
diff --git a/controller/binding.h b/controller/binding.h
index d10eeec1f..7ce00570a 100644
--- a/controller/binding.h
+++ b/controller/binding.h
@@ -108,6 +108,9 @@ struct binding_ctx_out {
     struct if_status_mgr *if_mgr;
 
     struct sset *postponed_ports;
+
+    bool localnet_learn_fdb;
+    bool localnet_learn_fdb_changed;
 };
 
 /* Local bindings. binding.c module binds the logical port (represented by
diff --git a/controller/lflow.c b/controller/lflow.c
index 71d396289..85a4943dc 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -2066,7 +2066,8 @@ static void
 consider_fdb_flows(const struct sbrec_fdb *fdb,
                    const struct hmap *local_datapaths,
                    struct ovn_desired_flow_table *flow_table,
-                   struct ovsdb_idl_index *sbrec_port_binding_by_key)
+                   struct ovsdb_idl_index *sbrec_port_binding_by_key,
+                   bool localnet_learn_fdb)
 {
     struct local_datapath *ld = get_local_datapath(local_datapaths,
                                                    fdb->dp_key);
@@ -2108,7 +2109,7 @@ consider_fdb_flows(const struct sbrec_fdb *fdb,
                     fdb->header_.uuid.parts[0], &lookup_match, &ofpacts,
                     &fdb->header_.uuid);
 
-    if (is_vif) {
+    if (is_vif && localnet_learn_fdb) {
         struct match lookup_match_vif = MATCH_CATCHALL_INITIALIZER;
         match_set_metadata(&lookup_match_vif, htonll(fdb->dp_key));
         match_set_dl_src(&lookup_match_vif, mac);
@@ -2128,12 +2129,13 @@ static void
 add_fdb_flows(const struct sbrec_fdb_table *fdb_table,
               const struct hmap *local_datapaths,
               struct ovn_desired_flow_table *flow_table,
-              struct ovsdb_idl_index *sbrec_port_binding_by_key)
+              struct ovsdb_idl_index *sbrec_port_binding_by_key,
+              bool localnet_learn_fdb)
 {
     const struct sbrec_fdb *fdb;
     SBREC_FDB_TABLE_FOR_EACH (fdb, fdb_table) {
         consider_fdb_flows(fdb, local_datapaths, flow_table,
-                           sbrec_port_binding_by_key);
+                           sbrec_port_binding_by_key, localnet_learn_fdb);
     }
 }
 
@@ -2157,7 +2159,8 @@ lflow_run(struct lflow_ctx_in *l_ctx_in, struct lflow_ctx_out *l_ctx_out)
                          l_ctx_out->flow_table);
     add_fdb_flows(l_ctx_in->fdb_table, l_ctx_in->local_datapaths,
                   l_ctx_out->flow_table,
-                  l_ctx_in->sbrec_port_binding_by_key);
+                  l_ctx_in->sbrec_port_binding_by_key,
+                  l_ctx_in->localnet_learn_fdb);
     add_port_sec_flows(l_ctx_in->binding_lports, l_ctx_in->chassis,
                        l_ctx_out->flow_table);
 }
@@ -2248,7 +2251,8 @@ lflow_add_flows_for_datapath(const struct sbrec_datapath_binding *dp,
                               l_ctx_in->sbrec_fdb_by_dp_key) {
         consider_fdb_flows(fdb_row, l_ctx_in->local_datapaths,
                            l_ctx_out->flow_table,
-                           l_ctx_in->sbrec_port_binding_by_key);
+                           l_ctx_in->sbrec_port_binding_by_key,
+                           l_ctx_in->localnet_learn_fdb);
     }
     sbrec_fdb_index_destroy_row(fdb_index_row);
 
@@ -2312,6 +2316,15 @@ lflow_handle_flows_for_lport(const struct sbrec_port_binding *pb,
                                           pb->logical_port)) {
         consider_port_sec_flows(pb, l_ctx_out->flow_table);
     }
+    if (l_ctx_in->localnet_learn_fdb_changed && l_ctx_in->localnet_learn_fdb) {
+        const struct sbrec_fdb *fdb;
+        SBREC_FDB_TABLE_FOR_EACH (fdb, l_ctx_in->fdb_table) {
+            consider_fdb_flows(fdb, l_ctx_in->local_datapaths,
+                               l_ctx_out->flow_table,
+                               l_ctx_in->sbrec_port_binding_by_key,
+                               l_ctx_in->localnet_learn_fdb);
+        }
+    }
     return true;
 }
 
@@ -2442,7 +2455,8 @@ lflow_handle_changed_fdbs(struct lflow_ctx_in *l_ctx_in,
                  UUID_ARGS(&fdb->header_.uuid));
         consider_fdb_flows(fdb, l_ctx_in->local_datapaths,
                            l_ctx_out->flow_table,
-                           l_ctx_in->sbrec_port_binding_by_key);
+                           l_ctx_in->sbrec_port_binding_by_key,
+                           l_ctx_in->localnet_learn_fdb);
     }
 
     return true;
diff --git a/controller/lflow.h b/controller/lflow.h
index 6ff499a94..9b7ffa19c 100644
--- a/controller/lflow.h
+++ b/controller/lflow.h
@@ -128,6 +128,8 @@ struct lflow_ctx_in {
     const struct flow_collector_ids *collector_ids;
     const struct hmap *local_lbs;
     bool lb_hairpin_use_ct_mark;
+    bool localnet_learn_fdb;
+    bool localnet_learn_fdb_changed;
 };
 
 struct lflow_ctx_out {
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 1bd456560..924c529f8 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -1487,6 +1487,8 @@ struct ed_type_runtime_data {
     /* Tracked data. See below for more details and comments. */
     bool tracked;
     bool local_lports_changed;
+    bool localnet_learn_fdb;
+    bool localnet_learn_fdb_changed;
     struct hmap tracked_dp_bindings;
 
     struct shash local_active_ports_ipv6_pd;
@@ -1697,6 +1699,8 @@ init_binding_ctx(struct engine_node *node,
     b_ctx_out->postponed_ports = rt_data->postponed_ports;
     b_ctx_out->tracked_dp_bindings = NULL;
     b_ctx_out->if_mgr = ctrl_ctx->if_mgr;
+    b_ctx_out->localnet_learn_fdb = rt_data->localnet_learn_fdb;
+    b_ctx_out->localnet_learn_fdb_changed = false;
 }
 
 static void
@@ -1754,6 +1758,7 @@ en_runtime_data_run(struct engine_node *node, void *data)
     }
 
     binding_run(&b_ctx_in, &b_ctx_out);
+    rt_data->localnet_learn_fdb = b_ctx_out.localnet_learn_fdb;
 
     engine_set_node_state(node, EN_UPDATED);
 }
@@ -1866,9 +1871,12 @@ runtime_data_sb_port_binding_handler(struct engine_node *node, void *data)
     }
 
     rt_data->local_lports_changed = b_ctx_out.local_lports_changed;
+    rt_data->localnet_learn_fdb = b_ctx_out.localnet_learn_fdb;
+    rt_data->localnet_learn_fdb_changed = b_ctx_out.localnet_learn_fdb_changed;
     if (b_ctx_out.related_lports_changed ||
             b_ctx_out.non_vif_ports_changed ||
             b_ctx_out.local_lports_changed ||
+            b_ctx_out.localnet_learn_fdb_changed ||
             !hmap_is_empty(b_ctx_out.tracked_dp_bindings)) {
         engine_set_node_state(node, EN_UPDATED);
     }
@@ -3912,6 +3920,8 @@ init_lflow_ctx(struct engine_node *node,
     l_ctx_in->active_tunnels = &rt_data->active_tunnels;
     l_ctx_in->related_lport_ids = &rt_data->related_lports.lport_ids;
     l_ctx_in->binding_lports = &rt_data->lbinding_data.lports;
+    l_ctx_in->localnet_learn_fdb = rt_data->localnet_learn_fdb;
+    l_ctx_in->localnet_learn_fdb_changed = rt_data->localnet_learn_fdb_changed;
     l_ctx_in->chassis_tunnels = &non_vif_data->chassis_tunnels;
     l_ctx_in->lb_hairpin_use_ct_mark = n_opts->lb_hairpin_use_ct_mark;
     l_ctx_in->nd_ra_opts = &fo->nd_ra_opts;
diff --git a/tests/ovn.at b/tests/ovn.at
index 8ac82383d..48a3fd16a 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -31486,12 +31486,10 @@ as hv2 ovs-ofctl dump-flows br-int table=72 > hv2_offlows_table72.txt
 AT_CAPTURE_FILE([hv1_offlows_table72.txt])
 AT_CAPTURE_FILE([hv2_offlows_table72.txt])
 AT_CHECK_UNQUOTED([cat hv1_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
 
 AT_CHECK_UNQUOTED([cat hv2_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
 
@@ -31516,7 +31514,6 @@ priority=100,metadata=0x$dp_key,dl_dst=50:54:00:00:00:13 actions=load:0x$port_ke
 ])
 
 AT_CHECK_UNQUOTED([cat hv3_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
 
@@ -31567,22 +31564,16 @@ AT_CAPTURE_FILE([hv1_offlows_table72.txt])
 AT_CAPTURE_FILE([hv2_offlows_table72.txt])
 AT_CAPTURE_FILE([hv3_offlows_table72.txt])
 AT_CHECK_UNQUOTED([cat hv1_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
 
 AT_CHECK_UNQUOTED([cat hv2_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
 
 AT_CHECK_UNQUOTED([cat hv3_offlows_table72.txt | grep -v NXST | cut -d ' ' -f8- | sort], [0], [dnl
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
-priority=100,reg10=0x8000/0x8000,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:13 actions=load:0x1->NXM_NX_REG10[[8]]
 priority=100,reg14=0x$port_key,metadata=0x$dp_key,dl_src=50:54:00:00:00:14 actions=load:0x1->NXM_NX_REG10[[8]]
 ])
@@ -37150,8 +37141,8 @@ for i in 2 3; do
 done
 wait_column "$vif21_key" fdb port_key mac='"00:00:00:00:10:21"'
 
-check_flow_count hv1 4
-check_flow_count hv2 4
+check_flow_count hv1 2
+check_flow_count hv2 2
 
 # We now enable localnet_learn_fdb
 # We check how it behaves with existing vif entries in fdb
