Repository: sonic-net/sonic-utilities

Issue:
Generic_patch: AddRack: Port should be turned as admin up as last change
<!--
    If you are reporting a new issue, make sure that we do not have any duplicates
    already open. You can ensure this by searching the issue list for this
    repository. If there is a duplicate, please close your issue and add a comment
    to the existing issue instead.

    If you suspect your issue is a bug, please edit your issue description to
    include the BUG REPORT INFORMATION shown below. If you fail to provide this
    information within 7 days, we cannot debug your issue and will close it. We
    will, however, reopen it if you later provide the information.

    For more information about reporting issues, see
    https://github.com/Azure/SONiC/wiki#report-issues

    ---------------------------------------------------
    GENERAL SUPPORT INFORMATION
    ---------------------------------------------------

    The GitHub issue tracker is for bug reports and feature requests.
    General support can be found at the following locations:

    - SONiC Support Forums - https://groups.google.com/forum/#!forum/sonicproject

    ---------------------------------------------------
    BUG REPORT INFORMATION
    ---------------------------------------------------
    Use the commands below to provide key information from your environment:
    You do NOT have to include this information if this is a FEATURE REQUEST
-->

#### Description

In AddRack scenarion where it adds a port and related config, the port should be marked admin-up, only upon completing all other configuration


## Steps to reproduce the issue
1. Create a config-db.json w/o a port & related settings
2. Create a patch from diff between config-db.json w/o port and existing config_db.json that has all the config.
3. Apply it

#### Describe the results you received
```
Patch Applier: The patch was sorted into 48 changes:
Patch Applier:   * [{"op": "add", "path": "/ACL_TABLE/EVERFLOW/ports/8", "value": "Ethernet64"}]
Patch Applier:   * [{"op": "add", "path": "/ACL_TABLE/EVERFLOWV6/ports/8", "value": "Ethernet64"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33", "value": {"admin_status": "up"}}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/asn", "value": "64001"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/holdtime", "value": "10"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/keepalive", "value": "3"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/local_addr", "value": "10.0.0.32"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/name", "value": "ARISTA01T0"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/nhopself", "value": "0"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/10.0.0.33/rrclient", "value": "0"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42", "value": {"admin_status": "up"}}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/asn", "value": "64001"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/holdtime", "value": "10"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/keepalive", "value": "3"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/local_addr", "value": "fc00::41"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/name", "value": "ARISTA01T0"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/nhopself", "value": "0"}]
Patch Applier:   * [{"op": "add", "path": "/BGP_NEIGHBOR/fc00::42/rrclient", "value": "0"}]
Patch Applier:   * [{"op": "add", "path": "/BUFFER_PG/Ethernet64|3-4", "value": {"profile": "pg_lossless_40000_40m_profile"}}]
Patch Applier:   * [{"op": "add", "path": "/BUFFER_PG/Ethernet64|0", "value": {"profile": "ingress_lossy_profile"}}]
Patch Applier:   * [{"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|0-2", "value": {"profile": "egress_lossy_profile"}}]
Patch Applier:   * [{"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|3-4", "value": {"profile": "egress_lossless_profile"}}]
Patch Applier:   * [{"op": "add", "path": "/BUFFER_QUEUE/Ethernet64|5-6", "value": {"profile": "egress_lossy_profile"}}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR/Ethernet64", "value": {"name": "ARISTA01T0"}}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR/Ethernet64/port", "value": "Ethernet1"}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0", "value": {"hwsku": "Arista-VM"}}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0/lo_addr", "value": "None"}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0/mgmt_addr", "value": "172.16.131.40"}]
Patch Applier:   * [{"op": "add", "path": "/DEVICE_NEIGHBOR_METADATA/ARISTA01T0/type", "value": "ToRRouter"}]
Patch Applier:   * [{"op": "add", "path": "/INTERFACE/Ethernet64", "value": {}}]
Patch Applier:   * [{"op": "add", "path": "/INTERFACE/Ethernet64|10.0.0.32~131", "value": {}}]
Patch Applier:   * [{"op": "add", "path": "/INTERFACE/Ethernet64|FC00::41~1126", "value": {}}]
Patch Applier:   * [{"op": "replace", "path": "/PORT/Ethernet64/description", "value": "ARISTA01T0:Ethernet1"}]
Patch Applier:   * [{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}]
Patch Applier:   * [{"op": "add", "path": "/PORT_QOS_MAP/Ethernet64", "value": {"dscp_to_tc_map": "AZURE"}}]
Patch Applier:   * [{"op": "add", "path": "/PORT_QOS_MAP/Ethernet64/pfc_enable", "value": "3,4"}]
Patch Applier:   * [{"op": "add", "path": "/PORT_QOS_MAP/Ethernet64/pfc_to_queue_map", "value": "AZURE"}]
Patch Applier:   * [{"op": "add", "path": "/PORT_QOS_MAP/Ethernet64/tc_to_pg_map", "value": "AZURE"}]
Patch Applier:   * [{"op": "add", "path": "/PORT_QOS_MAP/Ethernet64/tc_to_queue_map", "value": "AZURE"}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|1", "value": {"scheduler": "scheduler.0"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|2", "value": {"scheduler": "scheduler.0"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|5", "value": {"scheduler": "scheduler.0"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|4", "value": {"scheduler": "scheduler.1"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|4/wred_profile", "value": "AZURE_LOSSLESS"}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|6", "value": {"scheduler": "scheduler.0"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|3", "value": {"scheduler": "scheduler.1"}}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|3/wred_profile", "value": "AZURE_LOSSLESS"}]
Patch Applier:   * [{"op": "add", "path": "/QUEUE/Ethernet64|0", "value": {"scheduler": "scheduler.0"}}]
```

#### Describe the results you expected
Same as above with exception that line that marked port up should be at the end.

`Patch Applier:   * [{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}]`


#### Additional information you deem important (e.g. issue happens only occasionally)


#### Sample files to help with repro

[issue_repro.tar.gz](https://github.com/Azure/sonic-utilities/files/7550247/issue_repro.tar.gz)






Discussion:
[from email thread]
Subject: Generic Patch Updater: Port admin status change

Hi @Mohamed Ghoneim,

The below topic needs vetting by SMEs, @Prince Sunny, @Neetha John, @Guohan Lu 

Request:
Whenever a patch has admin status down for  a port, order it first
“[{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "down"}]”

Vice versa, whenever it has it up, order it last.
“[{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}]”

Additionally, whenever a patch has only “port – up” but not down, insert a down at the start explicitly.

Reason:
When a patch has “admin down” for a port, likely it *could* be associated with more changes related to that port. For example, cable length, qos-parameters or alike. If these changes reach consumers, while port is still up, it could be a complex challenge to handle these changes for an active port. So marking the port as down at the start and then send the rest of the changes, would help consumers to process  other updates on that port, with ease.

In the same line, when a port is marked up (like in AddRack case --- ~~sample here~~), the patch is often accompanied by other changes related to the port. So send a patch to ensure, it is explicitly marked down, if it is not currently (or it could be redundant too – benign no-op). Then send all other changes and at the end , send the patch to mark it up. This way you let the consumers configure the port in inactive state and make it go active at the end.

Even in the case, where patch does not have other updates for port, as the port admin-status is like a *main* switch, turning it down at the start & up at the end, will work in all scenarios.

Thank you,
Renuka

[replying to the email thread i.e. last comment]
I have thought about this problem for a little bit and I think the solution would be to.
- If there is a change to a “port-critical” config that needs the port to be down 
  - we can inject port admin down before if the port is not already admin down
  - then the port will be brought back up afterwards **only if this is the final state in the patch**

This will take care of the 3 scenarios mentioned.

1) Whenever a patch has admin status down for a port, order it first
“[{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "down"}]”

If the patch contains "port-critical" config, then we will inject port down first if the port is not already down. This means the port admin down happened first.

2) Vice versa, whenever it has it up, order it last.
“[{"op": "add", "path": "/PORT/Ethernet64/admin_status", "value": "up"}]”

If the patch contains "port-critical" config, we will start by checking if the port is admin down, I think the port is most probably already down. In this case we will just turn it back up after the "port-critical" config. This means the port admin up happened last.

3) Additionally, whenever a patch has only “port – up” but not down, insert a down at the start explicitly.
If the patch contains "port-critical" config already, then we will turn the port-down first and then turn it back up afterwards.


**Identifying port-critical changes**
- Optimally we should mark them in YANG models using a YANG extension
  - Similar to the `CreateOnly` flag ext that we have the patch-sorter design doc [here](https://github.com/Azure/SONiC/blob/master/doc/config-generic-update-rollback/Json_Patch_Ordering_using_YANG_Models_Design.md#313-using-yang-models-to-host-flags-for-move-validation)
- Alternatively we can just handle identifying these configs in the code, maybe hard-coded into a python list or something

Resolving patch:
diff --git a/generic_config_updater/gu_common.py b/generic_config_updater/gu_common.py
--- a/generic_config_updater/gu_common.py
+++ b/generic_config_updater/gu_common.py
@@ -273,7 +273,13 @@ def create_path(self, tokens):
         return JsonPointer.from_parts(tokens).path
 
     def has_path(self, doc, path):
-        return JsonPointer(path).get(doc, default=None) is not None
+        return self.get_from_path(doc, path) is not None
+
+    def get_from_path(self, doc, path):
+        return JsonPointer(path).get(doc, default=None)
+
+    def is_config_different(self, path, current, target):
+        return self.get_from_path(current, path) != self.get_from_path(target, path)
 
     def get_xpath_tokens(self, xpath):
         """
@@ -548,7 +554,8 @@ def _get_xpath_tokens_from_leaf(self, model, token_index, path_tokens, config):
             # Source: Check examples in https://netopeer.liberouter.org/doc/libyang/master/html/howto_x_path.html
             return [f"{token}[.='{value}']"]
 
-        raise ValueError("Token not found")
+        raise ValueError(f"Path token not found.\n  model: {model}\n  token_index: {token_index}\n  " + \
+                         f"path_tokens: {path_tokens}\n  config: {config}")
 
     def _extractKey(self, tableKey, keys):
         keyList = keys.split()
@@ -712,7 +719,8 @@ def _get_path_tokens_from_leaf(self, model, token_index, xpath_tokens, config):
             list_idx = list_config.index(leaf_list_value)
             return [leaf_list_name, list_idx]
 
-        raise Exception("no leaf")
+        raise ValueError(f"Xpath token not found.\n  model: {model}\n  token_index: {token_index}\n  " + \
+                         f"xpath_tokens: {xpath_tokens}\n  config: {config}")
 
     def _extract_key_dict(self, list_token):
         # Example: VLAN_MEMBER_LIST[name='Vlan1000'][port='Ethernet8']
diff --git a/generic_config_updater/patch_sorter.py b/generic_config_updater/patch_sorter.py
--- a/generic_config_updater/patch_sorter.py
+++ b/generic_config_updater/patch_sorter.py
@@ -1,14 +1,14 @@
 import copy
 import json
 import jsonpatch
-from collections import deque
+from collections import deque, OrderedDict
 from enum import Enum
 from .gu_common import OperationWrapper, OperationType, GenericConfigUpdaterError, \
                        JsonChange, PathAddressing, genericUpdaterLogging
 
 class Diff:
     """
-    A class that contains the diff info between current and target configs. 
+    A class that contains the diff info between current and target configs.
     """
     def __init__(self, current_config, target_config):
         self.current_config = current_config
@@ -114,7 +114,7 @@ def _to_jsonpatch_add_operation(diff, current_config_tokens, target_config_token
             }
           Assume JsonMove:
             op_type=add, current_config_tokens=[dict1, key11], target_config_tokens=[dict1, key11]
-  
+
           Converting this to operation directly would result in:
             {"op":"add", "path":"/dict1/key11", "value":"value11"}
           BUT this is not correct since 'dict1' which does not exist in Current Config.
@@ -333,6 +333,189 @@ def _extend_moves(self, move, diff):
             for newmove in extender.extend(move, diff):
                 yield newmove
 
+class JsonPointerFilter:
+    """
+    A filtering class to get the paths matching the filter from the given config.
+    The patterns:
+    - Each pattern consist of multiple tokens
+    - Tokens are matched with the config from the root level
+    - Each token can be:
+      - '*' Will match all keys at the current level
+      - '@' Will be replaced by 'common_key' passed in 'get_paths'
+      - <other> Will match other strings that are not * nor @
+    - Token advanced options
+      - '*|@' Will match keys that end with '|common_key'
+      - '@|*' Will match keys that start with 'common_key|'
+      - '*|<other>' Will match keys that end with '|<other>'
+      - '<other>|*' Will match keys that start with '<other>|'
+    """
+    def __init__(self, patterns, path_addressing):
+        self.patterns = patterns
+        self.path_addressing = path_addressing
+
+    def get_paths(self, config, common_key=None):
+        for pattern in self.patterns:
+            for path in self._get_paths_recursive(config, pattern, [], 0, common_key):
+                yield path
+
+    def _get_paths_recursive(self, config, pattern_tokens, matching_tokens, idx, common_key):
+        if idx == len(pattern_tokens):
+            yield self.path_addressing.create_path(matching_tokens)
+            return
+
+        token = pattern_tokens[idx]
+        if common_key:
+            token = token.replace("@", common_key)
+
+        matching_keys = []
+        if token == "*":
+            matching_keys = config.keys()
+        elif token.startswith("*|"):
+            suffix = token[2:]
+            matching_keys = [key for key in config.keys() if key.endswith(suffix)]
+        elif token.endswith("|*"):
+            prefix = token[:-2]
+            matching_keys = [key for key in config.keys() if key.startswith(prefix)]
+        elif token in config:
+            matching_keys = [token]
+
+        for key in matching_keys:
+            matching_tokens.append(key)
+            for path in self._get_paths_recursive(config[key], pattern_tokens, matching_tokens, idx+1, common_key):
+                yield path
+            matching_tokens.pop()
+
+    def is_match(self, path):
+        tokens = self.path_addressing.get_path_tokens(path)
+        for pattern in self.patterns:
+            if len(pattern) != len(tokens):
+                return False
+
+            for idx in range(len(pattern)):
+                pattern_token = pattern[idx]
+                token = tokens[idx]
+
+                if not self._is_token_match(pattern_token, token):
+                    return False
+
+        return True
+
+    def _is_token_match(self, pattern_token, token):
+        if "|" in pattern_token:
+            pattern_token_parts = pattern_token.split("|", 1)
+            token_parts = token.split("|", 1)
+            if len(pattern_token_parts) != len(token_parts):
+                return False
+
+            return self._is_simple_token_match(pattern_token_parts[0], token_part[0]) and \
+                   self._is_simple_token_match(pattern_token_parts[1], token_part[1])
+
+        return self._is_simple_token_match(pattern_token, token)
+
+
+    def _is_simple_token_match(self, pattern_token, token):
+        if pattern_token == "*" or pattern_token == "@":
+            return True
+
+        return pattern_token == token
+
+class RequiredValueIdentifier:
+    """
+    A class that identifies the config that requires other fields to be of specific value
+    The "requiring" config is the config that requires other fields to be of specific value.
+    The "required" config is the confing that needs to be of specific value.
+    E.g. Changes to "QUEUE" table requires the corresponding "PORT" to be admin down.
+    """
+    def __init__(self, path_addressing):
+        # TODO: port-critical fields are hard-coded for now, it should be moved to YANG models
+        # settings format, each setting consist of:
+        #   [
+        #       "required_pattern": the list of tokens, where there is a single token with value '@' which is the common key
+        #                           with the requiring patterns
+        #       "required_value": the required value
+        #       "default_value": the default value of the required paths
+        #       "requiring_patterns": the patterns matching paths that requires the given value, each pattern can have '@'
+        #                             which will be replaced with the common key, '*' will match any symbol
+        #   }
+        self.settings = [
+            {
+                "required_pattern": ["PORT", "@", "admin_status"],
+                "required_value": "down",
+                "default_value": "down",
+                "requiring_patterns": [
+                        ["BUFFER_PG", "@|*"],
+                        ["BUFFER_PORT_EGRESS_PROFILE_LIST", "@"],
+                        ["BUFFER_PORT_INGRESS_PROFILE_LIST", "@"],
+                        ["BUFFER_QUEUE", "@|*"],
+                        ["PORT_QOS_MAP", "@"],
+                        ["QUEUE", "@|*"],
+                    ]
+            },
+        ]
+        self.path_addressing = path_addressing
+        for setting in self.settings:
+            required_pattern = setting["required_pattern"]
+            required_parent_pattern = required_pattern[:-1]
+            # replace the '@' with '*' so it can be used as a JsonPointerFilter
+            required_parent_pattern_with_asterisk = [token.replace("@", "*") for token in required_parent_pattern]
+            setting["required_parent_filter"] = JsonPointerFilter([required_parent_pattern_with_asterisk], path_addressing)
+            setting["required_field_name"] = required_pattern[-1]
+            for index, token in enumerate(required_pattern):
+                if token == "@":
+                    setting["common_key_index"] = index
+            setting["requiring_filter"] = JsonPointerFilter(setting["requiring_patterns"], path_addressing)
+
+
+    def get_required_value_data(self, configs):
+        data = {}
+        for setting in self.settings:
+            required_parent_filter = setting["required_parent_filter"]
+            required_field_name = setting["required_field_name"]
+            common_key_index = setting["common_key_index"]
+            required_value = setting["required_value"]
+            requiring_filter = setting["requiring_filter"]
+            for config in configs:
+                for required_parent_path in required_parent_filter.get_paths(config):
+                    parent_tokens = self.path_addressing.get_path_tokens(required_parent_path)
+                    required_path = self.path_addressing.create_path(parent_tokens+[required_field_name])
+                    common_key = parent_tokens[common_key_index]
+                    requires_paths = requiring_filter.get_paths(config, common_key)
+                    for requires_path in requires_paths:
+                        if requires_path not in data:
+                            data[requires_path] = set()
+                        data[requires_path].add((required_path, required_value))
+
+        sorted_paths = sorted(data.keys())
+        sorted_data = OrderedDict()
+        for path in sorted_paths:
+            sorted_data[path] = sorted(data[path])
+
+        return sorted_data
+
+    def get_value_or_default(self, config, path):
+        value = self.path_addressing.get_from_path(config, path)
+        if value is not None:
+            return value
+
+        # Check if parent exist
+        tokens = self.path_addressing.get_path_tokens(path)
+        parent_tokens = tokens[:-1]
+        field_name = tokens[-1]
+        parent_path = self.path_addressing.create_path(parent_tokens)
+        parent_value = self.path_addressing.get_from_path(config, parent_path)
+
+        if parent_value is None:
+            return None
+
+        return self._get_default_value_from_settings(parent_path, field_name)
+
+    def _get_default_value_from_settings(self, parent_path, field_name):
+        for setting in self.settings:
+            if setting["required_parent_filter"].is_match(parent_path) and field_name == setting["required_field_name"]:
+                return setting["default_value"]
+
+        return None
+
 class DeleteWholeConfigMoveValidator:
     """
     A class to validate not deleting whole config as it is not supported by JsonPatch lib.
@@ -388,19 +571,18 @@ def __init__(self, path_addressing):
         self.path_addressing = path_addressing
 
         # TODO: create-only fields are hard-coded for now, it should be moved to YANG models
-        # Each pattern consist of a list of tokens. Token matching starts from the root level of the config.
-        # Each token is either a specific key or '*' to match all keys.
-        self.create_only_patterns = [
-            ["PORT", "*", "lanes"],
-            ["LOOPBACK_INTERFACE", "*", "vrf_name"],
-            ["BGP_NEIGHBOR", "*", "holdtime"],
-            ["BGP_NEIGHBOR", "*", "keepalive"],
-            ["BGP_NEIGHBOR", "*", "name"],
-            ["BGP_NEIGHBOR", "*", "asn"],
-            ["BGP_NEIGHBOR", "*", "local_addr"],
-            ["BGP_NEIGHBOR", "*", "nhopself"],
-            ["BGP_NEIGHBOR", "*", "rrclient"],
-        ]
+        self.create_only_filter = JsonPointerFilter([
+                ["PORT", "*", "lanes"],
+                ["LOOPBACK_INTERFACE", "*", "vrf_name"],
+                ["BGP_NEIGHBOR", "*", "holdtime"],
+                ["BGP_NEIGHBOR", "*", "keepalive"],
+                ["BGP_NEIGHBOR", "*", "name"],
+                ["BGP_NEIGHBOR", "*", "asn"],
+                ["BGP_NEIGHBOR", "*", "local_addr"],
+                ["BGP_NEIGHBOR", "*", "nhopself"],
+                ["BGP_NEIGHBOR", "*", "rrclient"],
+            ],
+            path_addressing)
 
     def validate(self, move, diff):
         simulated_config = move.apply(diff.current_config)
@@ -443,26 +625,8 @@ def _parent_added_child_not_as_target(self, tokens, current_config, simulated_co
             return self.path_addressing.has_path(simulated_config, child_path)
 
     def _get_create_only_paths(self, config):
-        for pattern in self.create_only_patterns:
-            for create_only_path in self._get_create_only_path_recursive(config, pattern, [], 0):
-                yield create_only_path
-
-    def _get_create_only_path_recursive(self, config, pattern_tokens, matching_tokens, idx):
-        if idx == len(pattern_tokens):
-            yield '/' + '/'.join(matching_tokens)
-            return
-
-        matching_keys = []
-        if pattern_tokens[idx] == "*":
-            matching_keys = config.keys()
-        elif pattern_tokens[idx] in config:
-            matching_keys = [pattern_tokens[idx]]
-
-        for key in matching_keys:
-            matching_tokens.append(key)
-            for create_only_path in self._get_create_only_path_recursive(config[key], pattern_tokens, matching_tokens, idx+1):
-                yield create_only_path
-            matching_tokens.pop()
+        for path in self.create_only_filter.get_paths(config):
+            yield path
 
     def _value_exist_but_different(self, tokens, current_config_ptr, simulated_config_ptr):
         for token in tokens:
@@ -610,7 +774,7 @@ def _get_paths(self, current_ptr, target_ptr, tokens):
                 tokens.pop()
 
             return deleted_paths, added_paths
-        
+
         # current/target configs are not dict nor list, so handle them as string, int, bool, float
         if current_ptr != target_ptr:
             # tokens.append(token)
@@ -691,6 +855,63 @@ def _validate_table(self, table, config):
         # the only invalid case is if table exists and is empty
         return table not in config or config[table]
 
+class RequiredValueMoveValidator:
+    """
+    Check RequiredValueIdentifier class description first.
+
+    The validator checks the following:
+    - A move that is changing a requiring config, while the required path is not equal to the required value is rejected
+      E.g. A move that is changing "QUEUE" table while the corresponding "PORT" is not admin down is rejected
+    - A move that is changing the required path value to something other than the required value, while there are
+      requiring changes left is rejected
+      E.g. A move is changing "PORT" to admin up from down, while "QUEUE" table still have changes left is rejected.
+    """
+    def __init__(self, path_addressing):
+        self.path_addressing = path_addressing
+        self.identifier = RequiredValueIdentifier(path_addressing)
+
+    def validate(self, move, diff):
+        # ignore full config removal because it is not possible by JsonPatch lib
+        if move.op_type == OperationType.REMOVE and move.path == "":
+            return
+
+        current_config = diff.current_config
+        simulated_config = move.apply(current_config) # Config after applying just this move
+        target_config = diff.target_config # Final config after applying whole patch
+
+        # data dictionary:
+        # {
+        #   <path>: [(required_path, required_value), ...],
+        #   ...
+        # }
+        data = self.identifier.get_required_value_data([current_config, simulated_config, target_config])
+
+        # If move is changing a requiring path while the required path does not have the required value, reject the move
+        # E.g. if the move is changing port-critical configs while the port is up, reject the move
+        for path in data:
+            if self.path_addressing.is_config_different(path, current_config, simulated_config):
+                for required_path, required_value in data[path]:
+                    actual_value = self.identifier.get_value_or_default(current_config, required_path)
+                    if actual_value is None: # current config does not have this value at all
+                        continue
+                    if actual_value != required_value:
+                        return False
+
+        # If some changes to the requiring paths are still to take place and the move has changes
+        # to the required path, reject the move
+        # E.g. if there are still port-critical changes left and the move has changes to the port
+        #      admin status, reject the move
+        # This makes sure we don't change the required path unnecessarily.
+        for path in data:
+            if self.path_addressing.is_config_different(path, current_config, target_config):
+                for required_path, required_value in data[path]:
+                    current_value = self.identifier.get_value_or_default(current_config, required_path)
+                    simulated_value = self.identifier.get_value_or_default(simulated_config, required_path)
+                    if current_value != simulated_value and simulated_value != required_value:
+                        return False
+
+        return True
+
 class LowLevelMoveGenerator:
     """
     A class to generate the low level moves i.e. moves corresponding to differences between current/target config
@@ -759,7 +980,7 @@ def _traverse(self, current_ptr, target_ptr, current_tokens, target_tokens):
                     yield move
                 current_tokens.pop()
                 target_tokens.pop()
-            
+
             return
 
         # The current/target ptr are neither dict nor list, so they might be string, int, float, bool
@@ -911,6 +1132,99 @@ def _list_to_dict_with_count(self, items):
 
         return counts
 
+class RequiredValueMoveExtender:
+    """
+    Check RequiredValueIdentifier class description first.
+
+    The extender does the following:
+    - If the move that is changing a requiring config, while the required path is not equal to the required value, then
+      generate a move to turn the required path to the required value.
+      E.g. A move that is changing "QUEUE" table while the corresponding "PORT" is not admin down, then generate
+           a move to turn the "PORT" to admin down.
+    - If a move that is changing the required path value to something other than the required value, while there are
+      requiring changes left, then flip all the required paths in the move to the required value.
+      E.g. A move is changing "PORT" to admin up from down, while "QUEUE" table still have changes left, then flip
+           the "PORT" to admin down in the move.
+    """
+    def __init__(self, path_addressing, operation_wrapper):
+        self.path_addressing = path_addressing
+        self.identifier = RequiredValueIdentifier(path_addressing)
+        self.operation_wrapper = operation_wrapper
+
+    def extend(self, move, diff):
+        # ignore full config removal because it is not possible by JsonPatch lib
+        if move.op_type == OperationType.REMOVE and move.path == "":
+            return
+
+        current_config = diff.current_config
+        simulated_config = move.apply(current_config) # Config after applying just this move
+        target_config = diff.target_config # Final config after applying whole patch
+
+        # data dictionary:
+        # {
+        #   <path>: [(required_path, required_value), ...],
+        #   ...
+        # }
+        data = self.identifier.get_required_value_data([current_config, simulated_config, target_config])
+
+        # If move is changing a requiring path while the required path does not have the required value,
+        # flip the required path to the required value
+        # E.g. if the move is changing port-critical config while the port is admin up, create a move to
+        #      turn the port admin down
+        processed_moves = set()
+        for path in data:
+            if self.path_addressing.is_config_different(path, current_config, simulated_config):
+                for required_path, required_value in data[path]:
+                    actual_value = self.identifier.get_value_or_default(current_config, required_path)
+                    if actual_value is None: # current config does not have this value at all
+                        continue
+                    if actual_value != required_value:
+                        extended_move = JsonMove.from_operation({"op":"replace", "path":required_path, "value":required_value})
+                        if extended_move not in processed_moves:
+                            processed_moves.add(extended_move)
+                            yield extended_move
+
+        # If some changes to the requiring paths are still to take place and the move has changes
+        # to the required path, flip the required path to the required value.
+        # E.g. if there are still port-critical changes left and the move has changes to the port
+        #      admin status, flip the port to admin down in the move
+        # This makes sure we don't change the required path unnecessarily.
+        flip_path_value_tuples = set()
+        for path in data:
+            if self.path_addressing.is_config_different(path, current_config, target_config):
+                for required_path, required_value in data[path]:
+                    current_value = self.identifier.get_value_or_default(current_config, required_path)
+                    simulated_value = self.identifier.get_value_or_default(simulated_config, required_path)
+                    if current_value != simulated_value and simulated_value != required_value:
+                        flip_path_value_tuples.add((required_path, required_value))
+
+        if flip_path_value_tuples:
+            extended_move = self._flip(move, flip_path_value_tuples)
+            yield extended_move
+
+    def _flip(self, move, flip_path_value_tuples):
+        new_value = copy.deepcopy(move.value)
+        move_tokens = self.path_addressing.get_path_tokens(move.path)
+        for field_path, field_value in flip_path_value_tuples:
+            field_tokens = self.path_addressing.get_path_tokens(field_path)
+            new_value = self._change_value(field_tokens, field_value, move_tokens, new_value)
+
+        operation = self.operation_wrapper.create(move.op_type, move.path, new_value)
+        return JsonMove.from_operation(operation)
+
+    def _change_value(self, field_tokens, field_value, move_tokens, move_value):
+        rem_tokens = field_tokens[len(move_tokens):]
+        if not rem_tokens:
+            return field_value
+
+        move_value_ptr = move_value
+        for token in rem_tokens[:-1]:
+            move_value_ptr = move_value_ptr[token]
+
+        last_token = rem_tokens[-1]
+        move_value_ptr[last_token] = field_value
+        return move_value
+
 class UpperLevelMoveExtender:
     """
     A class to extend the given move by including its parent. It has 3 cases:
@@ -1084,7 +1398,8 @@ def __init__(self, operation_wrapper, config_wrapper, path_addressing):
 
     def create(self, algorithm=Algorithm.DFS):
         move_generators = [LowLevelMoveGenerator(self.path_addressing)]
-        move_extenders = [UpperLevelMoveExtender(),
+        move_extenders = [RequiredValueMoveExtender(self.path_addressing, self.operation_wrapper),
+                          UpperLevelMoveExtender(),
                           DeleteInsteadOfReplaceMoveExtender(),
                           DeleteRefsMoveExtender(self.path_addressing)]
         move_validators = [DeleteWholeConfigMoveValidator(),
@@ -1092,6 +1407,7 @@ def create(self, algorithm=Algorithm.DFS):
                            NoDependencyMoveValidator(self.path_addressing, self.config_wrapper),
                            UniqueLanesMoveValidator(),
                            CreateOnlyMoveValidator(self.path_addressing),
+                           RequiredValueMoveValidator(self.path_addressing),
                            NoEmptyTableMoveValidator(self.path_addressing)]
 
         move_wrapper = MoveWrapper(move_generators, move_extenders, move_validators)


Test patch:
diff --git a/tests/generic_config_updater/files/config_db_with_port_critical.json b/tests/generic_config_updater/files/config_db_with_port_critical.json
new file mode 100644
--- /dev/null
+++ b/tests/generic_config_updater/files/config_db_with_port_critical.json
@@ -0,0 +1,49 @@
+{
+    "PORT": {
+        "Ethernet4": {
+            "admin_status": "up",
+            "alias": "fortyGigE0/4",
+            "description": "Servers0:eth0",
+            "index": "1",
+            "lanes": "29,30,31,32",
+            "mtu": "9100",
+            "pfc_asym": "off",
+            "speed": "40000"
+        },
+        "Ethernet8": {
+            "admin_status": "up",
+            "alias": "fortyGigE0/8",
+            "description": "Servers1:eth0",
+            "index": "2",
+            "lanes": "33,34,35,36",
+            "pfc_asym": "off",
+            "speed": "40000"
+        },
+        "Ethernet12": {
+            "admin_status": "down",
+            "alias": "fortyGigE0/12",
+            "description": "Servers2:eth0",
+            "index": "3",
+            "lanes": "37,38,39,40",
+            "mtu": "9100",
+            "pfc_asym": "off",
+            "speed": "40000"
+        },
+        "Ethernet16": {
+            "alias": "fortyGigE0/16",
+            "description": "Servers3:eth0",
+            "index": "4",
+            "lanes": "41,42,43,44",
+            "pfc_asym": "off",
+            "speed": "40000"
+        }
+    },
+    "BUFFER_PG": {
+        "Ethernet4|0": {
+            "profile": "ingress_lossy_profile"
+        },
+        "Ethernet12|0": {
+            "profile": "ingress_lossy_profile"
+        }
+    }
+}
diff --git a/tests/generic_config_updater/files/patch_sorter_test_success.json b/tests/generic_config_updater/files/patch_sorter_test_success.json
--- a/tests/generic_config_updater/files/patch_sorter_test_success.json
+++ b/tests/generic_config_updater/files/patch_sorter_test_success.json
@@ -2974,5 +2974,1800 @@
                 }
             ]
         ]
+    },
+    "PORT_CRITICAL_CHANGE_AND_PORT_IS_ADMIN_UP": {
+        "desc": "Port critical change and the port is already admin up",
+        "current_config": {
+            "PORT": {
+                "Ethernet4": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/4",
+                    "description": "Servers0:eth0",
+                    "index": "1",
+                    "lanes": "29,30,31,32",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000"
+                }
+            },
+            "BUFFER_PROFILE": {
+                "egress_lossy_profile": {
+                    "dynamic_th": "3",
+                    "pool": "egress_lossy_pool",
+                    "size": "1518"
+                }
+            },
+            "BUFFER_POOL": {
+                "egress_lossy_pool": {
+                    "mode": "dynamic",
+                    "size": "7326924",
+                    "type": "egress"
+                }
+            }
+        },
+        "patch": [
+            {
+                "op": "add",
+                "path": "/BUFFER_PG",
+                "value": {
+                    "Ethernet4|0": {
+                        "profile": "egress_lossy_profile"
+                    }
+                }
+            }
+        ],
+        "expected_changes": [
+            [
+                {
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4/admin_status",
+                    "value": "down"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_PG",
+                    "value": {
+                        "Ethernet4|0": {
+                            "profile": "egress_lossy_profile"
+                        }
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4/admin_status",
+                    "value": "up"
+                }
+            ]
+        ]
+    },
+    "PORT_CRITICAL_CONFIG_AND_ADDING_ADMIN_UP_PORT": {
+        "desc": "Port critical change and the port with admin up is added in the same patch.",
+        "current_config": {
+            "BUFFER_PROFILE": {
+                "egress_lossy_profile": {
+                    "dynamic_th": "3",
+                    "pool": "egress_lossy_pool",
+                    "size": "1518"
+                }
+            },
+            "BUFFER_POOL": {
+                "egress_lossy_pool": {
+                    "mode": "dynamic",
+                    "size": "7326924",
+                    "type": "egress"
+                }
+            }
+        },
+        "patch": [
+            {
+                "op": "add",
+                "path": "/PORT",
+                "value": {
+                    "Ethernet4": {
+                        "admin_status": "up",
+                        "alias": "fortyGigE0/4",
+                        "description": "Servers0:eth0",
+                        "index": "1",
+                        "lanes": "29,30,31,32",
+                        "mtu": "9100",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_PG",
+                "value": {
+                    "Ethernet4|0": {
+                        "profile": "egress_lossy_profile"
+                    }
+                }
+            }
+        ],
+        "expected_changes": [
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT",
+                    "value": {
+                        "Ethernet4": {
+                            "admin_status": "down",
+                            "alias": "fortyGigE0/4",
+                            "description": "Servers0:eth0",
+                            "index": "1",
+                            "lanes": "29,30,31,32",
+                            "mtu": "9100",
+                            "pfc_asym": "off",
+                            "speed": "40000"
+                        }
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_PG",
+                    "value": {
+                        "Ethernet4|0": {
+                            "profile": "egress_lossy_profile"
+                        }
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4/admin_status",
+                    "value": "up"
+                }
+            ]
+        ]
+    },
+    "ADD_RACK": {
+        "desc": "Add a rack and all its related settings",
+        "current_config": {
+            "ACL_TABLE": {
+                "EVERFLOW": {
+                    "policy_desc": "EVERFLOW",
+                    "ports": [
+                        "Ethernet68",
+                        "Ethernet72"
+                    ],
+                    "stage": "ingress",
+                    "type": "MIRROR"
+                },
+                "EVERFLOWV6": {
+                    "policy_desc": "EVERFLOWV6",
+                    "ports": [
+                        "Ethernet68",
+                        "Ethernet72"
+                    ],
+                    "stage": "ingress",
+                    "type": "MIRRORV6"
+                }
+            },
+            "BGP_NEIGHBOR": {
+                "10.0.0.1": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.0",
+                    "name": "ARISTA01T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.5": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.4",
+                    "name": "ARISTA03T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.9": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.8",
+                    "name": "ARISTA05T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.13": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.12",
+                    "name": "ARISTA07T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.17": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.16",
+                    "name": "ARISTA09T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.21": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.20",
+                    "name": "ARISTA11T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.25": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.24",
+                    "name": "ARISTA13T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.29": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.28",
+                    "name": "ARISTA15T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.35": {
+                    "asn": "64002",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.34",
+                    "name": "ARISTA02T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.37": {
+                    "asn": "64003",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.36",
+                    "name": "ARISTA03T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.39": {
+                    "asn": "64004",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.38",
+                    "name": "ARISTA04T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.41": {
+                    "asn": "64005",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.40",
+                    "name": "ARISTA05T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.43": {
+                    "asn": "64006",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.42",
+                    "name": "ARISTA06T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.45": {
+                    "asn": "64007",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.44",
+                    "name": "ARISTA07T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.47": {
+                    "asn": "64008",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.46",
+                    "name": "ARISTA08T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.49": {
+                    "asn": "64009",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.48",
+                    "name": "ARISTA09T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.51": {
+                    "asn": "64010",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.50",
+                    "name": "ARISTA10T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.53": {
+                    "asn": "64011",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.52",
+                    "name": "ARISTA11T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.55": {
+                    "asn": "64012",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.54",
+                    "name": "ARISTA12T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.57": {
+                    "asn": "64013",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.56",
+                    "name": "ARISTA13T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.59": {
+                    "asn": "64014",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.58",
+                    "name": "ARISTA14T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.61": {
+                    "asn": "64015",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.60",
+                    "name": "ARISTA15T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "10.0.0.63": {
+                    "asn": "64016",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.62",
+                    "name": "ARISTA16T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::1a": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::19",
+                    "name": "ARISTA07T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::2": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::1",
+                    "name": "ARISTA01T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::2a": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::29",
+                    "name": "ARISTA11T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::3a": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::39",
+                    "name": "ARISTA15T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::4a": {
+                    "asn": "64003",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::49",
+                    "name": "ARISTA03T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::4e": {
+                    "asn": "64004",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::4d",
+                    "name": "ARISTA04T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::5a": {
+                    "asn": "64007",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::59",
+                    "name": "ARISTA07T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::5e": {
+                    "asn": "64008",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::5d",
+                    "name": "ARISTA08T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::6a": {
+                    "asn": "64011",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::69",
+                    "name": "ARISTA11T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::6e": {
+                    "asn": "64012",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::6d",
+                    "name": "ARISTA12T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::7a": {
+                    "asn": "64015",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::79",
+                    "name": "ARISTA15T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::7e": {
+                    "asn": "64016",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::7d",
+                    "name": "ARISTA16T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::12": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::11",
+                    "name": "ARISTA05T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::22": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::21",
+                    "name": "ARISTA09T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::32": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::31",
+                    "name": "ARISTA13T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::46": {
+                    "asn": "64002",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::45",
+                    "name": "ARISTA02T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::52": {
+                    "asn": "64005",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::51",
+                    "name": "ARISTA05T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::56": {
+                    "asn": "64006",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::55",
+                    "name": "ARISTA06T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::62": {
+                    "asn": "64009",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::61",
+                    "name": "ARISTA09T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::66": {
+                    "asn": "64010",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::65",
+                    "name": "ARISTA10T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::72": {
+                    "asn": "64013",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::71",
+                    "name": "ARISTA13T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::76": {
+                    "asn": "64014",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::75",
+                    "name": "ARISTA14T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                },
+                "fc00::a": {
+                    "asn": "65200",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::9",
+                    "name": "ARISTA03T2",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                }
+            },
+            "BUFFER_PG": {
+                "Ethernet68|0": {
+                    "profile": "ingress_lossy_profile"
+                },
+                "Ethernet68|3-4": {
+                    "profile": "pg_lossless_40000_40m_profile"
+                },
+                "Ethernet72|0": {
+                    "profile": "ingress_lossy_profile"
+                },
+                "Ethernet72|3-4": {
+                    "profile": "pg_lossless_40000_40m_profile"
+                }
+            },
+            "BUFFER_POOL": {
+                "egress_lossless_pool": {
+                    "mode": "static",
+                    "size": "12766208",
+                    "type": "egress"
+                },
+                "egress_lossy_pool": {
+                    "mode": "dynamic",
+                    "size": "7326924",
+                    "type": "egress"
+                },
+                "ingress_lossless_pool": {
+                    "mode": "dynamic",
+                    "size": "12766208",
+                    "type": "ingress"
+                }
+            },
+            "BUFFER_PROFILE": {
+                "egress_lossless_profile": {
+                    "pool": "egress_lossless_pool",
+                    "size": "0",
+                    "static_th": "12766208"
+                },
+                "egress_lossy_profile": {
+                    "dynamic_th": "3",
+                    "pool": "egress_lossy_pool",
+                    "size": "1518"
+                },
+                "ingress_lossy_profile": {
+                    "dynamic_th": "3",
+                    "pool": "ingress_lossless_pool",
+                    "size": "0"
+                },
+                "pg_lossless_40000_40m_profile": {
+                    "dynamic_th": "-3",
+                    "pool": "ingress_lossless_pool",
+                    "size": "56368",
+                    "xoff": "55120",
+                    "xon": "18432",
+                    "xon_offset": "2496"
+                },
+                "pg_lossless_40000_300m_profile": {
+                    "dynamic_th": "-3",
+                    "pool": "ingress_lossless_pool",
+                    "size": "56368",
+                    "xoff": "55120",
+                    "xon": "18432",
+                    "xon_offset": "2496"
+                }
+            },
+            "BUFFER_QUEUE": {
+                "Ethernet52|0-2": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet52|3-4": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet52|5-6": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet56|0-2": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet56|3-4": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet56|5-6": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet60|0-2": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet60|3-4": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet60|5-6": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet68|0-2": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet68|3-4": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet68|5-6": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet72|0-2": {
+                    "profile": "egress_lossy_profile"
+                },
+                "Ethernet72|3-4": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet72|5-6": {
+                    "profile": "egress_lossy_profile"
+                }
+            },
+            "DEVICE_NEIGHBOR": {
+                "Ethernet52": {
+                    "name": "ARISTA13T2",
+                    "port": "Ethernet2"
+                },
+                "Ethernet56": {
+                    "name": "ARISTA15T2",
+                    "port": "Ethernet1"
+                },
+                "Ethernet60": {
+                    "name": "ARISTA15T2",
+                    "port": "Ethernet2"
+                },
+                "Ethernet68": {
+                    "name": "ARISTA02T0",
+                    "port": "Ethernet1"
+                },
+                "Ethernet72": {
+                    "name": "ARISTA03T0",
+                    "port": "Ethernet1"
+                }
+            },
+            "DSCP_TO_TC_MAP": {
+                "AZURE": {
+                    "0": "1",
+                    "1": "1",
+                    "10": "1",
+                    "11": "1",
+                    "12": "1",
+                    "13": "1",
+                    "14": "1",
+                    "15": "1",
+                    "16": "1",
+                    "17": "1",
+                    "18": "1",
+                    "19": "1",
+                    "2": "1",
+                    "20": "1",
+                    "21": "1",
+                    "22": "1",
+                    "23": "1",
+                    "24": "1",
+                    "25": "1",
+                    "26": "1",
+                    "27": "1",
+                    "28": "1",
+                    "29": "1",
+                    "3": "3",
+                    "30": "1",
+                    "31": "1",
+                    "32": "1",
+                    "33": "1",
+                    "34": "1",
+                    "35": "1",
+                    "36": "1",
+                    "37": "1",
+                    "38": "1",
+                    "39": "1",
+                    "4": "4",
+                    "40": "1",
+                    "41": "1",
+                    "42": "1",
+                    "43": "1",
+                    "44": "1",
+                    "45": "1",
+                    "46": "5",
+                    "47": "1",
+                    "48": "6",
+                    "49": "1",
+                    "5": "2",
+                    "50": "1",
+                    "51": "1",
+                    "52": "1",
+                    "53": "1",
+                    "54": "1",
+                    "55": "1",
+                    "56": "1",
+                    "57": "1",
+                    "58": "1",
+                    "59": "1",
+                    "6": "1",
+                    "60": "1",
+                    "61": "1",
+                    "62": "1",
+                    "63": "1",
+                    "7": "1",
+                    "8": "0",
+                    "9": "1"
+                }
+            },
+            "INTERFACE": {
+                "Ethernet68": {},
+                "Ethernet68|10.0.0.34/31": {},
+                "Ethernet68|FC00::45/126": {},
+                "Ethernet72": {},
+                "Ethernet72|10.0.0.36/31": {},
+                "Ethernet72|FC00::49/126": {}
+            },
+            "MAP_PFC_PRIORITY_TO_QUEUE": {
+                "AZURE": {
+                    "0": "0",
+                    "1": "1",
+                    "2": "2",
+                    "3": "3",
+                    "4": "4",
+                    "5": "5",
+                    "6": "6",
+                    "7": "7"
+                }
+            },
+            "PORT": {
+                "Ethernet52": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/52",
+                    "description": "ARISTA13T2:Ethernet2",
+                    "index": "13",
+                    "lanes": "49,50,51,52",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                },
+                "Ethernet56": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/56",
+                    "description": "ARISTA15T2:Ethernet1",
+                    "index": "14",
+                    "lanes": "57,58,59,60",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                },
+                "Ethernet60": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/60",
+                    "description": "ARISTA15T2:Ethernet2",
+                    "index": "15",
+                    "lanes": "61,62,63,64",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                },
+                "Ethernet64": {
+                    "alias": "fortyGigE0/64",
+                    "description": "fortyGigE0/64",
+                    "index": "16",
+                    "lanes": "69,70,71,72",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                },
+                "Ethernet68": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/68",
+                    "description": "ARISTA02T0:Ethernet1",
+                    "index": "17",
+                    "lanes": "65,66,67,68",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                },
+                "Ethernet72": {
+                    "admin_status": "up",
+                    "alias": "fortyGigE0/72",
+                    "description": "ARISTA03T0:Ethernet1",
+                    "index": "18",
+                    "lanes": "73,74,75,76",
+                    "mtu": "9100",
+                    "pfc_asym": "off",
+                    "speed": "40000",
+                    "tpid": "0x8100"
+                }
+            },
+            "PORT_QOS_MAP": {
+                "Ethernet52": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+                "Ethernet56": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+                "Ethernet60": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+                "Ethernet68": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+                "Ethernet72": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                }
+            },
+            "TC_TO_PRIORITY_GROUP_MAP": {
+                "AZURE": {
+                    "0": "0",
+                    "1": "0",
+                    "2": "0",
+                    "3": "3",
+                    "4": "4",
+                    "5": "0",
+                    "6": "0",
+                    "7": "7"
+                }
+            },
+            "TC_TO_QUEUE_MAP": {
+                "AZURE": {
+                    "0": "0",
+                    "1": "1",
+                    "2": "2",
+                    "3": "3",
+                    "4": "4",
+                    "5": "5",
+                    "6": "6",
+                    "7": "7"
+                }
+            }
+        },
+        "patch": [
+            {
+                "op": "add",
+                "path": "/PORT/Ethernet64/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "replace",
+                "path": "/PORT/Ethernet64/description",
+                "value": "ARISTA01T0:Ethernet1"
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_QUEUE/Ethernet64|0-2",
+                "value": {
+                    "profile": "egress_lossy_profile"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_QUEUE/Ethernet64|3-4",
+                "value": {
+                    "profile": "egress_lossless_profile"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_QUEUE/Ethernet64|5-6",
+                "value": {
+                    "profile": "egress_lossy_profile"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/ACL_TABLE/EVERFLOWV6/ports/0",
+                "value": "Ethernet64"
+            },
+            {
+                "op": "add",
+                "path": "/ACL_TABLE/EVERFLOW/ports/0",
+                "value": "Ethernet64"
+            },
+            {
+                "op": "add",
+                "path": "/INTERFACE/Ethernet64",
+                "value": {}
+            },
+            {
+                "op": "add",
+                "path": "/INTERFACE/Ethernet64|10.0.0.32~131",
+                "value": {}
+            },
+            {
+                "op": "add",
+                "path": "/INTERFACE/Ethernet64|FC00::41~1126",
+                "value": {}
+            },
+            {
+                "op": "add",
+                "path": "/PORT_QOS_MAP/Ethernet64",
+                "value": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.33",
+                "value": {
+                    "admin_status": "up",
+                    "asn": "64001",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "10.0.0.32",
+                    "name": "ARISTA01T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::42",
+                "value": {
+                    "admin_status": "up",
+                    "asn": "64001",
+                    "holdtime": "10",
+                    "keepalive": "3",
+                    "local_addr": "fc00::41",
+                    "name": "ARISTA01T0",
+                    "nhopself": "0",
+                    "rrclient": "0"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::6a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.1/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.17/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::56/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::62/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::76/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.41/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.25/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::5e/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::52/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::7a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.35/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.63/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.53/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::32/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::22/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.9/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::6e/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.29/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.47/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.21/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::72/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.13/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.5/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.39/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.61/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.55/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.37/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::5a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::66/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::46/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::4e/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::2a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::2/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.49/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.59/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::1a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::12/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::4a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.45/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::7e/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.43/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::3a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.51/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/10.0.0.57/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/BGP_NEIGHBOR/fc00::a/admin_status",
+                "value": "up"
+            },
+            {
+                "op": "add",
+                "path": "/DEVICE_NEIGHBOR/Ethernet64",
+                "value": {
+                    "name": "ARISTA01T0",
+                    "port": "Ethernet1"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_PG/Ethernet64|3-4",
+                "value": {
+                    "profile": "pg_lossless_40000_40m_profile"
+                }
+            },
+            {
+                "op": "add",
+                "path": "/BUFFER_PG/Ethernet64|0",
+                "value": {
+                    "profile": "ingress_lossy_profile"
+                }
+            }
+        ],
+        "expected_changes": [
+            [
+                {
+                    "op": "add",
+                    "path": "/ACL_TABLE/EVERFLOW/ports/0",
+                    "value": "Ethernet64"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/ACL_TABLE/EVERFLOWV6/ports/0",
+                    "value": "Ethernet64"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.1/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.5/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.9/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.13/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.17/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.21/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.25/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.29/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.35/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.37/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.39/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.41/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.43/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.45/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.47/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.49/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.51/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.53/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.55/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.57/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.59/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.61/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.63/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::1a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::2/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::2a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::3a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::4a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::4e/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::5a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::5e/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::6a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::6e/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::7a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::7e/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::12/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::22/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::32/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::46/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::52/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::56/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::62/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::66/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::72/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::76/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::a/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_PG/Ethernet64|3-4",
+                    "value": {
+                        "profile": "pg_lossless_40000_40m_profile"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_PG/Ethernet64|0",
+                    "value": {
+                        "profile": "ingress_lossy_profile"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_QUEUE/Ethernet64|0-2",
+                    "value": {
+                        "profile": "egress_lossy_profile"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_QUEUE/Ethernet64|3-4",
+                    "value": {
+                        "profile": "egress_lossless_profile"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BUFFER_QUEUE/Ethernet64|5-6",
+                    "value": {
+                        "profile": "egress_lossy_profile"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/DEVICE_NEIGHBOR/Ethernet64",
+                    "value": {
+                        "name": "ARISTA01T0"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/DEVICE_NEIGHBOR/Ethernet64/port",
+                    "value": "Ethernet1"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/INTERFACE/Ethernet64",
+                    "value": {}
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/INTERFACE/Ethernet64|10.0.0.32~131",
+                    "value": {}
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/INTERFACE/Ethernet64|FC00::41~1126",
+                    "value": {}
+                }
+            ],
+            [
+                {
+                    "op": "replace",
+                    "path": "/PORT/Ethernet64/description",
+                    "value": "ARISTA01T0:Ethernet1"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT_QOS_MAP/Ethernet64",
+                    "value": {
+                        "dscp_to_tc_map": "AZURE"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT_QOS_MAP/Ethernet64/pfc_enable",
+                    "value": "3,4"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT_QOS_MAP/Ethernet64/pfc_to_queue_map",
+                    "value": "AZURE"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT_QOS_MAP/Ethernet64/tc_to_pg_map",
+                    "value": "AZURE"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT_QOS_MAP/Ethernet64/tc_to_queue_map",
+                    "value": "AZURE"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/PORT/Ethernet64/admin_status",
+                    "value": "up"
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/10.0.0.33",
+                    "value": {
+                        "admin_status": "up",
+                        "asn": "64001",
+                        "holdtime": "10",
+                        "keepalive": "3",
+                        "local_addr": "10.0.0.32",
+                        "name": "ARISTA01T0",
+                        "nhopself": "0",
+                        "rrclient": "0"
+                    }
+                }
+            ],
+            [
+                {
+                    "op": "add",
+                    "path": "/BGP_NEIGHBOR/fc00::42",
+                    "value": {
+                        "admin_status": "up",
+                        "asn": "64001",
+                        "holdtime": "10",
+                        "keepalive": "3",
+                        "local_addr": "fc00::41",
+                        "name": "ARISTA01T0",
+                        "nhopself": "0",
+                        "rrclient": "0"
+                    }
+                }
+            ]
+        ]
     }
 }
\ No newline at end of file
diff --git a/tests/generic_config_updater/patch_sorter_test.py b/tests/generic_config_updater/patch_sorter_test.py
--- a/tests/generic_config_updater/patch_sorter_test.py
+++ b/tests/generic_config_updater/patch_sorter_test.py
@@ -1,3 +1,4 @@
+from collections import OrderedDict
 import jsonpatch
 import unittest
 from unittest.mock import MagicMock, Mock
@@ -669,6 +670,84 @@ def test_simulate__applies_move(self):
         # Assert
         self.assertIs(self.any_diff, actual)
 
+class TestRequiredValueIdentifier(unittest.TestCase):
+    def test_hard_coded_required_value_data(self):
+        identifier = ps.RequiredValueIdentifier(PathAddressing())
+        config = {
+            "BUFFER_PG": {
+                "Ethernet4|0": {
+                    "profile": "ingress_lossy_profile"
+                },
+                "Ethernet8|3-4": {
+                    "profile": "pg_lossless_40000_40m_profile"
+                }
+            },
+            "BUFFER_QUEUE": {
+                "Ethernet0|5-6": {
+                    "profile": "egress_lossless_profile"
+                },
+                "Ethernet4|1": {
+                    "profile": "egress_lossy_profile"
+                }
+            },
+            "QUEUE": {
+                "Ethernet4|2": {
+                    "scheduler": "scheduler.0"
+                },
+                "Ethernet4|7-8": {
+                    "scheduler": "scheduler.0"
+                }
+            },
+            "BUFFER_PORT_INGRESS_PROFILE_LIST": {
+                "Ethernet0": {
+                    "profile_list": ["ingress_lossy_profile"]
+                },
+                "Ethernet4": {
+                    "profile_list": ["ingress_lossy_profile"]
+                },
+            },
+            "BUFFER_PORT_EGRESS_PROFILE_LIST": {
+                "Ethernet4": {
+                    "profile_list": ["egress_lossless_profile", "egress_lossy_profile"]
+                },
+                "Ethernet8": {
+                    "profile_list": ["ingress_lossy_profile"]
+                },
+            },
+            "PORT_QOS_MAP": {
+                "Ethernet4": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+                "Ethernet12": {
+                    "dscp_to_tc_map": "AZURE",
+                    "pfc_enable": "3,4",
+                    "pfc_to_queue_map": "AZURE",
+                    "tc_to_pg_map": "AZURE",
+                    "tc_to_queue_map": "AZURE"
+                },
+            },
+            "PORT": {
+                "Ethernet4": {}
+            }
+        }
+        expected = OrderedDict([
+            ('/BUFFER_PG/Ethernet4|0', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/BUFFER_PORT_EGRESS_PROFILE_LIST/Ethernet4', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/BUFFER_PORT_INGRESS_PROFILE_LIST/Ethernet4', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/BUFFER_QUEUE/Ethernet4|1', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/PORT_QOS_MAP/Ethernet4', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/QUEUE/Ethernet4|2', [('/PORT/Ethernet4/admin_status', 'down')]),
+            ('/QUEUE/Ethernet4|7-8', [('/PORT/Ethernet4/admin_status', 'down')]),
+        ])
+
+        actual = identifier.get_required_value_data([config])
+
+        self.assertEqual(expected, actual)
+
 class TestDeleteWholeConfigMoveValidator(unittest.TestCase):
     def setUp(self):
         self.operation_wrapper = OperationWrapper()
@@ -1270,6 +1349,472 @@ def test_validate__add_non_empty_table__success(self):
         # Act and assert
         self.assertTrue(self.validator.validate(move, diff))
 
+class TestRequiredValueMoveValidator(unittest.TestCase):
+    def setUp(self):
+        self.operation_wrapper = OperationWrapper()
+        path_addressing = PathAddressing()
+        self.validator = ps.RequiredValueMoveValidator(path_addressing)
+        self.validator.identifier.settings[0]["requiring_filter"] = ps.JsonPointerFilter([
+                ["BUFFER_PG", "@|*"],
+                ["PORT", "@", "mtu"]
+            ],
+            path_addressing)
+
+    def test_validate__critical_port_change(self):
+        # Each test format:
+        #   "<test-name>": {
+        #       "expected": "<True|False>",
+        #       "config": <config>,
+        #       "move": <move>,
+        #       "target_config": <OPTIONAL> <target-config-if-different-than-applying-move-to-config>
+        #   }
+        # Each test is testing different flag of:
+        #  - port-up: if port is up or not in current_config
+        #  - status-changing: if admin_status is changing from any state to another
+        #  - under-port: if the port-critical config is under port
+        #  - port-exist: if the port already exist in current_config
+        test_cases = self._get_critical_port_change_test_cases()
+        for test_case_name in test_cases:
+            with self.subTest(name=test_case_name):
+                self._run_single_test(test_cases[test_case_name])
+
+    def _run_single_test(self, test_case):
+        # Arrange
+        expected = test_case['expected']
+        current_config = test_case['config']
+        move = test_case['move']
+        target_config = test_case.get('target_config', move.apply(current_config))
+        diff = ps.Diff(current_config, target_config)
+
+        # Act and Assert
+        self.assertEqual(expected, self.validator.validate(move, diff))
+
+    def _get_critical_port_change_test_cases(self):
+        # port-up  status-changing  under-port  port-exist  verdict
+        # 1        1                1           1           0
+        # 1        1                1           0           invalid - port cannot be up while it does not exist
+        # 1        1                0           1           0
+        # 1        1                0           0           invalid - port cannot be up while it does not exist
+        # 1        0                1           1           0
+        # 1        0                1           0           invalid - port cannot be up while it does not exist
+        # 1        0                0           1           0
+        # 1        0                0           0           invalid - port cannot be up while it does not exist
+        # 0        1                1           1           0
+        # 0        1                1           0           0    can be 1?
+        # 0        1                0           1           0
+        # 0        1                0           0           0
+        # 0        0                1           1           1
+        # 0        0                1           0           1
+        # 0        0                0           1           1
+        # 0        0                0           0           invalid - port does not exist anyway
+        return {
+            "PORT_UP__STATUS_CHANGING__UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4",
+                    "value": { # only admin_status and mtu are different
+                        "admin_status": "down", # <== status changing
+                        "alias": "fortyGigE0/4",
+                        "description": "Servers0:eth0",
+                        "index": "1",
+                        "lanes": "29,30,31,32",
+                        "mtu": "9000", # <== critical config under port
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            # cannot test "port-up, status-changing, under-port, not port-exist"
+            #   because if port does not exist, it cannot be admin up
+            "PORT_UP__STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "",
+                    "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                            [
+                                # status-changing
+                                {"op":"replace", "path":"/PORT/Ethernet4/admin_status", "value": "down"},
+                                # port-critical config is not under port
+                                {"op":"replace", "path":"/BUFFER_PG/Ethernet4|0/profile", "value": "egress_lossy_profile"},
+                            ])
+                })
+            },
+            # cannot test "port-up, status-changing, not under-port, not port-exist"
+            #   because if port does not exist, it cannot be admin up
+            "PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4/mtu",
+                    "value": "9000"
+                })
+            },
+            # cannot test "port-up, not status-changing, under-port, not port-exist"
+            #   because if port does not exist, it cannot be admin up
+            "PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"replace",
+                    "path":"/BUFFER_PG/Ethernet4|0/profile",
+                    "value": "egress_lossy_profile"
+                })
+            },
+            # cannot test "port-up, not status-changing, not under-port, not port-exist"
+            #   because if port does not exist, it cannot be admin up
+            "NOT_PORT_UP__STATUS_CHANGING__UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet12",
+                    "value": {
+                        "admin_status": "up", # <== status changing
+                        "alias": "fortyGigE0/12",
+                        "description": "Servers2:eth0",
+                        "index": "3",
+                        "lanes": "37,38,39,40",
+                        "mtu": "9000", # <== critical config under port
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__UNDER_PORT__NOT_PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet20",
+                    "value": {
+                        "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                        "alias": "fortyGigE0/20",
+                        "description": "Servers4:eth0",
+                        "index": "5",
+                        "mtu": "9100",  # <== critical config under port
+                        "lanes": "45,46,47,48",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "",
+                    "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                        [
+                            # status-changing
+                            {"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value": "up"},
+                            # port-critical config is not under port
+                            {"op":"replace", "path":"/BUFFER_PG/Ethernet4|0/profile", "value": "egress_lossy_profile"},
+                        ]
+                    )
+                })
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__NOT_UNDER_PORT__NOT_PORT_EXIST": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "",
+                    "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                        [
+                            # status-changing
+                            {
+                                "op":"add",
+                                "path":"/PORT/Ethernet20",
+                                "value": {
+                                    "admin_status": "up", # <== status-changing from not-existing i.e. "down" to "up"
+                                    "alias": "fortyGigE0/20",
+                                    "description": "Servers4:eth0",
+                                    "index": "5",
+                                    "lanes": "45,46,47,48",
+                                    "pfc_asym": "off",
+                                    "speed": "40000"
+                                }
+                            },
+                            # port-critical config is not under port
+                            {
+                                "op":"add",
+                                "path":"/BUFFER_PG/Ethernet20|0",
+                                "value": {
+                                    "profile": "ingress_lossy_profile"
+                                }
+                            },
+                        ]
+                    )
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "/PORT/Ethernet12/mtu",
+                    "value": "9000"
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__NOT_PORT_EXIST": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet20",
+                    "value": {
+                        "alias": "fortyGigE0/20",
+                        "description": "Servers4:eth0",
+                        "index": "5",
+                        "mtu": "9100",  # <== critical config under port
+                        "lanes": "45,46,47,48",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"replace",
+                    "path":"/BUFFER_PG/Ethernet12|0/profile",
+                    "value": "egress_lossy_profile"
+                })
+            },
+            # cannot test "not port-up, not status-changing, not under-port, not port-exist"
+            #   because if port does not exist, it cannot be admin up
+
+            # The following set of cases check validation failure when a move is turning a port admin up, while still
+            # some critical changes not included at all in the move
+            "NOT_PORT_UP__STATUS_CHANGING__UNDER_PORT__PORT_EXIST__NOT_ALL_CRITICAL_CHANGES_INCLUDED": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "target_config": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                    [
+                        # The following critical change is not part of the move below.
+                        {"op": "replace", "path": "/PORT/Ethernet12/mtu", "value": "9000"}
+                    ]),
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value": "up"})
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__UNDER_PORT__NOT_PORT_EXIST__NOT_ALL_CRITICAL_CHANGES_INCLUDED": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "target_config": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                    [
+                        {
+                            "op": "add",
+                            "path": "/PORT/Ethernet20",
+                            "value": {
+                                "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                                "alias": "fortyGigE0/20",
+                                "description": "Servers4:eth0",
+                                "index": "5",
+                                "mtu": "9100",  # <== critical config under port which is not part of the move below
+                                "lanes": "45,46,47,48",
+                                "pfc_asym": "off",
+                                "speed": "40000"
+                            }
+                        }
+                    ]),
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet20",
+                    "value": {
+                        "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                        "alias": "fortyGigE0/20",
+                        "description": "Servers4:eth0",
+                        "index": "5",
+                        # "mtu": "9100", # <== critical change is left out
+                        "lanes": "45,46,47,48",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST__NOT_ALL_CRITICAL_CHANGES_INCLUDED": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "target_config": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                    [
+                        # The following critical change is not part of the move below
+                        {"op":"replace", "path":"/BUFFER_PG/Ethernet12|0/profile", "value": "egress_lossy_profile"},
+                    ]),
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value": "up"})
+            },
+            "NOT_PORT_UP__STATUS_CHANGING__NOT_UNDER_PORT__NOT_PORT_EXIST__NOT_ALL_CRITICAL_CHANGES_INCLUDED": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "target_config": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                    [
+                        {
+                            "op":"add",
+                            "path":"/BUFFER_PG/Ethernet20|0",
+                            "value": {
+                                "profile": "ingress_lossy_profile"
+                            }
+                        },
+                        {
+                            "op": "add",
+                            "path": "/PORT/Ethernet20",
+                            "value": {
+                                "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                                "alias": "fortyGigE0/20",
+                                "description": "Servers4:eth0",
+                                "index": "5",
+                                "lanes": "45,46,47,48",
+                                "pfc_asym": "off",
+                                "speed": "40000"
+                            }
+                        }
+                    ]),
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet20",
+                    "value": {
+                        "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                        "alias": "fortyGigE0/20",
+                        "description": "Servers4:eth0",
+                        "index": "5",
+                        # "mtu": "9100", # <== critical change is left out
+                        "lanes": "45,46,47,48",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                })
+            },
+            # Additional cases trying different operation to port-critical config i.e. REPLACE, REMOVE, ADD
+            "PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST__REMOVE": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "remove",
+                    "path": "/PORT/Ethernet4/mtu"
+                })
+            },
+            "PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST__ADD": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet8/mtu",
+                    "value": "9000"
+                })
+            },
+            "PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST__REMOVE": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"remove",
+                    "path":"/BUFFER_PG/Ethernet4|0/profile"
+                })
+            },
+            "PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST__ADD": {
+                "expected": False,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"add",
+                    "path":"/BUFFER_PG/Ethernet8|0",
+                    "value":{
+                        "profile": "ingress_lossy_profile"
+                    }
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST__REMOVE": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "remove",
+                    "path": "/PORT/Ethernet12/mtu"
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__UNDER_PORT__PORT_EXIST__ADD": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet16/mtu",
+                    "value": "9000"
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST__REMOVE": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"remove",
+                    "path":"/BUFFER_PG/Ethernet12|0"
+                })
+            },
+            "NOT_PORT_UP__NOT_STATUS_CHANGING__NOT_UNDER_PORT__PORT_EXIST__ADD": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op":"add",
+                    "path":"/BUFFER_PG/Ethernet16|0",
+                    "value": {
+                        "profile": "ingress_lossy_profile"
+                    }
+                })
+            },
+        }
+
+    def test_validate__no_critical_port_changes(self):
+        # Each test format:
+        #   "<test-name>": {
+        #       "expected": "<True|False>",
+        #       "config": <config>,
+        #       "move": <move>,
+        #       "target_config": <OPTIONAL> <target-config-if-different-than-applying-move-to-config>
+        #   }
+        # Each test is testing different flag of:
+        #  - port-up: if port is up or not in current_config
+        #  - status-changing: if admin_status is changing from any state to another
+        #  - under-port: if the port-critical config is under port
+        #  - port-exist: if the port already exist in current_config
+        test_cases = self._get_no_critical_port_change_test_cases()
+        for test_case_name in test_cases:
+            with self.subTest(name=test_case_name):
+                self._run_single_test(test_cases[test_case_name])
+
+    def _get_no_critical_port_change_test_cases(self):
+        return {
+            "REPLACE_NON_CRITICAL_CONFIG": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "replace",
+                    "path": "/PORT/Ethernet4/description",
+                    "value": "desc4"
+                })
+            },
+            "REMOVE_NON_CRITICAL_CONFIG": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "remove",
+                    "path": "/PORT/Ethernet4/description"
+                })
+            },
+            "ADD_NON_CRITICAL_CONFIG": {
+                "expected": True,
+                "config": Files.CONFIG_DB_WITH_PORT_CRITICAL,
+                "move": ps.JsonMove.from_operation({
+                    "op": "add",
+                    "path": "/PORT/Ethernet8/description",
+                    "value": "desc8"
+                })
+            },
+        }
+
+    def _apply_operations(self, config, operations):
+        return jsonpatch.JsonPatch(operations).apply(config)
+
 class TestLowLevelMoveGenerator(unittest.TestCase):
     def setUp(self):
         path_addressing = PathAddressing()
@@ -1522,6 +2067,405 @@ def get_diff(self, target_config_ops = None, current_config_ops = None):
 
         return ps.Diff(current_config, target_config)
 
+class TestRequiredValueMoveExtender(unittest.TestCase):
+    def setUp(self):
+        path_addressing = PathAddressing()
+        self.extender = ps.RequiredValueMoveExtender(path_addressing, OperationWrapper())
+        self.extender.identifier.settings[0]["requiring_filter"] = ps.JsonPointerFilter([
+                ["BUFFER_PG", "@|*"],
+                ["PORT", "@", "mtu"]
+            ],
+            path_addressing)
+
+    def test_extend__remove_whole_config__no_extended_moves(self):
+        # Arrange
+        move = ps.JsonMove.from_operation({"op":"remove", "path":""})
+        diff = ps.Diff(Files.ANY_CONFIG_DB, Files.ANY_OTHER_CONFIG_DB)
+        expected = []
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__port_up_and_no_critical_move__no_extended_moves(self):
+        # Arrange
+        move = ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet4/description", "value":"desc4"})
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = move.apply(current_config)
+        diff = ps.Diff(current_config, target_config)
+        expected = []
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__port_up_and_critical_move__turn_admin_status_down(self):
+        # Arrange
+        move = ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet4/mtu", "value":"9000"})
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = move.apply(current_config)
+        diff = ps.Diff(current_config, target_config)
+        expected = [{"op":"replace", "path":"/PORT/Ethernet4/admin_status", "value":"down"}]
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__port_turn_up_and_no_critical_move__no_extended_moves(self):
+        # Arrange
+        move = ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value":"up"})
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = move.apply(current_config)
+        diff = ps.Diff(current_config, target_config)
+        expected = []
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__port_turn_up_and_critical_move__flip_to_turn_down(self):
+        # Arrange
+        move = ps.JsonMove.from_operation({
+            "op":"replace",
+            "path":"/PORT/Ethernet12",
+            "value":{
+                "admin_status": "up", # <== Turn admin_status up
+                "alias": "fortyGigE0/12",
+                "description": "Servers2:eth0",
+                "index": "3",
+                "lanes": "37,38,39,40",
+                "mtu": "9000", # <== Critical move
+                "pfc_asym": "off",
+                "speed": "40000"
+            },
+        })
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = move.apply(current_config)
+        diff = ps.Diff(current_config, target_config)
+        expected = [{
+            "op":"replace",
+            "path":"/PORT/Ethernet12",
+            "value":{
+                "admin_status": "down", # <== Leave admin_status as down
+                "alias": "fortyGigE0/12",
+                "description": "Servers2:eth0",
+                "index": "3",
+                "lanes": "37,38,39,40",
+                "mtu": "9000", # <== Critical move
+                "pfc_asym": "off",
+                "speed": "40000"
+            },
+        }]
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__multi_port_turn_up_and_critical_move__multi_flip_to_turn_down(self):
+        # Arrange
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL, [
+            {"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value":"up"},
+            {"op":"add", "path":"/PORT/Ethernet16/admin_status", "value":"up"},
+            {"op":"add", "path":"/PORT/Ethernet12/mtu", "value":"9000"},
+            # Will not be part of the move, only in the final target config
+            {"op":"add", "path":"/PORT/Ethernet16/mtu", "value":"9000"}, 
+        ])
+        move = ps.JsonMove.from_operation({
+            "op":"replace",
+            "path":"/PORT",
+            # Following value is for the PORT part of the config
+            "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL["PORT"], [
+                {"op":"replace", "path":"/Ethernet12/admin_status", "value":"up"},
+                {"op":"add", "path":"/Ethernet16/admin_status", "value":"up"},
+                {"op":"add", "path":"/Ethernet12/mtu", "value":"9000"},
+            ])
+        })
+        diff = ps.Diff(current_config, target_config)
+        expected = [{
+            "op":"replace",
+            "path":"/PORT",
+            # Following value is for the PORT part of the config
+            "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL["PORT"], [
+                {"op":"replace", "path":"/Ethernet12/admin_status", "value":"down"},
+                {"op":"add", "path":"/Ethernet16/admin_status", "value":"down"},
+                {"op":"add", "path":"/Ethernet12/mtu", "value":"9000"},
+            ])
+        }]
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def test_extend__multiple_changes__multiple_extend_moves(self):
+        # Arrange
+        current_config = Files.CONFIG_DB_WITH_PORT_CRITICAL
+        target_config = self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL, [
+            {"op":"replace", "path":"/BUFFER_PG/Ethernet4|0/profile", "value": "egress_lossy_profile"},
+            {"op": "add", "path": "/PORT/Ethernet8/mtu", "value": "9000"},
+            {
+                "op": "add",
+                "path": "/PORT/Ethernet20", # <== adding a non-existing port
+                "value": {
+                    "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                    "alias": "fortyGigE0/20",
+                    "description": "Servers4:eth0",
+                    "index": "5",
+                    "mtu": "9100",  # <== critical config under port
+                    "lanes": "45,46,47,48",
+                    "pfc_asym": "off",
+                    "speed": "40000"
+                }
+            },
+            {"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value":"up"},
+            {"op":"add", "path":"/PORT/Ethernet16/admin_status", "value":"up"},
+            {"op":"add", "path":"/PORT/Ethernet12/mtu", "value":"9000"},
+            # Will not be part of the move, only in the final target config
+            {"op":"add", "path":"/PORT/Ethernet16/mtu", "value":"9000"}, 
+        ])
+        move = ps.JsonMove.from_operation({
+            "op":"replace",
+            "path":"",
+            "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL, [
+                {"op":"replace", "path":"/BUFFER_PG/Ethernet4|0/profile", "value": "egress_lossy_profile"},
+                {"op": "add", "path": "/PORT/Ethernet8/mtu", "value": "9000"},
+                {
+                    "op": "add",
+                    "path": "/PORT/Ethernet20", # <== adding a non-existing port
+                    "value": {
+                        "admin_status": "up", # <== status-changing from not-existing i.e "down" to "up"
+                        "alias": "fortyGigE0/20",
+                        "description": "Servers4:eth0",
+                        "index": "5",
+                        "mtu": "9100",  # <== critical config under port
+                        "lanes": "45,46,47,48",
+                        "pfc_asym": "off",
+                        "speed": "40000"
+                    }
+                },
+                {"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value":"up"},
+                {"op":"add", "path":"/PORT/Ethernet16/admin_status", "value":"up"},
+                {"op":"add", "path":"/PORT/Ethernet12/mtu", "value":"9000"},
+            ])
+        })
+        diff = ps.Diff(current_config, target_config)
+        expected = [
+            {"op":"replace", "path":"/PORT/Ethernet4/admin_status", "value":"down"},
+            {"op":"replace", "path":"/PORT/Ethernet8/admin_status", "value":"down"},
+            {
+                "op":"replace",
+                "path":"",
+                "value": self._apply_operations(Files.CONFIG_DB_WITH_PORT_CRITICAL, [
+                    {"op":"replace", "path":"/BUFFER_PG/Ethernet4|0/profile", "value": "egress_lossy_profile"},
+                    {"op": "add", "path": "/PORT/Ethernet8/mtu", "value": "9000"},
+                    {
+                        "op": "add",
+                        "path": "/PORT/Ethernet20", # <== adding a non-existing port
+                        "value": {
+                            "admin_status": "down", # <== flipping to down admin_status
+                            "alias": "fortyGigE0/20",
+                            "description": "Servers4:eth0",
+                            "index": "5",
+                            "mtu": "9100",  # <== critical config under port
+                            "lanes": "45,46,47,48",
+                            "pfc_asym": "off",
+                            "speed": "40000"
+                        }
+                    },
+                    {"op":"replace", "path":"/PORT/Ethernet12/admin_status", "value":"down"},
+                    {"op":"add", "path":"/PORT/Ethernet16/admin_status", "value":"down"},
+                    {"op":"add", "path":"/PORT/Ethernet12/mtu", "value":"9000"},
+                ])
+            }
+        ]
+
+        # Act
+        actual = self.extender.extend(move, diff)
+
+        # Assert
+        self._verify_moves(expected, actual)
+
+    def _verify_moves(self, ex_ops, moves):
+        moves_ops = [list(move.patch)[0] for move in moves]
+        self.assertCountEqual(ex_ops, moves_ops)
+
+    def _apply_operations(self, config, operations):
+        return jsonpatch.JsonPatch(operations).apply(config)
+
+    def test_flip(self):
+        test_cases = {
+            "ADD_ADMIN_STATUS": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200/admin_status", "value": "up"}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200/admin_status", "value": "down"})
+            },
+            "ADD_ETHERNET": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "up",
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "down",
+                }})
+            },
+            "ADD_ETHERNET_NO_ADMIN_STATUS": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "up",
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "down",
+                }})
+            },
+            "ADD_PORT": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"/PORT", "value": {
+                    "Ethernet200":{
+                        "admin_status": "up",
+                    }
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"/PORT", "value": {
+                    "Ethernet200":{
+                        "admin_status": "down",
+                    }
+                }})
+            },
+            "ADD_WHOLE_CONFIG": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200": {
+                            "admin_status": "up",
+                        }
+                    }
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200":{
+                            "admin_status": "down",
+                        }
+                    }
+                }}),
+            },
+            "ADD_WHOLE_CONFIG_NO_ADMIN_STATUS": {
+                "move": ps.JsonMove.from_operation({"op":"add", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200": {
+                        }
+                    }
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"add", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200":{
+                            "admin_status": "down",
+                        }
+                    }
+                }}),
+            },
+            "REPLACE_ADMIN_STATUS": {
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet200/admin_status", "value": "up"}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet200/admin_status", "value": "down"})
+            },
+            "REPLACE_ETHERNET": {
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "up",
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT/Ethernet200", "value": {
+                    "admin_status": "down",
+                }})
+            },
+            "REPLACE_PORT": {
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT", "value": {
+                    "Ethernet200":{
+                        "admin_status": "up",
+                    }
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"replace", "path":"/PORT", "value": {
+                    "Ethernet200":{
+                        "admin_status": "down",
+                    }
+                }})
+            },
+            "REPLACE_WHOLE_CONFIG": {
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200": {
+                            "admin_status": "up",
+                        }
+                    }
+                }}),
+                "port_names": ["Ethernet200"],
+                "expected": ps.JsonMove.from_operation({"op":"replace", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200":{
+                            "admin_status": "down",
+                        }
+                    }
+                }}),
+            },
+            "MULTIPLE_PORTS" :{
+                "move": ps.JsonMove.from_operation({"op":"replace", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200": {
+                            "admin_status": "up",
+                        },
+                        "Ethernet300": {
+                            "admin_status": "down",
+                        },
+                        "Ethernet400": {
+                            "admin_status": "up",
+                        },
+                        "Ethernet500": {
+                        },
+                    }
+                }}),
+                "port_names": ["Ethernet200", "Ethernet300", "Ethernet400", "Ethernet500"],
+                "expected": ps.JsonMove.from_operation({"op":"replace", "path":"", "value": {
+                    "PORT": {
+                        "Ethernet200": {
+                            "admin_status": "down",
+                        },
+                        "Ethernet300": {
+                            "admin_status": "down",
+                        },
+                        "Ethernet400": {
+                            "admin_status": "down",
+                        },
+                        "Ethernet500": {
+                            "admin_status": "down",
+                        },
+                    }
+                }}),
+            },
+        }
+
+        for test_case_name, test_case in test_cases.items():
+            with self.subTest(name=test_case_name):
+                move = test_case["move"]
+                port_names = test_case["port_names"]
+                expected = test_case["expected"]
+
+                path_value_tuples = [(f"/PORT/{port_name}/admin_status", "down") for port_name in port_names]
+
+                actual = self.extender._flip(move, path_value_tuples)
+                self.assertEqual(expected, actual)
+
 class TestUpperLevelMoveExtender(unittest.TestCase):
     def setUp(self):
         self.extender = ps.UpperLevelMoveExtender()
@@ -1832,12 +2776,16 @@ def verify(self, algo, algo_class):
         config_wrapper = ConfigWrapper()
         factory = ps.SortAlgorithmFactory(OperationWrapper(), config_wrapper, PathAddressing(config_wrapper))
         expected_generators = [ps.LowLevelMoveGenerator]
-        expected_extenders = [ps.UpperLevelMoveExtender, ps.DeleteInsteadOfReplaceMoveExtender, ps.DeleteRefsMoveExtender]
+        expected_extenders = [ps.RequiredValueMoveExtender,
+                              ps.UpperLevelMoveExtender,
+                              ps.DeleteInsteadOfReplaceMoveExtender,
+                              ps.DeleteRefsMoveExtender]
         expected_validator = [ps.DeleteWholeConfigMoveValidator,
                               ps.FullConfigMoveValidator,
                               ps.NoDependencyMoveValidator,
                               ps.UniqueLanesMoveValidator,
                               ps.CreateOnlyMoveValidator,
+                              ps.RequiredValueMoveValidator,
                               ps.NoEmptyTableMoveValidator]
 
         # Act
@@ -1873,6 +2821,9 @@ def test_patch_sorter_success(self):
         data = Files.PATCH_SORTER_TEST_SUCCESS
         skip_exact_change_list_match = False
         for test_case_name in data:
+            # Skipping ADD RACK case until fixing issue https://github.com/Azure/sonic-utilities/issues/2034
+            if test_case_name == "ADD_RACK":
+                continue
             with self.subTest(name=test_case_name):
                 self.run_single_success_case(data[test_case_name], skip_exact_change_list_match)