diff --git a/src/device/service/drivers/openconfig/GnmiTelemetry.py b/src/device/service/drivers/openconfig/GnmiTelemetry.py
new file mode 100644
index 0000000000000000000000000000000000000000..44b15d519d934fc5b464cf048145eebdcf8437d7
--- /dev/null
+++ b/src/device/service/drivers/openconfig/GnmiTelemetry.py
@@ -0,0 +1,166 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Ref: https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-specification.md
+# Ref: https://github.com/openconfig/gnmi/blob/master/proto/gnmi/gnmi.proto
+
+import anytree, logging, queue, threading
+from typing import Any, Iterator, List, Optional, Tuple, Union
+from common.type_checkers.Checkers import chk_float, chk_length, chk_string, chk_type
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES,
+    _Driver)
+
+LOGGER = logging.getLogger(__name__)
+
+SPECIAL_RESOURCE_MAPPINGS = {
+    RESOURCE_ENDPOINTS        : '/endpoints',
+    RESOURCE_INTERFACES       : '/interfaces',
+    RESOURCE_NETWORK_INSTANCES: '/net-instances',
+}
+
+class MonitoringThread(threading.Thread):
+    def __init__(self, in_subscriptions : queue.Queue, out_samples : queue.Queue) -> None:
+        super().__init__(daemon=True)
+        self._in_subscriptions = in_subscriptions
+        self._out_samples = out_samples
+
+    def run(self) -> None:
+        while True:
+            # TODO: req_iterator = generate_requests(self._in_subscriptions)
+            # TODO: stub.Subscribe(req_iterator)
+            self._out_samples.put_nowait((timestamp, resource_key, value))
+
+class EmulatedDriver(_Driver):
+    def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called
+        self.__lock = threading.Lock()
+
+        # endpoints = settings.get('endpoints', [])
+
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+
+        self.__in_subscriptions = queue.Queue()
+        self.__out_samples = queue.Queue()
+
+        self.__monitoring_thread = MonitoringThread(self.__in_subscriptions, self.__out_samples)
+
+    def Connect(self) -> bool:
+        # If started, assume it is already connected
+        if self.__started.is_set(): return True
+
+        # TODO: check capabilities
+        self.__monitoring_thread.start()
+
+        # Indicate the driver is now connected to the device
+        self.__started.set()
+        return True
+
+    def Disconnect(self) -> bool:
+        # Trigger termination of loops and processes
+        self.__terminate.set()
+
+        # TODO: send unsubscriptions
+        # TODO: terminate monitoring thread
+        # TODO: disconnect gRPC
+        self.__monitoring_thread.join()
+
+        # If not started, assume it is already disconnected
+        if not self.__started.is_set(): return True
+        return True
+
+    def GetInitialConfig(self) -> List[Tuple[str, Any]]:
+        with self.__lock:
+            return []
+
+    def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]:
+        chk_type('resources', resource_keys, list)
+        with self.__lock:
+            results = []
+            for i,resource_key in enumerate(resource_keys):
+                str_resource_name = 'resource_key[#{:d}]'.format(i)
+                try:
+                    chk_string(str_resource_name, resource_key, allow_empty=False)
+                    resource_key = SPECIAL_RESOURCE_MAPPINGS.get(resource_key, resource_key)
+                except Exception as e: # pylint: disable=broad-except
+                    LOGGER.exception('Exception validating {:s}: {:s}'.format(str_resource_name, str(resource_key)))
+                    results.append((resource_key, e)) # if validation fails, store the exception
+                    continue
+
+                # TODO: if resource_key == '/endpoints': retornar lista de endpoints
+                #       results.extend(endpoints)
+            return results
+
+    def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
+        chk_type('subscriptions', subscriptions, list)
+        if len(subscriptions) == 0: return []
+        results = []
+        with self.__lock:
+            for i,subscription in enumerate(subscriptions):
+                str_subscription_name = 'subscriptions[#{:d}]'.format(i)
+                try:
+                    chk_type(str_subscription_name, subscription, (list, tuple))
+                    chk_length(str_subscription_name, subscription, min_length=3, max_length=3)
+                    resource_key,sampling_duration,sampling_interval = subscription
+                    chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False)
+                    resource_path = resource_key.split('/')
+                    chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0)
+                    chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0)
+                except Exception as e: # pylint: disable=broad-except
+                    LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key)))
+                    results.append(e) # if validation fails, store the exception
+                    continue
+
+                # TODO: format subscription
+                # TODO: self.__in_subscriptions.put_nowait(subscription)
+                results.append(True)
+        return results
+
+    def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
+        chk_type('subscriptions', subscriptions, list)
+        if len(subscriptions) == 0: return []
+        results = []
+        resolver = anytree.Resolver(pathattr='name')
+        with self.__lock:
+            for i,resource in enumerate(subscriptions):
+                str_subscription_name = 'resources[#{:d}]'.format(i)
+                try:
+                    chk_type(str_subscription_name, resource, (list, tuple))
+                    chk_length(str_subscription_name, resource, min_length=3, max_length=3)
+                    resource_key,sampling_duration,sampling_interval = resource
+                    chk_string(str_subscription_name + '.resource_key', resource_key, allow_empty=False)
+                    resource_path = resource_key.split('/')
+                    chk_float(str_subscription_name + '.sampling_duration', sampling_duration, min_value=0)
+                    chk_float(str_subscription_name + '.sampling_interval', sampling_interval, min_value=0)
+                except Exception as e: # pylint: disable=broad-except
+                    LOGGER.exception('Exception validating {:s}: {:s}'.format(str_subscription_name, str(resource_key)))
+                    results.append(e) # if validation fails, store the exception
+                    continue
+
+                # TODO: format unsubscription
+                # TODO: self.__in_subscriptions.put_nowait(unsubscription)
+                results.append(True)
+        return results
+
+    def GetState(self, blocking=False, terminate : Optional[threading.Event] = None) -> Iterator[Tuple[str, Any]]:
+        while True:
+            if self.__terminate.is_set(): break
+            if terminate is not None and terminate.is_set(): break
+            try:
+                sample = self.__out_samples.get(block=blocking, timeout=0.1)
+            except queue.Empty:
+                if blocking: continue
+                return
+            if sample is None: continue
+            yield sample
diff --git a/src/device/service/drivers/openconfig/NetConfTelemetry.py b/src/device/service/drivers/openconfig/NetConfTelemetry.py
new file mode 100644
index 0000000000000000000000000000000000000000..1549d9811aa5d1c193a44ad45d0d7773236c0612
--- /dev/null
+++ b/src/device/service/drivers/openconfig/NetConfTelemetry.py
@@ -0,0 +1,14 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/device/service/drivers/openconfig/NetconfSessionHandler.py b/src/device/service/drivers/openconfig/NetconfSessionHandler.py
new file mode 100644
index 0000000000000000000000000000000000000000..746f11d120088429b5bf007839400e09842c0c5c
--- /dev/null
+++ b/src/device/service/drivers/openconfig/NetconfSessionHandler.py
@@ -0,0 +1,129 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, threading
+from typing import Any, List, Tuple
+from ncclient.manager import Manager, connect_ssh
+from common.tools.client.RetryDecorator import delay_exponential
+from common.type_checkers.Checkers import chk_length, chk_string, chk_type
+from device.service.driver_api.Exceptions import UnsupportedResourceKeyException
+from .templates import EMPTY_CONFIG, compose_config
+from .RetryDecorator import retry
+
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+LOGGER = logging.getLogger(__name__)
+
+class NetconfSessionHandler:
+    def __init__(self, address : str, port : int, **settings) -> None:
+        self.__lock = threading.RLock()
+        self.__connected = threading.Event()
+        self.__address = address
+        self.__port = int(port)
+        self.__username       = settings.get('username')
+        self.__password       = settings.get('password')
+        self.__vendor         = settings.get('vendor')
+        self.__key_filename   = settings.get('key_filename')
+        self.__hostkey_verify = settings.get('hostkey_verify', True)
+        self.__look_for_keys  = settings.get('look_for_keys', True)
+        self.__allow_agent    = settings.get('allow_agent', True)
+        self.__force_running  = settings.get('force_running', False)
+        self.__commit_per_delete  = settings.get('delete_rule', False)
+        self.__device_params  = settings.get('device_params', {})
+        self.__manager_params = settings.get('manager_params', {})
+        self.__nc_params      = settings.get('nc_params', {})
+        self.__manager : Manager   = None
+        self.__candidate_supported = False
+
+    def connect(self):
+        with self.__lock:
+            self.__manager = connect_ssh(
+                host=self.__address, port=self.__port, username=self.__username, password=self.__password,
+                device_params=self.__device_params, manager_params=self.__manager_params, nc_params=self.__nc_params,
+                key_filename=self.__key_filename, hostkey_verify=self.__hostkey_verify, allow_agent=self.__allow_agent,
+                look_for_keys=self.__look_for_keys)
+            self.__candidate_supported = ':candidate' in self.__manager.server_capabilities
+            self.__connected.set()
+
+    def disconnect(self):
+        if not self.__connected.is_set(): return
+        with self.__lock:
+            self.__manager.close_session()
+
+    @property
+    def use_candidate(self): return self.__candidate_supported and not self.__force_running
+
+    @property
+    def commit_per_rule(self): return self.__commit_per_delete 
+
+    @property
+    def vendor(self): return self.__vendor
+
+    @RETRY_DECORATOR
+    def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
+        with self.__lock:
+            return self.__manager.get(filter=filter, with_defaults=with_defaults)
+
+    @RETRY_DECORATOR
+    def edit_config(
+        self, config, target='running', default_operation=None, test_option=None,
+        error_option=None, format='xml'                                             # pylint: disable=redefined-builtin
+    ):
+        if config == EMPTY_CONFIG: return
+        with self.__lock:
+            self.__manager.edit_config(
+                config, target=target, default_operation=default_operation, test_option=test_option,
+                error_option=error_option, format=format)
+
+    def locked(self, target):
+        return self.__manager.locked(target=target)
+
+    def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None):
+        return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id)
+
+def edit_config(
+    netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, commit_per_rule= False,
+    target='running', default_operation='merge', test_option=None, error_option=None,
+    format='xml' # pylint: disable=redefined-builtin
+):
+    str_method = 'DeleteConfig' if delete else 'SetConfig'
+    LOGGER.info('[{:s}] resources = {:s}'.format(str_method, str(resources)))
+    results = [None for _ in resources]
+    for i,resource in enumerate(resources):
+        str_resource_name = 'resources[#{:d}]'.format(i)
+        try:
+            LOGGER.info('[{:s}] resource = {:s}'.format(str_method, str(resource)))
+            chk_type(str_resource_name, resource, (list, tuple))
+            chk_length(str_resource_name, resource, min_length=2, max_length=2)
+            resource_key,resource_value = resource
+            chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
+            str_config_message = compose_config(
+                resource_key, resource_value, delete=delete, vendor=netconf_handler.vendor)
+            if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
+            LOGGER.info('[{:s}] str_config_message[{:d}] = {:s}'.format(
+                str_method, len(str_config_message), str(str_config_message)))
+            netconf_handler.edit_config(
+                config=str_config_message, target=target, default_operation=default_operation,
+                test_option=test_option, error_option=error_option, format=format)
+            if commit_per_rule:
+                netconf_handler.commit()
+            results[i] = True
+        except Exception as e: # pylint: disable=broad-except
+            str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
+            msg = '[{:s}] Exception {:s} {:s}: {:s}'
+            LOGGER.exception(msg.format(str_method, str_operation, str_resource_name, str(resource)))
+            results[i] = e # if validation fails, store the exception
+    return results
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index ac67c4ab0d314adb3ce2af0aaffeda18e67334fc..64d05cb21188ca7221c3aa1b25848a8b6040e914 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import anytree, copy, logging, pytz, queue, re, threading
+import anytree, copy, logging, pytz, queue, re, threading, json, os, sys
 #import lxml.etree as ET
 from datetime import datetime, timedelta
 from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
@@ -31,6 +31,15 @@ from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_su
 from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse
 from .RetryDecorator import retry
 
+import grpc
+from google.protobuf.json_format import MessageToJson
+
+gnmi_path__ = os.path.dirname(os.path.abspath(__file__))
+sys.path.append(gnmi_path__)
+import gnmi_pb2_grpc
+import gnmi_pb2
+
+
 DEBUG_MODE = False
 logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
 logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
@@ -54,6 +63,7 @@ RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION,
 
 class NetconfSessionHandler:
     def __init__(self, address : str, port : int, **settings) -> None:
+        mensaje = f"__init__: address={address}, port={port}, settings={settings}"
         self.__lock = threading.RLock()
         self.__connected = threading.Event()
         self.__address = address
@@ -121,6 +131,106 @@ class NetconfSessionHandler:
     def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None):
         return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id)
 
+class gNMISessionHandler:
+    def __init__(self, address : str, **settings) -> None:
+        self.__lock = threading.RLock()
+        self.__connected = threading.Event()
+        self.__address = address
+        self.__port           = settings.get('gnmi_port')
+        self.__username       = settings.get('username')
+        self.__password       = settings.get('password')
+        self.__vendor         = settings.get('vendor')
+        self.__key_filename   = settings.get('key_filename')
+        self.__hostkey_verify = settings.get('hostkey_verify', True)
+        self.__look_for_keys  = settings.get('look_for_keys', True)
+        self.__allow_agent    = settings.get('allow_agent', True)
+        self.__force_running  = settings.get('force_running', False)
+        self.__commit_per_delete  = settings.get('delete_rule', False)
+        self.__device_params  = settings.get('device_params', {})
+        self.__manager_params = settings.get('manager_params', {})
+        self.__nc_params      = settings.get('nc_params', {})
+        self.__stub = None
+        self.__candidate_supported = False
+        self.__channel = None
+        self.__supportedEncodings = None
+        self.__options = Options()
+
+    def connect(self):
+        with self.__lock:
+            self.__channel = grpc.insecure_channel(str(self.__address)+':'+self.__port)
+            self.__stub = gnmi_pb2_grpc.gNMIStub(self.__channel)
+            metadata = [('username',self.__username ), ('password', self.__password)]
+            req = gnmi_pb2.CapabilityRequest()
+            response = self.__stub.Capabilities(req, metadata=metadata)
+            data = json.loads(MessageToJson(response))
+            self.__supportedEncodings = data['supportedEncodings']
+            # TODO: self.__candidate_supported = 
+            self.__connected.set()
+
+    def disconnect(self):
+        if not self.__connected.is_set(): return
+        with self.__lock:
+            self.__channel.close()
+
+    def subscribeStreaming(self, subscription : Tuple[str, float, float], out_samples : queue.Queue) -> None:
+        resource_key, sampling_duration, sampling_interval = subscription
+        options = copy.deepcopy(self.__options)
+        options.xpaths = [parse_xpath(resource_key)]
+        options.timeout = int(sampling_duration)
+        options.interval = int(sampling_interval)
+        req_iterator = gen_request(options)
+        metadata = [('username',self.__username), ('password', self.__password)]
+        responses = self.__stub.Subscribe(req_iterator, self.__options.timeout, metadata=metadata)
+        previous_sample = None
+        delta = 0.0
+        previous_timestamp = datetime.timestamp(datetime.utcnow())
+        for response in responses:
+            data = json.loads(MessageToJson(response))
+            if data.get("update") is not None and data.get("update").get("update") != None:
+                now = datetime.timestamp(datetime.utcnow())
+                for element in data['update']['update']:
+                    counter_name = split_resource_key(dict_to_xpath(element['path']))
+                    if counter_name == split_resource_key(resource_key):
+                        value = int(element['val']['uintVal'])
+                        delay = now - previous_timestamp
+                        if previous_sample is not None: delta = (value - previous_sample)/delay
+                        previous_sample = int(value)
+                        previous_timestamp = now
+                        sample = (now, resource_key, delta)
+                        out_samples.put_nowait(sample)
+
+    @property
+    def use_candidate(self): return self.__candidate_supported and not self.__force_running
+
+    @property
+    def commit_per_rule(self): return self.__commit_per_delete 
+
+    @property
+    def vendor(self): return self.__vendor
+
+    @RETRY_DECORATOR
+    def get(self): # pylint: disable=redefined-builtin
+        return False
+
+    @RETRY_DECORATOR
+    def edit_config(
+        self, config, target='running', default_operation=None, test_option=None,
+        error_option=None, format='xml'                                             # pylint: disable=redefined-builtin
+    ):
+        if config == EMPTY_CONFIG: return
+        with self.__lock:
+            self.__manager.edit_config(
+                config, target=target, default_operation=default_operation, test_option=test_option,
+                error_option=error_option, format=format)
+
+    @RETRY_DECORATOR
+    def locked(self, target):
+        return self.__manager.locked(target=target)
+
+    @RETRY_DECORATOR
+    def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None):
+        return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id)
+
 def compute_delta_sample(previous_sample, previous_timestamp, current_sample, current_timestamp):
     if previous_sample is None: return None
     if previous_timestamp is None: return None
@@ -141,13 +251,14 @@ def compute_delta_sample(previous_sample, previous_timestamp, current_sample, cu
     return delta_sample
 
 class SamplesCache:
-    def __init__(self, netconf_handler : NetconfSessionHandler, logger : logging.Logger) -> None:
+    def __init__(self, netconf_handler : NetconfSessionHandler, gNMI_handler : gNMISessionHandler, logger : logging.Logger) -> None:
         self.__netconf_handler = netconf_handler
         self.__logger = logger
         self.__lock = threading.Lock()
         self.__timestamp = None
         self.__absolute_samples = {}
         self.__delta_samples = {}
+        self.__gNMI_handler = gNMI_handler
 
     def _refresh_samples(self) -> None:
         with self.__lock:
@@ -192,6 +303,24 @@ def do_sampling(
     except: # pylint: disable=bare-except
         logger.exception('Error retrieving samples')
 
+class Options:
+    def __init__(self, xpaths=None, prefix=None, mode=0, submode=0, suppress=False, interval=0,
+                 encoding='JSON', heartbeat=0, qos=None, aggregate=False, server=None, username='admin', password='admin', timeout=None):
+        self.xpaths = xpaths
+        self.prefix = prefix
+        self.mode = mode
+        self.submode = submode
+        self.suppress = suppress
+        self.interval = interval
+        self.encoding = encoding
+        self.heartbeat = heartbeat
+        self.qos = qos
+        self.aggregate = aggregate
+        self.server = server
+        self.username = username
+        self.password = password
+        self.timeout = timeout
+
 def edit_config(
     netconf_handler : NetconfSessionHandler, logger : logging.Logger, resources : List[Tuple[str, Any]], delete=False,
     commit_per_rule=False, target='running', default_operation='merge', test_option=None, error_option=None,
@@ -248,6 +377,7 @@ class OpenConfigDriver(_Driver):
         self.__subscriptions = TreeNode('.')
         self.__started = threading.Event()
         self.__terminate = threading.Event()
+        self.__gnmi_monitoring = settings.get('monitoring_protocol') == 'gnmi'
         self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events
         self.__scheduler.configure(
             jobstores = {'default': MemoryJobStore()},
@@ -256,12 +386,16 @@ class OpenConfigDriver(_Driver):
             timezone=pytz.utc)
         self.__out_samples = queue.Queue()
         self.__netconf_handler = NetconfSessionHandler(self.address, self.port, **(self.settings))
-        self.__samples_cache = SamplesCache(self.__netconf_handler, self.__logger)
+        self.__gNMI_handler : gNMISessionHandler = gNMISessionHandler(address, **settings)
+        self.__samples_cache = SamplesCache(self.__netconf_handler, self.__gNMI_handler, self.__logger)
 
     def Connect(self) -> bool:
         with self.__lock:
             if self.__started.is_set(): return True
             self.__netconf_handler.connect()
+            if self.__gnmi_monitoring: 
+                self.__gNMI_handler.connect()
+                LOGGER.debug('Using gNMI as monitoring protocol')
             # Connect triggers activation of sampling events that will be scheduled based on subscriptions
             self.__scheduler.start()
             self.__started.set()
@@ -275,7 +409,7 @@ class OpenConfigDriver(_Driver):
             if not self.__started.is_set(): return True
             # Disconnect triggers deactivation of sampling events
             self.__scheduler.shutdown()
-            self.__netconf_handler.disconnect()
+            if self.__gnmi_monitoring: self.__netconf_handler.disconnect()
             return True
 
     @metered_subclass_method(METRICS_POOL)
@@ -362,7 +496,13 @@ class OpenConfigDriver(_Driver):
                     end_date = start_date + timedelta(seconds=sampling_duration)
 
                 job_id = 'k={:s}/d={:f}/i={:f}'.format(resource_key, sampling_duration, sampling_interval)
-                job = self.__scheduler.add_job(
+               
+                if self.__gnmi_monitoring:
+                    LOGGER.debug('Processing gNMI subscription: '+ str(subscription))
+                    job = threading.Thread(target=self.__gNMI_handler.subscribeStreaming, args=(subscription, self.__out_samples))
+                    job.start()
+                else:
+                    job = self.__scheduler.add_job(
                     do_sampling, args=(self.__samples_cache, self.__logger, resource_key, self.__out_samples),
                     kwargs={}, id=job_id, trigger='interval', seconds=sampling_interval,
                     start_date=start_date, end_date=end_date, timezone=pytz.utc)
@@ -426,4 +566,4 @@ class OpenConfigDriver(_Driver):
                 if blocking: continue
                 return
             if sample is None: continue
-            yield sample
+            yield sample
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/SamplesCache.py b/src/device/service/drivers/openconfig/SamplesCache.py
new file mode 100644
index 0000000000000000000000000000000000000000..24dc33663f1676e0ccf2096ec71b7f6448322740
--- /dev/null
+++ b/src/device/service/drivers/openconfig/SamplesCache.py
@@ -0,0 +1,100 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Collection of samples through NetConf is very slow and each request collects all the data.
+# Populate a cache periodically (when first interface is interrogated).
+# Evict data after some seconds, when data is considered as outdated
+
+import copy, queue, logging, re, threading
+from datetime import datetime
+from typing import Dict, Tuple
+from .templates import get_filter, parse
+from .NetconfSessionHandler import NetconfSessionHandler
+
+SAMPLE_EVICTION_SECONDS = 30.0 # seconds
+SAMPLE_RESOURCE_KEY = 'interfaces/interface/state/counters'
+
+RE_GET_ENDPOINT_FROM_INTERFACE_KEY = re.compile(r'.*interface\[([^\]]+)\].*')
+RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^\]]+)'\].*")
+
+LOGGER = logging.getLogger(__name__)
+
+def compute_delta_sample(previous_sample, previous_timestamp, current_sample, current_timestamp):
+    if previous_sample is None: return None
+    if previous_timestamp is None: return None
+    if current_sample is None: return None
+    if current_timestamp is None: return None
+    delay = current_timestamp - previous_timestamp
+    field_keys = set(previous_sample.keys()).union(current_sample.keys())
+    field_keys.discard('name')
+    delta_sample = {'name': previous_sample['name']}
+    for field_key in field_keys:
+        previous_sample_value = previous_sample[field_key]
+        if not isinstance(previous_sample_value, (int, float)): continue
+        current_sample_value = current_sample[field_key]
+        if not isinstance(current_sample_value, (int, float)): continue
+        delta_value = current_sample_value - previous_sample_value
+        if delta_value < 0: continue
+        delta_sample[field_key] = delta_value / delay
+    return delta_sample
+
+class SamplesCache:
+    def __init__(self, netconf_handler : NetconfSessionHandler) -> None:
+        self.__netconf_handler = netconf_handler
+        self.__lock = threading.Lock()
+        self.__timestamp = None
+        self.__absolute_samples = {}
+        self.__delta_samples = {}
+
+    def _refresh_samples(self) -> None:
+        with self.__lock:
+            try:
+                now = datetime.timestamp(datetime.utcnow())
+                if self.__timestamp is not None and (now - self.__timestamp) < SAMPLE_EVICTION_SECONDS: return
+                str_filter = get_filter(SAMPLE_RESOURCE_KEY)
+                xml_data = self.__netconf_handler.get(filter=str_filter).data_ele
+                interface_samples = parse(SAMPLE_RESOURCE_KEY, xml_data)
+                for interface,samples in interface_samples:
+                    match = RE_GET_ENDPOINT_FROM_INTERFACE_KEY.match(interface)
+                    if match is None: continue
+                    interface = match.group(1)
+                    delta_sample = compute_delta_sample(
+                        self.__absolute_samples.get(interface), self.__timestamp, samples, now)
+                    if delta_sample is not None: self.__delta_samples[interface] = delta_sample
+                    self.__absolute_samples[interface] = samples
+                self.__timestamp = now
+            except: # pylint: disable=bare-except
+                LOGGER.exception('Error collecting samples')
+
+    def get(self, resource_key : str) -> Tuple[float, Dict]:
+        self._refresh_samples()
+        match = RE_GET_ENDPOINT_FROM_INTERFACE_XPATH.match(resource_key)
+        with self.__lock:
+            if match is None: return self.__timestamp, {}
+            interface = match.group(1)
+            return self.__timestamp, copy.deepcopy(self.__delta_samples.get(interface, {}))
+
+def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples : queue.Queue) -> None:
+    try:
+        timestamp, samples = samples_cache.get(resource_key)
+        counter_name = resource_key.split('/')[-1].split(':')[-1]
+        value = samples.get(counter_name)
+        if value is None:
+            LOGGER.warning('[do_sampling] value not found for {:s}'.format(resource_key))
+            return
+        # resource_key template: //oci:interfaces/oci:interface[oci:name='{:s}']/state/counters/{:s}
+        sample = (timestamp, resource_key, value)
+        out_samples.put_nowait(sample)
+    except: # pylint: disable=bare-except
+        LOGGER.exception('Error retrieving samples')
diff --git a/src/device/service/drivers/openconfig/TelemetryProtocolEnum.py b/src/device/service/drivers/openconfig/TelemetryProtocolEnum.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5927848fee942cc37ab883a8c9b29b0efbe33ad
--- /dev/null
+++ b/src/device/service/drivers/openconfig/TelemetryProtocolEnum.py
@@ -0,0 +1,27 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import enum
+from typing import Optional
+
+class TelemetryProtocolEnum(enum.Enum):
+    GNMI    = 'gnmi'
+    NETCONF = 'netconf'
+
+DEFAULT_TELEMETRY_PROTOCOL = TelemetryProtocolEnum.NETCONF
+
+def parse_telemetry_protocol(telemetry_protocol : Optional[str] = None) -> TelemetryProtocolEnum:
+    if telemetry_protocol is None: return DEFAULT_TELEMETRY_PROTOCOL
+    # pylint: disable=no-member
+    return TelemetryProtocolEnum._member_map_.get(telemetry_protocol, DEFAULT_TELEMETRY_PROTOCOL)
diff --git a/src/device/service/drivers/openconfig/_Telemetry.py b/src/device/service/drivers/openconfig/_Telemetry.py
new file mode 100644
index 0000000000000000000000000000000000000000..efd05993b2bbcac8441f3022b659e40a8c54323e
--- /dev/null
+++ b/src/device/service/drivers/openconfig/_Telemetry.py
@@ -0,0 +1,27 @@
+# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+class _Telemetry:
+    def __init__(self) -> None:
+        pass
+
+    def subscribe(self) -> None:
+        pass
+
+    def unsubscribe(self) -> None:
+        pass
+
+    def get_samples_queue(self) -> None:
+        pass
diff --git a/src/device/service/drivers/openconfig/gnmi.proto b/src/device/service/drivers/openconfig/gnmi.proto
new file mode 100644
index 0000000000000000000000000000000000000000..292880a55586f5a5c05b0edcfc0f2f73baf7be13
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi.proto
@@ -0,0 +1,501 @@
+syntax = "proto3";
+
+import "google/protobuf/any.proto";
+import "google/protobuf/descriptor.proto";
+// import gnmi_ext.proto;
+
+// Package gNMI defines a service specification for the gRPC Network Management
+// Interface. This interface is defined to be a standard interface via which
+// a network management system ("client") can subscribe to state values,
+// retrieve snapshots of state information, and manipulate the state of a data
+// tree supported by a device ("target").
+//
+// This document references the gNMI Specification which can be found at
+// http://github.com/openconfig/reference/blob/master/rpc/gnmi
+package gnmi;
+
+// Define a protobuf FileOption that defines the gNMI service version.
+extend google.protobuf.FileOptions {
+  // The gNMI service semantic version.
+  string gnmi_service = 1001;
+}
+
+// gNMI_service is the current version of the gNMI service, returned through
+// the Capabilities RPC.
+option (gnmi_service) = "0.8.0";
+
+option go_package = "github.com/openconfig/gnmi/proto/gnmi";
+option java_multiple_files = true;
+option java_outer_classname = "GnmiProto";
+option java_package = "com.github.gnmi.proto";
+
+
+service gNMI {
+  // Capabilities allows the client to retrieve the set of capabilities that
+  // is supported by the target. This allows the target to validate the
+  // service version that is implemented and retrieve the set of models that
+  // the target supports. The models can then be specified in subsequent RPCs
+  // to restrict the set of data that is utilized.
+  // Reference: gNMI Specification Section 3.2
+  rpc Capabilities(CapabilityRequest) returns (CapabilityResponse);
+  // Retrieve a snapshot of data from the target. A Get RPC requests that the
+  // target snapshots a subset of the data tree as specified by the paths
+  // included in the message and serializes this to be returned to the
+  // client using the specified encoding.
+  // Reference: gNMI Specification Section 3.3
+  rpc Get(GetRequest) returns (GetResponse);
+  // Set allows the client to modify the state of data on the target. The
+  // paths to modified along with the new values that the client wishes
+  // to set the value to.
+  // Reference: gNMI Specification Section 3.4
+  rpc Set(SetRequest) returns (SetResponse);
+  // Subscribe allows a client to request the target to send it values
+  // of particular paths within the data tree. These values may be streamed
+  // at a particular cadence (STREAM), sent one off on a long-lived channel
+  // (POLL), or sent as a one-off retrieval (ONCE).
+  // Reference: gNMI Specification Section 3.5
+  rpc Subscribe(stream SubscribeRequest) returns (stream SubscribeResponse);
+}
+// The Extension message contains a single gNMI extension.
+message Extension {
+  oneof ext {
+    RegisteredExtension registered_ext = 1;    // A registered extension.
+    // Well known extensions.
+    MasterArbitration master_arbitration = 2;  // Master arbitration extension.
+    History history = 3;                       // History extension.
+  }
+}
+
+// The RegisteredExtension message defines an extension which is defined outside
+// of this file.
+message RegisteredExtension {
+  ExtensionID id = 1; // The unique ID assigned to this extension.
+  bytes msg = 2;      // The binary-marshalled protobuf extension payload.
+}
+
+// RegisteredExtension is an enumeration acting as a registry for extensions
+// defined by external sources.
+enum ExtensionID {
+  EID_UNSET = 0;
+  // New extensions are to be defined within this enumeration - their definition
+  // MUST link to a reference describing their implementation.
+
+  // An experimental extension that may be used during prototyping of a new
+  // extension.
+  EID_EXPERIMENTAL = 999;
+}
+
+// MasterArbitration is used to select the master among multiple gNMI clients
+// with the same Roles. The client with the largest election_id is honored as
+// the master.
+// The document about gNMI master arbitration can be found at
+// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-master-arbitration.md
+message MasterArbitration {
+  Role role = 1;
+  Uint128 election_id = 2;
+}
+
+// Representation of unsigned 128-bit integer.
+message Uint128 {
+  uint64 high = 1;
+  uint64 low = 2;
+}
+
+// There can be one master for each role. The role is identified by its id.
+message Role {
+  string id = 1;
+  // More fields can be added if needed, for example, to specify what paths the
+  // role can read/write.
+}
+
+// The History extension allows clients to request historical data. Its
+// spec can be found at
+// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-history.md
+message History {
+  oneof request {
+    int64 snapshot_time = 1; // Nanoseconds since the epoch
+    TimeRange range = 2;
+  }
+}
+
+message TimeRange {
+  int64 start = 1; // Nanoseconds since the epoch
+  int64 end = 2;   // Nanoseconds since the epoch
+}
+// Notification is a re-usable message that is used to encode data from the
+// target to the client. A Notification carries two types of changes to the data
+// tree:
+//  - Deleted values (delete) - a set of paths that have been removed from the
+//    data tree.
+//  - Updated values (update) - a set of path-value pairs indicating the path
+//    whose value has changed in the data tree.
+// Reference: gNMI Specification Section 2.1
+message Notification {
+  int64 timestamp = 1;          // Timestamp in nanoseconds since Epoch.
+  Path prefix = 2;              // Prefix used for paths in the message.
+  repeated Update update = 4;   // Data elements that have changed values.
+  repeated Path delete = 5;     // Data elements that have been deleted.
+  // This notification contains a set of paths that are always updated together
+  // referenced by a globally unique prefix.
+  bool atomic = 6;
+  // Reserved field numbers and identifiers.
+  reserved "alias";
+  reserved 3;
+}
+
+// Update is a re-usable message that is used to store a particular Path,
+// Value pair.
+// Reference: gNMI Specification Section 2.1
+message Update {
+  Path path = 1;                      // The path (key) for the update.
+  Value value = 2 [deprecated=true];  // The value (value) for the update.
+  TypedValue val = 3;                 // The explicitly typed update value.
+  uint32 duplicates = 4;              // Number of coalesced duplicates.
+}
+
+// TypedValue is used to encode a value being sent between the client and
+// target (originated by either entity).
+message TypedValue {
+  // One of the fields within the val oneof is populated with the value
+  // of the update. The type of the value being included in the Update
+  // determines which field should be populated. In the case that the
+  // encoding is a particular form of the base protobuf type, a specific
+  // field is used to store the value (e.g., json_val).
+  oneof value {
+    string string_val = 1;            // String value.
+    int64 int_val = 2;                // Integer value.
+    uint64 uint_val = 3;              // Unsigned integer value.
+    bool bool_val = 4;                // Bool value.
+    bytes bytes_val = 5;              // Arbitrary byte sequence value.
+    float float_val = 6 [deprecated=true]; // Deprecated - use double_val.
+    double double_val = 14;           // Floating point value.
+    Decimal64 decimal_val = 7 [deprecated=true]; // Deprecated - use double_val.
+    ScalarArray leaflist_val = 8;     // Mixed type scalar array value.
+    google.protobuf.Any any_val = 9;  // protobuf.Any encoded bytes.
+    bytes json_val = 10;              // JSON-encoded text.
+    bytes json_ietf_val = 11;         // JSON-encoded text per RFC7951.
+    string ascii_val = 12;            // Arbitrary ASCII text.
+    // Protobuf binary encoded bytes. The message type is not included.
+    // See the specification at
+    // github.com/openconfig/reference/blob/master/rpc/gnmi/protobuf-vals.md
+    // for a complete specification. [Experimental]
+    bytes proto_bytes = 13;
+  }
+}
+
+// Path encodes a data tree path as a series of repeated strings, with
+// each element of the path representing a data tree node name and the
+// associated attributes.
+// Reference: gNMI Specification Section 2.2.2.
+message Path {
+  // Elements of the path are no longer encoded as a string, but rather within
+  // the elem field as a PathElem message.
+  repeated string element = 1 [deprecated=true];
+  string origin = 2;                              // Label to disambiguate path.
+  repeated PathElem elem = 3;                     // Elements of the path.
+  string target = 4;                              // The name of the target
+                                                  // (Sec. 2.2.2.1)
+}
+
+// PathElem encodes an element of a gNMI path, along with any attributes (keys)
+// that may be associated with it.
+// Reference: gNMI Specification Section 2.2.2.
+message PathElem {
+  string name = 1;                    // The name of the element in the path.
+  map<string, string> key = 2;        // Map of key (attribute) name to value.
+}
+
+// Value encodes a data tree node's value - along with the way in which
+// the value is encoded. This message is deprecated by gNMI 0.3.0.
+// Reference: gNMI Specification Section 2.2.3.
+message Value {
+  option deprecated = true;
+  bytes value = 1;      // Value of the variable being transmitted.
+  Encoding type = 2;    // Encoding used for the value field.
+}
+
+// Encoding defines the value encoding formats that are supported by the gNMI
+// protocol. These encodings are used by both the client (when sending Set
+// messages to modify the state of the target) and the target when serializing
+// data to be returned to the client (in both Subscribe and Get RPCs).
+// Reference: gNMI Specification Section 2.3
+enum Encoding {
+  JSON = 0;           // JSON encoded text.
+  BYTES = 1;          // Arbitrarily encoded bytes.
+  PROTO = 2;          // Encoded according to scalar values of TypedValue.
+  ASCII = 3;          // ASCII text of an out-of-band agreed format.
+  JSON_IETF = 4;      // JSON encoded text as per RFC7951.
+}
+
+// Error message previously utilised to return errors to the client. Deprecated
+// in favour of using the google.golang.org/genproto/googleapis/rpc/status
+// message in the RPC response.
+// Reference: gNMI Specification Section 2.5
+message Error {
+  option deprecated = true;
+  uint32 code = 1;                // Canonical gRPC error code.
+  string message = 2;             // Human readable error.
+  google.protobuf.Any data = 3;   // Optional additional information.
+}
+
+// Decimal64 is used to encode a fixed precision decimal number. The value
+// is expressed as a set of digits with the precision specifying the
+// number of digits following the decimal point in the digit set.
+// This message is deprecated in favor of encoding all floating point types
+// as double precision.
+message Decimal64 {
+  option deprecated = true;
+  int64 digits = 1;         // Set of digits.
+  uint32 precision = 2;     // Number of digits following the decimal point.
+}
+
+// ScalarArray is used to encode a mixed-type array of values.
+message ScalarArray {
+  // The set of elements within the array. Each TypedValue message should
+  // specify only elements that have a field identifier of 1-7 (i.e., the
+  // values are scalar values).
+  repeated TypedValue element = 1;
+}
+
+// SubscribeRequest is the message sent by the client to the target when
+// initiating a subscription to a set of paths within the data tree. The
+// request field must be populated and the initial message must specify a
+// SubscriptionList to initiate a subscription.
+// Reference: gNMI Specification Section 3.5.1.1
+message SubscribeRequest {
+  oneof request {
+    SubscriptionList subscribe = 1; // Specify the paths within a subscription.
+    Poll poll = 3;                  // Trigger a polled update.
+  }
+  // Extension messages associated with the SubscribeRequest. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 5;
+  // Reserved field numbers and identifiers.
+  reserved 4;
+  reserved "aliases";
+}
+
+// Poll is sent within a SubscribeRequest to trigger the device to
+// send telemetry updates for the paths that are associated with the
+// subscription.
+// Reference: gNMI Specification Section Section 3.5.1.4
+message Poll {
+}
+
+// SubscribeResponse is the message used by the target within a Subscribe RPC.
+// The target includes a Notification message which is used to transmit values
+// of the path(s) that are associated with the subscription. The same message
+// is to indicate that the target has sent all data values once (is
+// synchronized).
+// Reference: gNMI Specification Section 3.5.1.4
+message SubscribeResponse {
+  oneof response {
+    Notification update = 1;          // Changed or sampled value for a path.
+    // Indicate target has sent all values associated with the subscription
+    // at least once.
+    bool sync_response = 3;
+    // Deprecated in favour of google.golang.org/genproto/googleapis/rpc/status
+    Error error = 4 [deprecated=true];
+  }
+  // Extension messages associated with the SubscribeResponse. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 5;
+}
+
+// SubscriptionList is used within a Subscribe message to specify the list of
+// paths that the client wishes to subscribe to. The message consists of a
+// list of (possibly prefixed) paths, and options that relate to the
+// subscription.
+// Reference: gNMI Specification Section 3.5.1.2
+message SubscriptionList {
+  Path prefix = 1;                          // Prefix used for paths.
+  repeated Subscription subscription = 2;   // Set of subscriptions to create.
+  QOSMarking qos = 4;                       // DSCP marking to be used.
+  // Mode of the subscription.
+  enum Mode {
+    STREAM = 0; // Values streamed by the target (Sec. 3.5.1.5.2).
+    ONCE = 1;   // Values sent once-off by the target (Sec. 3.5.1.5.1).
+    POLL = 2;   // Values sent in response to a poll request (Sec. 3.5.1.5.3).
+  }
+  Mode mode = 5;
+  // Whether elements of the schema that are marked as eligible for aggregation
+  // should be aggregated or not.
+  bool allow_aggregation = 6;
+  // The set of schemas that define the elements of the data tree that should
+  // be sent by the target.
+  repeated ModelData use_models = 7;
+  // The encoding that the target should use within the Notifications generated
+  // corresponding to the SubscriptionList.
+  Encoding encoding = 8;
+  // An optional field to specify that only updates to current state should be
+  // sent to a client. If set, the initial state is not sent to the client but
+  // rather only the sync message followed by any subsequent updates to the
+  // current state. For ONCE and POLL modes, this causes the server to send only
+  // the sync message (Sec. 3.5.2.3).
+  bool updates_only = 9;
+  // Reserved field numbers and identifiers.
+  reserved 3;
+  reserved "use_aliases";
+}
+
+// Subscription is a single request within a SubscriptionList. The path
+// specified is interpreted (along with the prefix) as the elements of the data
+// tree that the client is subscribing to. The mode determines how the target
+// should trigger updates to be sent.
+// Reference: gNMI Specification Section 3.5.1.3
+message Subscription {
+  Path path = 1;                    // The data tree path.
+  SubscriptionMode mode = 2;        // Subscription mode to be used.
+  uint64 sample_interval = 3;       // ns between samples in SAMPLE mode.
+  // Indicates whether values that have not changed should be sent in a SAMPLE
+  // subscription.
+  bool suppress_redundant = 4;
+  // Specifies the maximum allowable silent period in nanoseconds when
+  // suppress_redundant is in use. The target should send a value at least once
+  // in the period specified.
+  uint64 heartbeat_interval = 5;
+}
+
+// SubscriptionMode is the mode of the subscription, specifying how the
+// target must return values in a subscription.
+// Reference: gNMI Specification Section 3.5.1.3
+enum SubscriptionMode {
+  TARGET_DEFINED = 0;  // The target selects the relevant mode for each element.
+  ON_CHANGE      = 1;  // The target sends an update on element value change.
+  SAMPLE         = 2;  // The target samples values according to the interval.
+}
+
+// QOSMarking specifies the DSCP value to be set on transmitted telemetry
+// updates from the target.
+// Reference: gNMI Specification Section 3.5.1.2
+message QOSMarking {
+  uint32 marking = 1;
+}
+
+// SetRequest is sent from a client to the target to update values in the data
+// tree. Paths are either deleted by the client, or modified by means of being
+// updated, or replaced. Where a replace is used, unspecified values are
+// considered to be replaced, whereas when update is used the changes are
+// considered to be incremental. The set of changes that are specified within
+// a single SetRequest are considered to be a transaction.
+// Reference: gNMI Specification Section 3.4.1
+message SetRequest {
+  Path prefix = 1;                // Prefix used for paths in the message.
+  repeated Path delete = 2;       // Paths to be deleted from the data tree.
+  repeated Update replace = 3;    // Updates specifying elements to be replaced.
+  repeated Update update = 4;     // Updates specifying elements to updated.
+  // Extension messages associated with the SetRequest. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 5;
+}
+
+// SetResponse is the response to a SetRequest, sent from the target to the
+// client. It reports the result of the modifications to the data tree that were
+// specified by the client. Errors for this RPC should be reported using the
+// https://github.com/googleapis/googleapis/blob/master/google/rpc/status.proto
+// message in the RPC return. The gnmi.Error message can be used to add additional
+// details where required.
+// Reference: gNMI Specification Section 3.4.2
+message SetResponse {
+  Path prefix = 1;                      // Prefix used for paths.
+  // A set of responses specifying the result of the operations specified in
+  // the SetRequest.
+  repeated UpdateResult response = 2;
+  Error message = 3 [deprecated=true]; // The overall status of the transaction.
+  int64 timestamp = 4;                 // Timestamp of transaction (ns since epoch).
+  // Extension messages associated with the SetResponse. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 5;
+}
+
+// UpdateResult is used within the SetResponse message to communicate the
+// result of an operation specified within a SetRequest message.
+// Reference: gNMI Specification Section 3.4.2
+message UpdateResult {
+  // The operation that was associated with the Path specified.
+  enum Operation {
+    INVALID = 0;
+    DELETE = 1;           // The result relates to a delete of Path.
+    REPLACE = 2;          // The result relates to a replace of Path.
+    UPDATE = 3;           // The result relates to an update of Path.
+  }
+  // Deprecated timestamp for the UpdateResult, this field has been
+  // replaced by the timestamp within the SetResponse message, since
+  // all mutations effected by a set should be applied as a single
+  // transaction.
+  int64 timestamp = 1 [deprecated=true];
+  Path path = 2;                            // Path associated with the update.
+  Error message = 3 [deprecated=true];      // Status of the update operation.
+  Operation op = 4;                         // Update operation type.
+}
+
+// GetRequest is sent when a client initiates a Get RPC. It is used to specify
+// the set of data elements for which the target should return a snapshot of
+// data. The use_models field specifies the set of schema modules that are to
+// be used by the target - where use_models is not specified then the target
+// must use all schema models that it has.
+// Reference: gNMI Specification Section 3.3.1
+message GetRequest {
+  Path prefix = 1;                      // Prefix used for paths.
+  repeated Path path = 2;               // Paths requested by the client.
+  // Type of elements within the data tree.
+  enum DataType {
+    ALL = 0;                            // All data elements.
+    CONFIG = 1;                         // Config (rw) only elements.
+    STATE = 2;                          // State (ro) only elements.
+    // Data elements marked in the schema as operational. This refers to data
+    // elements whose value relates to the state of processes or interactions
+    // running on the device.
+    OPERATIONAL = 3;
+  }
+  DataType type = 3;                    // The type of data being requested.
+  Encoding encoding = 5;                // Encoding to be used.
+  repeated ModelData use_models = 6;    // The schema models to be used.
+  // Extension messages associated with the GetRequest. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 7;
+}
+
+// GetResponse is used by the target to respond to a GetRequest from a client.
+// The set of Notifications corresponds to the data values that are requested
+// by the client in the GetRequest.
+// Reference: gNMI Specification Section 3.3.2
+message GetResponse {
+  repeated Notification notification = 1;   // Data values.
+  Error error = 2 [deprecated=true];        // Errors that occurred in the Get.
+  // Extension messages associated with the GetResponse. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 3;
+}
+
+// CapabilityRequest is sent by the client in the Capabilities RPC to request
+// that the target reports its capabilities.
+// Reference: gNMI Specification Section 3.2.1
+message CapabilityRequest {
+  // Extension messages associated with the CapabilityRequest. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 1;
+}
+
+// CapabilityResponse is used by the target to report its capabilities to the
+// client within the Capabilities RPC.
+// Reference: gNMI Specification Section 3.2.2
+message CapabilityResponse {
+  repeated ModelData supported_models = 1;    // Supported schema models.
+  repeated Encoding supported_encodings = 2;  // Supported encodings.
+  string gNMI_version = 3;                    // Supported gNMI version.
+  // Extension messages associated with the CapabilityResponse. See the
+  // gNMI extension specification for further definition.
+  repeated Extension extension = 4;
+}
+
+// ModelData is used to describe a set of schema modules. It can be used in a
+// CapabilityResponse where a target reports the set of modules that it
+// supports, and within the SubscribeRequest and GetRequest messages to specify
+// the set of models from which data tree elements should be reported.
+// Reference: gNMI Specification Section 3.2.3
+message ModelData {
+  string name = 1;            // Name of the model.
+  string organization = 2;    // Organization publishing the model.
+  string version = 3;         // Semantic version of the model.
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/gnmi_ext.proto b/src/device/service/drivers/openconfig/gnmi_ext.proto
new file mode 100644
index 0000000000000000000000000000000000000000..9960f12afa9d19a45b3d30fd127cb27586f02607
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi_ext.proto
@@ -0,0 +1,76 @@
+syntax = "proto3";
+
+// Package gnmi_ext defines a set of extensions messages which can be optionally
+// included with the request and response messages of gNMI RPCs. A set of
+// well-known extensions are defined within this file, along with a registry for
+// extensions defined outside of this package.
+package gnmi_ext;
+
+option go_package = "github.com/openconfig/gnmi/proto/gnmi_ext";
+
+// The Extension message contains a single gNMI extension.
+message Extension {
+  oneof ext {
+    RegisteredExtension registered_ext = 1;    // A registered extension.
+    // Well known extensions.
+    MasterArbitration master_arbitration = 2;  // Master arbitration extension.
+    History history = 3;                       // History extension.
+  }
+}
+
+// The RegisteredExtension message defines an extension which is defined outside
+// of this file.
+message RegisteredExtension {
+  ExtensionID id = 1; // The unique ID assigned to this extension.
+  bytes msg = 2;      // The binary-marshalled protobuf extension payload.
+}
+
+// RegisteredExtension is an enumeration acting as a registry for extensions
+// defined by external sources.
+enum ExtensionID {
+  EID_UNSET = 0;
+  // New extensions are to be defined within this enumeration - their definition
+  // MUST link to a reference describing their implementation.
+
+  // An experimental extension that may be used during prototyping of a new
+  // extension.
+  EID_EXPERIMENTAL = 999;
+}
+
+// MasterArbitration is used to select the master among multiple gNMI clients
+// with the same Roles. The client with the largest election_id is honored as
+// the master.
+// The document about gNMI master arbitration can be found at
+// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-master-arbitration.md
+message MasterArbitration {
+  Role role = 1;
+  Uint128 election_id = 2;
+}
+
+// Representation of unsigned 128-bit integer.
+message Uint128 {
+  uint64 high = 1;
+  uint64 low = 2;
+}
+
+// There can be one master for each role. The role is identified by its id.
+message Role {
+  string id = 1;
+  // More fields can be added if needed, for example, to specify what paths the
+  // role can read/write.
+}
+
+// The History extension allows clients to request historical data. Its
+// spec can be found at
+// https://github.com/openconfig/reference/blob/master/rpc/gnmi/gnmi-history.md
+message History {
+  oneof request {
+    int64 snapshot_time = 1; // Nanoseconds since the epoch
+    TimeRange range = 2;
+  }
+}
+
+message TimeRange {
+  int64 start = 1; // Nanoseconds since the epoch
+  int64 end = 2;   // Nanoseconds since the epoch
+}
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/gnmi_pb2.py b/src/device/service/drivers/openconfig/gnmi_pb2.py
new file mode 100644
index 0000000000000000000000000000000000000000..af67f9a8ca1d4e01d1a95a0d86adbabe6d8e83ea
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi_pb2.py
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: gnmi.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import builder as _builder
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import descriptor_pool as _descriptor_pool
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\ngnmi.proto\x12\x04gnmi\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\"\xa0\x01\n\tExtension\x12\x33\n\x0eregistered_ext\x18\x01 \x01(\x0b\x32\x19.gnmi.RegisteredExtensionH\x00\x12\x35\n\x12master_arbitration\x18\x02 \x01(\x0b\x32\x17.gnmi.MasterArbitrationH\x00\x12 \n\x07history\x18\x03 \x01(\x0b\x32\r.gnmi.HistoryH\x00\x42\x05\n\x03\x65xt\"A\n\x13RegisteredExtension\x12\x1d\n\x02id\x18\x01 \x01(\x0e\x32\x11.gnmi.ExtensionID\x12\x0b\n\x03msg\x18\x02 \x01(\x0c\"Q\n\x11MasterArbitration\x12\x18\n\x04role\x18\x01 \x01(\x0b\x32\n.gnmi.Role\x12\"\n\x0b\x65lection_id\x18\x02 \x01(\x0b\x32\r.gnmi.Uint128\"$\n\x07Uint128\x12\x0c\n\x04high\x18\x01 \x01(\x04\x12\x0b\n\x03low\x18\x02 \x01(\x04\"\x12\n\x04Role\x12\n\n\x02id\x18\x01 \x01(\t\"O\n\x07History\x12\x17\n\rsnapshot_time\x18\x01 \x01(\x03H\x00\x12 \n\x05range\x18\x02 \x01(\x0b\x32\x0f.gnmi.TimeRangeH\x00\x42\t\n\x07request\"\'\n\tTimeRange\x12\r\n\x05start\x18\x01 \x01(\x03\x12\x0b\n\x03\x65nd\x18\x02 \x01(\x03\"\x94\x01\n\x0cNotification\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12\x1a\n\x06prefix\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1a\n\x06\x64\x65lete\x18\x05 \x03(\x0b\x32\n.gnmi.Path\x12\x0e\n\x06\x61tomic\x18\x06 \x01(\x08J\x04\x08\x03\x10\x04R\x05\x61lias\"u\n\x06Update\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0b.gnmi.ValueB\x02\x18\x01\x12\x1d\n\x03val\x18\x03 \x01(\x0b\x32\x10.gnmi.TypedValue\x12\x12\n\nduplicates\x18\x04 \x01(\r\"\x83\x03\n\nTypedValue\x12\x14\n\nstring_val\x18\x01 \x01(\tH\x00\x12\x11\n\x07int_val\x18\x02 \x01(\x03H\x00\x12\x12\n\x08uint_val\x18\x03 \x01(\x04H\x00\x12\x12\n\x08\x62ool_val\x18\x04 \x01(\x08H\x00\x12\x13\n\tbytes_val\x18\x05 \x01(\x0cH\x00\x12\x17\n\tfloat_val\x18\x06 \x01(\x02\x42\x02\x18\x01H\x00\x12\x14\n\ndouble_val\x18\x0e \x01(\x01H\x00\x12*\n\x0b\x64\x65\x63imal_val\x18\x07 \x01(\x0b\x32\x0f.gnmi.Decimal64B\x02\x18\x01H\x00\x12)\n\x0cleaflist_val\x18\x08 \x01(\x0b\x32\x11.gnmi.ScalarArrayH\x00\x12\'\n\x07\x61ny_val\x18\t \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x12\x12\n\x08json_val\x18\n \x01(\x0cH\x00\x12\x17\n\rjson_ietf_val\x18\x0b \x01(\x0cH\x00\x12\x13\n\tascii_val\x18\x0c \x01(\tH\x00\x12\x15\n\x0bproto_bytes\x18\r \x01(\x0cH\x00\x42\x07\n\x05value\"Y\n\x04Path\x12\x13\n\x07\x65lement\x18\x01 \x03(\tB\x02\x18\x01\x12\x0e\n\x06origin\x18\x02 \x01(\t\x12\x1c\n\x04\x65lem\x18\x03 \x03(\x0b\x32\x0e.gnmi.PathElem\x12\x0e\n\x06target\x18\x04 \x01(\t\"j\n\x08PathElem\x12\x0c\n\x04name\x18\x01 \x01(\t\x12$\n\x03key\x18\x02 \x03(\x0b\x32\x17.gnmi.PathElem.KeyEntry\x1a*\n\x08KeyEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"8\n\x05Value\x12\r\n\x05value\x18\x01 \x01(\x0c\x12\x1c\n\x04type\x18\x02 \x01(\x0e\x32\x0e.gnmi.Encoding:\x02\x18\x01\"N\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\"\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any:\x02\x18\x01\"2\n\tDecimal64\x12\x0e\n\x06\x64igits\x18\x01 \x01(\x03\x12\x11\n\tprecision\x18\x02 \x01(\r:\x02\x18\x01\"0\n\x0bScalarArray\x12!\n\x07\x65lement\x18\x01 \x03(\x0b\x32\x10.gnmi.TypedValue\"\x99\x01\n\x10SubscribeRequest\x12+\n\tsubscribe\x18\x01 \x01(\x0b\x32\x16.gnmi.SubscriptionListH\x00\x12\x1a\n\x04poll\x18\x03 \x01(\x0b\x32\n.gnmi.PollH\x00\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.ExtensionB\t\n\x07requestJ\x04\x08\x04\x10\x05R\x07\x61liases\"\x06\n\x04Poll\"\xa4\x01\n\x11SubscribeResponse\x12$\n\x06update\x18\x01 \x01(\x0b\x32\x12.gnmi.NotificationH\x00\x12\x17\n\rsync_response\x18\x03 \x01(\x08H\x00\x12 \n\x05\x65rror\x18\x04 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01H\x00\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.ExtensionB\n\n\x08response\"\xd5\x02\n\x10SubscriptionList\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12(\n\x0csubscription\x18\x02 \x03(\x0b\x32\x12.gnmi.Subscription\x12\x1d\n\x03qos\x18\x04 \x01(\x0b\x32\x10.gnmi.QOSMarking\x12)\n\x04mode\x18\x05 \x01(\x0e\x32\x1b.gnmi.SubscriptionList.Mode\x12\x19\n\x11\x61llow_aggregation\x18\x06 \x01(\x08\x12#\n\nuse_models\x18\x07 \x03(\x0b\x32\x0f.gnmi.ModelData\x12 \n\x08\x65ncoding\x18\x08 \x01(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cupdates_only\x18\t \x01(\x08\"&\n\x04Mode\x12\n\n\x06STREAM\x10\x00\x12\x08\n\x04ONCE\x10\x01\x12\x08\n\x04POLL\x10\x02J\x04\x08\x03\x10\x04R\x0buse_aliases\"\x9f\x01\n\x0cSubscription\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x04mode\x18\x02 \x01(\x0e\x32\x16.gnmi.SubscriptionMode\x12\x17\n\x0fsample_interval\x18\x03 \x01(\x04\x12\x1a\n\x12suppress_redundant\x18\x04 \x01(\x08\x12\x1a\n\x12heartbeat_interval\x18\x05 \x01(\x04\"\x1d\n\nQOSMarking\x12\x0f\n\x07marking\x18\x01 \x01(\r\"\xa5\x01\n\nSetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1a\n\x06\x64\x65lete\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\x1d\n\x07replace\x18\x03 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.Extension\"\xa8\x01\n\x0bSetResponse\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x08response\x18\x02 \x03(\x0b\x32\x12.gnmi.UpdateResult\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12\x11\n\ttimestamp\x18\x04 \x01(\x03\x12\"\n\textension\x18\x05 \x03(\x0b\x32\x0f.gnmi.Extension\"\xca\x01\n\x0cUpdateResult\x12\x15\n\ttimestamp\x18\x01 \x01(\x03\x42\x02\x18\x01\x12\x18\n\x04path\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12(\n\x02op\x18\x04 \x01(\x0e\x32\x1c.gnmi.UpdateResult.Operation\"=\n\tOperation\x12\x0b\n\x07INVALID\x10\x00\x12\n\n\x06\x44\x45LETE\x10\x01\x12\x0b\n\x07REPLACE\x10\x02\x12\n\n\x06UPDATE\x10\x03\"\x93\x02\n\nGetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x18\n\x04path\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\'\n\x04type\x18\x03 \x01(\x0e\x32\x19.gnmi.GetRequest.DataType\x12 \n\x08\x65ncoding\x18\x05 \x01(\x0e\x32\x0e.gnmi.Encoding\x12#\n\nuse_models\x18\x06 \x03(\x0b\x32\x0f.gnmi.ModelData\x12\"\n\textension\x18\x07 \x03(\x0b\x32\x0f.gnmi.Extension\";\n\x08\x44\x61taType\x12\x07\n\x03\x41LL\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\t\n\x05STATE\x10\x02\x12\x0f\n\x0bOPERATIONAL\x10\x03\"{\n\x0bGetResponse\x12(\n\x0cnotification\x18\x01 \x03(\x0b\x32\x12.gnmi.Notification\x12\x1e\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12\"\n\textension\x18\x03 \x03(\x0b\x32\x0f.gnmi.Extension\"7\n\x11\x43\x61pabilityRequest\x12\"\n\textension\x18\x01 \x03(\x0b\x32\x0f.gnmi.Extension\"\xa6\x01\n\x12\x43\x61pabilityResponse\x12)\n\x10supported_models\x18\x01 \x03(\x0b\x32\x0f.gnmi.ModelData\x12+\n\x13supported_encodings\x18\x02 \x03(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cgNMI_version\x18\x03 \x01(\t\x12\"\n\textension\x18\x04 \x03(\x0b\x32\x0f.gnmi.Extension\"@\n\tModelData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x0corganization\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t*3\n\x0b\x45xtensionID\x12\r\n\tEID_UNSET\x10\x00\x12\x15\n\x10\x45ID_EXPERIMENTAL\x10\xe7\x07*D\n\x08\x45ncoding\x12\x08\n\x04JSON\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\t\n\x05\x41SCII\x10\x03\x12\r\n\tJSON_IETF\x10\x04*A\n\x10SubscriptionMode\x12\x12\n\x0eTARGET_DEFINED\x10\x00\x12\r\n\tON_CHANGE\x10\x01\x12\n\n\x06SAMPLE\x10\x02\x32\xe3\x01\n\x04gNMI\x12\x41\n\x0c\x43\x61pabilities\x12\x17.gnmi.CapabilityRequest\x1a\x18.gnmi.CapabilityResponse\x12*\n\x03Get\x12\x10.gnmi.GetRequest\x1a\x11.gnmi.GetResponse\x12*\n\x03Set\x12\x10.gnmi.SetRequest\x1a\x11.gnmi.SetResponse\x12@\n\tSubscribe\x12\x16.gnmi.SubscribeRequest\x1a\x17.gnmi.SubscribeResponse(\x01\x30\x01:3\n\x0cgnmi_service\x12\x1c.google.protobuf.FileOptions\x18\xe9\x07 \x01(\tBS\n\x15\x63om.github.gnmi.protoB\tGnmiProtoP\x01Z%github.com/openconfig/gnmi/proto/gnmi\xca>\x05\x30.8.0b\x06proto3')
+
+_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
+_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'gnmi_pb2', globals())
+if _descriptor._USE_C_DESCRIPTORS == False:
+  google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(gnmi_service)
+
+  DESCRIPTOR._options = None
+  DESCRIPTOR._serialized_options = b'\n\025com.github.gnmi.protoB\tGnmiProtoP\001Z%github.com/openconfig/gnmi/proto/gnmi\312>\0050.8.0'
+  _UPDATE.fields_by_name['value']._options = None
+  _UPDATE.fields_by_name['value']._serialized_options = b'\030\001'
+  _TYPEDVALUE.fields_by_name['float_val']._options = None
+  _TYPEDVALUE.fields_by_name['float_val']._serialized_options = b'\030\001'
+  _TYPEDVALUE.fields_by_name['decimal_val']._options = None
+  _TYPEDVALUE.fields_by_name['decimal_val']._serialized_options = b'\030\001'
+  _PATH.fields_by_name['element']._options = None
+  _PATH.fields_by_name['element']._serialized_options = b'\030\001'
+  _PATHELEM_KEYENTRY._options = None
+  _PATHELEM_KEYENTRY._serialized_options = b'8\001'
+  _VALUE._options = None
+  _VALUE._serialized_options = b'\030\001'
+  _ERROR._options = None
+  _ERROR._serialized_options = b'\030\001'
+  _DECIMAL64._options = None
+  _DECIMAL64._serialized_options = b'\030\001'
+  _SUBSCRIBERESPONSE.fields_by_name['error']._options = None
+  _SUBSCRIBERESPONSE.fields_by_name['error']._serialized_options = b'\030\001'
+  _SETRESPONSE.fields_by_name['message']._options = None
+  _SETRESPONSE.fields_by_name['message']._serialized_options = b'\030\001'
+  _UPDATERESULT.fields_by_name['timestamp']._options = None
+  _UPDATERESULT.fields_by_name['timestamp']._serialized_options = b'\030\001'
+  _UPDATERESULT.fields_by_name['message']._options = None
+  _UPDATERESULT.fields_by_name['message']._serialized_options = b'\030\001'
+  _GETRESPONSE.fields_by_name['error']._options = None
+  _GETRESPONSE.fields_by_name['error']._serialized_options = b'\030\001'
+  _EXTENSIONID._serialized_start=3780
+  _EXTENSIONID._serialized_end=3831
+  _ENCODING._serialized_start=3833
+  _ENCODING._serialized_end=3901
+  _SUBSCRIPTIONMODE._serialized_start=3903
+  _SUBSCRIPTIONMODE._serialized_end=3968
+  _EXTENSION._serialized_start=82
+  _EXTENSION._serialized_end=242
+  _REGISTEREDEXTENSION._serialized_start=244
+  _REGISTEREDEXTENSION._serialized_end=309
+  _MASTERARBITRATION._serialized_start=311
+  _MASTERARBITRATION._serialized_end=392
+  _UINT128._serialized_start=394
+  _UINT128._serialized_end=430
+  _ROLE._serialized_start=432
+  _ROLE._serialized_end=450
+  _HISTORY._serialized_start=452
+  _HISTORY._serialized_end=531
+  _TIMERANGE._serialized_start=533
+  _TIMERANGE._serialized_end=572
+  _NOTIFICATION._serialized_start=575
+  _NOTIFICATION._serialized_end=723
+  _UPDATE._serialized_start=725
+  _UPDATE._serialized_end=842
+  _TYPEDVALUE._serialized_start=845
+  _TYPEDVALUE._serialized_end=1232
+  _PATH._serialized_start=1234
+  _PATH._serialized_end=1323
+  _PATHELEM._serialized_start=1325
+  _PATHELEM._serialized_end=1431
+  _PATHELEM_KEYENTRY._serialized_start=1389
+  _PATHELEM_KEYENTRY._serialized_end=1431
+  _VALUE._serialized_start=1433
+  _VALUE._serialized_end=1489
+  _ERROR._serialized_start=1491
+  _ERROR._serialized_end=1569
+  _DECIMAL64._serialized_start=1571
+  _DECIMAL64._serialized_end=1621
+  _SCALARARRAY._serialized_start=1623
+  _SCALARARRAY._serialized_end=1671
+  _SUBSCRIBEREQUEST._serialized_start=1674
+  _SUBSCRIBEREQUEST._serialized_end=1827
+  _POLL._serialized_start=1829
+  _POLL._serialized_end=1835
+  _SUBSCRIBERESPONSE._serialized_start=1838
+  _SUBSCRIBERESPONSE._serialized_end=2002
+  _SUBSCRIPTIONLIST._serialized_start=2005
+  _SUBSCRIPTIONLIST._serialized_end=2346
+  _SUBSCRIPTIONLIST_MODE._serialized_start=2289
+  _SUBSCRIPTIONLIST_MODE._serialized_end=2327
+  _SUBSCRIPTION._serialized_start=2349
+  _SUBSCRIPTION._serialized_end=2508
+  _QOSMARKING._serialized_start=2510
+  _QOSMARKING._serialized_end=2539
+  _SETREQUEST._serialized_start=2542
+  _SETREQUEST._serialized_end=2707
+  _SETRESPONSE._serialized_start=2710
+  _SETRESPONSE._serialized_end=2878
+  _UPDATERESULT._serialized_start=2881
+  _UPDATERESULT._serialized_end=3083
+  _UPDATERESULT_OPERATION._serialized_start=3022
+  _UPDATERESULT_OPERATION._serialized_end=3083
+  _GETREQUEST._serialized_start=3086
+  _GETREQUEST._serialized_end=3361
+  _GETREQUEST_DATATYPE._serialized_start=3302
+  _GETREQUEST_DATATYPE._serialized_end=3361
+  _GETRESPONSE._serialized_start=3363
+  _GETRESPONSE._serialized_end=3486
+  _CAPABILITYREQUEST._serialized_start=3488
+  _CAPABILITYREQUEST._serialized_end=3543
+  _CAPABILITYRESPONSE._serialized_start=3546
+  _CAPABILITYRESPONSE._serialized_end=3712
+  _MODELDATA._serialized_start=3714
+  _MODELDATA._serialized_end=3778
+  _GNMI._serialized_start=3971
+  _GNMI._serialized_end=4198
+# @@protoc_insertion_point(module_scope)
diff --git a/src/device/service/drivers/openconfig/gnmi_pb2.py.old b/src/device/service/drivers/openconfig/gnmi_pb2.py.old
new file mode 100644
index 0000000000000000000000000000000000000000..313674f8ce5be1586c63df02226570f5082544ba
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi_pb2.py.old
@@ -0,0 +1,2037 @@
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: proto/gnmi/gnmi.proto
+
+import sys
+_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+from google.protobuf import descriptor_pb2
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from google.protobuf import any_pb2 as google_dot_protobuf_dot_any__pb2
+from google.protobuf import descriptor_pb2 as google_dot_protobuf_dot_descriptor__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='proto/gnmi/gnmi.proto',
+  package='gnmi',
+  syntax='proto3',
+  serialized_pb=_b('\n\x15proto/gnmi/gnmi.proto\x12\x04gnmi\x1a\x19google/protobuf/any.proto\x1a google/protobuf/descriptor.proto\"\x86\x01\n\x0cNotification\x12\x11\n\ttimestamp\x18\x01 \x01(\x03\x12\x1a\n\x06prefix\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12\r\n\x05\x61lias\x18\x03 \x01(\t\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1a\n\x06\x64\x65lete\x18\x05 \x03(\x0b\x32\n.gnmi.Path\"u\n\x06Update\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1e\n\x05value\x18\x02 \x01(\x0b\x32\x0b.gnmi.ValueB\x02\x18\x01\x12\x1d\n\x03val\x18\x03 \x01(\x0b\x32\x10.gnmi.TypedValue\x12\x12\n\nduplicates\x18\x04 \x01(\r\"\xce\x02\n\nTypedValue\x12\x14\n\nstring_val\x18\x01 \x01(\tH\x00\x12\x11\n\x07int_val\x18\x02 \x01(\x03H\x00\x12\x12\n\x08uint_val\x18\x03 \x01(\x04H\x00\x12\x12\n\x08\x62ool_val\x18\x04 \x01(\x08H\x00\x12\x13\n\tbytes_val\x18\x05 \x01(\x0cH\x00\x12\x13\n\tfloat_val\x18\x06 \x01(\x02H\x00\x12&\n\x0b\x64\x65\x63imal_val\x18\x07 \x01(\x0b\x32\x0f.gnmi.Decimal64H\x00\x12)\n\x0cleaflist_val\x18\x08 \x01(\x0b\x32\x11.gnmi.ScalarArrayH\x00\x12\'\n\x07\x61ny_val\x18\t \x01(\x0b\x32\x14.google.protobuf.AnyH\x00\x12\x12\n\x08json_val\x18\n \x01(\x0cH\x00\x12\x17\n\rjson_ietf_val\x18\x0b \x01(\x0cH\x00\x12\x13\n\tascii_val\x18\x0c \x01(\tH\x00\x42\x07\n\x05value\"Y\n\x04Path\x12\x13\n\x07\x65lement\x18\x01 \x03(\tB\x02\x18\x01\x12\x0e\n\x06origin\x18\x02 \x01(\t\x12\x1c\n\x04\x65lem\x18\x03 \x03(\x0b\x32\x0e.gnmi.PathElem\x12\x0e\n\x06target\x18\x04 \x01(\t\"j\n\x08PathElem\x12\x0c\n\x04name\x18\x01 \x01(\t\x12$\n\x03key\x18\x02 \x03(\x0b\x32\x17.gnmi.PathElem.KeyEntry\x1a*\n\x08KeyEntry\x12\x0b\n\x03key\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t:\x02\x38\x01\"8\n\x05Value\x12\r\n\x05value\x18\x01 \x01(\x0c\x12\x1c\n\x04type\x18\x02 \x01(\x0e\x32\x0e.gnmi.Encoding:\x02\x18\x01\"N\n\x05\x45rror\x12\x0c\n\x04\x63ode\x18\x01 \x01(\r\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\"\n\x04\x64\x61ta\x18\x03 \x01(\x0b\x32\x14.google.protobuf.Any:\x02\x18\x01\".\n\tDecimal64\x12\x0e\n\x06\x64igits\x18\x01 \x01(\x04\x12\x11\n\tprecision\x18\x02 \x01(\r\"0\n\x0bScalarArray\x12!\n\x07\x65lement\x18\x01 \x03(\x0b\x32\x10.gnmi.TypedValue\"\x8a\x01\n\x10SubscribeRequest\x12+\n\tsubscribe\x18\x01 \x01(\x0b\x32\x16.gnmi.SubscriptionListH\x00\x12\x1a\n\x04poll\x18\x03 \x01(\x0b\x32\n.gnmi.PollH\x00\x12\"\n\x07\x61liases\x18\x04 \x01(\x0b\x32\x0f.gnmi.AliasListH\x00\x42\t\n\x07request\"\x06\n\x04Poll\"\x80\x01\n\x11SubscribeResponse\x12$\n\x06update\x18\x01 \x01(\x0b\x32\x12.gnmi.NotificationH\x00\x12\x17\n\rsync_response\x18\x03 \x01(\x08H\x00\x12 \n\x05\x65rror\x18\x04 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01H\x00\x42\n\n\x08response\"\xd7\x02\n\x10SubscriptionList\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12(\n\x0csubscription\x18\x02 \x03(\x0b\x32\x12.gnmi.Subscription\x12\x13\n\x0buse_aliases\x18\x03 \x01(\x08\x12\x1d\n\x03qos\x18\x04 \x01(\x0b\x32\x10.gnmi.QOSMarking\x12)\n\x04mode\x18\x05 \x01(\x0e\x32\x1b.gnmi.SubscriptionList.Mode\x12\x19\n\x11\x61llow_aggregation\x18\x06 \x01(\x08\x12#\n\nuse_models\x18\x07 \x03(\x0b\x32\x0f.gnmi.ModelData\x12 \n\x08\x65ncoding\x18\x08 \x01(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cupdates_only\x18\t \x01(\x08\"&\n\x04Mode\x12\n\n\x06STREAM\x10\x00\x12\x08\n\x04ONCE\x10\x01\x12\x08\n\x04POLL\x10\x02\"\x9f\x01\n\x0cSubscription\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x04mode\x18\x02 \x01(\x0e\x32\x16.gnmi.SubscriptionMode\x12\x17\n\x0fsample_interval\x18\x03 \x01(\x04\x12\x1a\n\x12suppress_redundant\x18\x04 \x01(\x08\x12\x1a\n\x12heartbeat_interval\x18\x05 \x01(\x04\"\x1d\n\nQOSMarking\x12\x0f\n\x07marking\x18\x01 \x01(\r\"0\n\x05\x41lias\x12\x18\n\x04path\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\r\n\x05\x61lias\x18\x02 \x01(\t\"\'\n\tAliasList\x12\x1a\n\x05\x61lias\x18\x01 \x03(\x0b\x32\x0b.gnmi.Alias\"\x81\x01\n\nSetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x1a\n\x06\x64\x65lete\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\x1d\n\x07replace\x18\x03 \x03(\x0b\x32\x0c.gnmi.Update\x12\x1c\n\x06update\x18\x04 \x03(\x0b\x32\x0c.gnmi.Update\"\x84\x01\n\x0bSetResponse\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12$\n\x08response\x18\x02 \x03(\x0b\x32\x12.gnmi.UpdateResult\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12\x11\n\ttimestamp\x18\x04 \x01(\x03\"\xca\x01\n\x0cUpdateResult\x12\x15\n\ttimestamp\x18\x01 \x01(\x03\x42\x02\x18\x01\x12\x18\n\x04path\x18\x02 \x01(\x0b\x32\n.gnmi.Path\x12 \n\x07message\x18\x03 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\x12(\n\x02op\x18\x04 \x01(\x0e\x32\x1c.gnmi.UpdateResult.Operation\"=\n\tOperation\x12\x0b\n\x07INVALID\x10\x00\x12\n\n\x06\x44\x45LETE\x10\x01\x12\x0b\n\x07REPLACE\x10\x02\x12\n\n\x06UPDATE\x10\x03\"\xef\x01\n\nGetRequest\x12\x1a\n\x06prefix\x18\x01 \x01(\x0b\x32\n.gnmi.Path\x12\x18\n\x04path\x18\x02 \x03(\x0b\x32\n.gnmi.Path\x12\'\n\x04type\x18\x03 \x01(\x0e\x32\x19.gnmi.GetRequest.DataType\x12 \n\x08\x65ncoding\x18\x05 \x01(\x0e\x32\x0e.gnmi.Encoding\x12#\n\nuse_models\x18\x06 \x03(\x0b\x32\x0f.gnmi.ModelData\";\n\x08\x44\x61taType\x12\x07\n\x03\x41LL\x10\x00\x12\n\n\x06\x43ONFIG\x10\x01\x12\t\n\x05STATE\x10\x02\x12\x0f\n\x0bOPERATIONAL\x10\x03\"W\n\x0bGetResponse\x12(\n\x0cnotification\x18\x01 \x03(\x0b\x32\x12.gnmi.Notification\x12\x1e\n\x05\x65rror\x18\x02 \x01(\x0b\x32\x0b.gnmi.ErrorB\x02\x18\x01\"\x13\n\x11\x43\x61pabilityRequest\"\x82\x01\n\x12\x43\x61pabilityResponse\x12)\n\x10supported_models\x18\x01 \x03(\x0b\x32\x0f.gnmi.ModelData\x12+\n\x13supported_encodings\x18\x02 \x03(\x0e\x32\x0e.gnmi.Encoding\x12\x14\n\x0cgNMI_version\x18\x03 \x01(\t\"@\n\tModelData\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x14\n\x0corganization\x18\x02 \x01(\t\x12\x0f\n\x07version\x18\x03 \x01(\t*D\n\x08\x45ncoding\x12\x08\n\x04JSON\x10\x00\x12\t\n\x05\x42YTES\x10\x01\x12\t\n\x05PROTO\x10\x02\x12\t\n\x05\x41SCII\x10\x03\x12\r\n\tJSON_IETF\x10\x04*A\n\x10SubscriptionMode\x12\x12\n\x0eTARGET_DEFINED\x10\x00\x12\r\n\tON_CHANGE\x10\x01\x12\n\n\x06SAMPLE\x10\x02\x32\xe3\x01\n\x04gNMI\x12\x41\n\x0c\x43\x61pabilities\x12\x17.gnmi.CapabilityRequest\x1a\x18.gnmi.CapabilityResponse\x12*\n\x03Get\x12\x10.gnmi.GetRequest\x1a\x11.gnmi.GetResponse\x12*\n\x03Set\x12\x10.gnmi.SetRequest\x1a\x11.gnmi.SetResponse\x12@\n\tSubscribe\x12\x16.gnmi.SubscribeRequest\x1a\x17.gnmi.SubscribeResponse(\x01\x30\x01:3\n\x0cgnmi_service\x12\x1c.google.protobuf.FileOptions\x18\xe9\x07 \x01(\tB\x08\xca>\x05\x30.5.0b\x06proto3')
+  ,
+  dependencies=[google_dot_protobuf_dot_any__pb2.DESCRIPTOR,google_dot_protobuf_dot_descriptor__pb2.DESCRIPTOR,])
+
+_ENCODING = _descriptor.EnumDescriptor(
+  name='Encoding',
+  full_name='gnmi.Encoding',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='JSON', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='BYTES', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='PROTO', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ASCII', index=3, number=3,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='JSON_IETF', index=4, number=4,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3053,
+  serialized_end=3121,
+)
+_sym_db.RegisterEnumDescriptor(_ENCODING)
+
+Encoding = enum_type_wrapper.EnumTypeWrapper(_ENCODING)
+_SUBSCRIPTIONMODE = _descriptor.EnumDescriptor(
+  name='SubscriptionMode',
+  full_name='gnmi.SubscriptionMode',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='TARGET_DEFINED', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ON_CHANGE', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='SAMPLE', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=3123,
+  serialized_end=3188,
+)
+_sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONMODE)
+
+SubscriptionMode = enum_type_wrapper.EnumTypeWrapper(_SUBSCRIPTIONMODE)
+JSON = 0
+BYTES = 1
+PROTO = 2
+ASCII = 3
+JSON_IETF = 4
+TARGET_DEFINED = 0
+ON_CHANGE = 1
+SAMPLE = 2
+
+GNMI_SERVICE_FIELD_NUMBER = 1001
+gnmi_service = _descriptor.FieldDescriptor(
+  name='gnmi_service', full_name='gnmi.gnmi_service', index=0,
+  number=1001, type=9, cpp_type=9, label=1,
+  has_default_value=False, default_value=_b("").decode('utf-8'),
+  message_type=None, enum_type=None, containing_type=None,
+  is_extension=True, extension_scope=None,
+  options=None)
+
+_SUBSCRIPTIONLIST_MODE = _descriptor.EnumDescriptor(
+  name='Mode',
+  full_name='gnmi.SubscriptionList.Mode',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='STREAM', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='ONCE', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='POLL', index=2, number=2,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=1706,
+  serialized_end=1744,
+)
+_sym_db.RegisterEnumDescriptor(_SUBSCRIPTIONLIST_MODE)
+
+_UPDATERESULT_OPERATION = _descriptor.EnumDescriptor(
+  name='Operation',
+  full_name='gnmi.UpdateResult.Operation',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='INVALID', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='DELETE', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='REPLACE', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='UPDATE', index=3, number=3,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=2439,
+  serialized_end=2500,
+)
+_sym_db.RegisterEnumDescriptor(_UPDATERESULT_OPERATION)
+
+_GETREQUEST_DATATYPE = _descriptor.EnumDescriptor(
+  name='DataType',
+  full_name='gnmi.GetRequest.DataType',
+  filename=None,
+  file=DESCRIPTOR,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='ALL', index=0, number=0,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIG', index=1, number=1,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='STATE', index=2, number=2,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='OPERATIONAL', index=3, number=3,
+      options=None,
+      type=None),
+  ],
+  containing_type=None,
+  options=None,
+  serialized_start=2683,
+  serialized_end=2742,
+)
+_sym_db.RegisterEnumDescriptor(_GETREQUEST_DATATYPE)
+
+
+_NOTIFICATION = _descriptor.Descriptor(
+  name='Notification',
+  full_name='gnmi.Notification',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='gnmi.Notification.timestamp', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='prefix', full_name='gnmi.Notification.prefix', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='alias', full_name='gnmi.Notification.alias', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='update', full_name='gnmi.Notification.update', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='delete', full_name='gnmi.Notification.delete', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=93,
+  serialized_end=227,
+)
+
+
+_UPDATE = _descriptor.Descriptor(
+  name='Update',
+  full_name='gnmi.Update',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='path', full_name='gnmi.Update.path', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='gnmi.Update.value', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+    _descriptor.FieldDescriptor(
+      name='val', full_name='gnmi.Update.val', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='duplicates', full_name='gnmi.Update.duplicates', index=3,
+      number=4, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=229,
+  serialized_end=346,
+)
+
+
+_TYPEDVALUE = _descriptor.Descriptor(
+  name='TypedValue',
+  full_name='gnmi.TypedValue',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='string_val', full_name='gnmi.TypedValue.string_val', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='int_val', full_name='gnmi.TypedValue.int_val', index=1,
+      number=2, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='uint_val', full_name='gnmi.TypedValue.uint_val', index=2,
+      number=3, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bool_val', full_name='gnmi.TypedValue.bool_val', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='bytes_val', full_name='gnmi.TypedValue.bytes_val', index=4,
+      number=5, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='float_val', full_name='gnmi.TypedValue.float_val', index=5,
+      number=6, type=2, cpp_type=6, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='decimal_val', full_name='gnmi.TypedValue.decimal_val', index=6,
+      number=7, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='leaflist_val', full_name='gnmi.TypedValue.leaflist_val', index=7,
+      number=8, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='any_val', full_name='gnmi.TypedValue.any_val', index=8,
+      number=9, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='json_val', full_name='gnmi.TypedValue.json_val', index=9,
+      number=10, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='json_ietf_val', full_name='gnmi.TypedValue.json_ietf_val', index=10,
+      number=11, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='ascii_val', full_name='gnmi.TypedValue.ascii_val', index=11,
+      number=12, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='value', full_name='gnmi.TypedValue.value',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=349,
+  serialized_end=683,
+)
+
+
+_PATH = _descriptor.Descriptor(
+  name='Path',
+  full_name='gnmi.Path',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='element', full_name='gnmi.Path.element', index=0,
+      number=1, type=9, cpp_type=9, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+    _descriptor.FieldDescriptor(
+      name='origin', full_name='gnmi.Path.origin', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='elem', full_name='gnmi.Path.elem', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='target', full_name='gnmi.Path.target', index=3,
+      number=4, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=685,
+  serialized_end=774,
+)
+
+
+_PATHELEM_KEYENTRY = _descriptor.Descriptor(
+  name='KeyEntry',
+  full_name='gnmi.PathElem.KeyEntry',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='key', full_name='gnmi.PathElem.KeyEntry.key', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='value', full_name='gnmi.PathElem.KeyEntry.value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=840,
+  serialized_end=882,
+)
+
+_PATHELEM = _descriptor.Descriptor(
+  name='PathElem',
+  full_name='gnmi.PathElem',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='gnmi.PathElem.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='key', full_name='gnmi.PathElem.key', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[_PATHELEM_KEYENTRY, ],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=776,
+  serialized_end=882,
+)
+
+
+_VALUE = _descriptor.Descriptor(
+  name='Value',
+  full_name='gnmi.Value',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='value', full_name='gnmi.Value.value', index=0,
+      number=1, type=12, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b(""),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='gnmi.Value.type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\030\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=884,
+  serialized_end=940,
+)
+
+
+_ERROR = _descriptor.Descriptor(
+  name='Error',
+  full_name='gnmi.Error',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='code', full_name='gnmi.Error.code', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='gnmi.Error.message', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='data', full_name='gnmi.Error.data', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=_descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\030\001')),
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=942,
+  serialized_end=1020,
+)
+
+
+_DECIMAL64 = _descriptor.Descriptor(
+  name='Decimal64',
+  full_name='gnmi.Decimal64',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='digits', full_name='gnmi.Decimal64.digits', index=0,
+      number=1, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='precision', full_name='gnmi.Decimal64.precision', index=1,
+      number=2, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1022,
+  serialized_end=1068,
+)
+
+
+_SCALARARRAY = _descriptor.Descriptor(
+  name='ScalarArray',
+  full_name='gnmi.ScalarArray',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='element', full_name='gnmi.ScalarArray.element', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1070,
+  serialized_end=1118,
+)
+
+
+_SUBSCRIBEREQUEST = _descriptor.Descriptor(
+  name='SubscribeRequest',
+  full_name='gnmi.SubscribeRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='subscribe', full_name='gnmi.SubscribeRequest.subscribe', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='poll', full_name='gnmi.SubscribeRequest.poll', index=1,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='aliases', full_name='gnmi.SubscribeRequest.aliases', index=2,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='request', full_name='gnmi.SubscribeRequest.request',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=1121,
+  serialized_end=1259,
+)
+
+
+_POLL = _descriptor.Descriptor(
+  name='Poll',
+  full_name='gnmi.Poll',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1261,
+  serialized_end=1267,
+)
+
+
+_SUBSCRIBERESPONSE = _descriptor.Descriptor(
+  name='SubscribeResponse',
+  full_name='gnmi.SubscribeResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='update', full_name='gnmi.SubscribeResponse.update', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='sync_response', full_name='gnmi.SubscribeResponse.sync_response', index=1,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='error', full_name='gnmi.SubscribeResponse.error', index=2,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+    _descriptor.OneofDescriptor(
+      name='response', full_name='gnmi.SubscribeResponse.response',
+      index=0, containing_type=None, fields=[]),
+  ],
+  serialized_start=1270,
+  serialized_end=1398,
+)
+
+
+_SUBSCRIPTIONLIST = _descriptor.Descriptor(
+  name='SubscriptionList',
+  full_name='gnmi.SubscriptionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='prefix', full_name='gnmi.SubscriptionList.prefix', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='subscription', full_name='gnmi.SubscriptionList.subscription', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='use_aliases', full_name='gnmi.SubscriptionList.use_aliases', index=2,
+      number=3, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='qos', full_name='gnmi.SubscriptionList.qos', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='mode', full_name='gnmi.SubscriptionList.mode', index=4,
+      number=5, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='allow_aggregation', full_name='gnmi.SubscriptionList.allow_aggregation', index=5,
+      number=6, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='use_models', full_name='gnmi.SubscriptionList.use_models', index=6,
+      number=7, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='encoding', full_name='gnmi.SubscriptionList.encoding', index=7,
+      number=8, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='updates_only', full_name='gnmi.SubscriptionList.updates_only', index=8,
+      number=9, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _SUBSCRIPTIONLIST_MODE,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1401,
+  serialized_end=1744,
+)
+
+
+_SUBSCRIPTION = _descriptor.Descriptor(
+  name='Subscription',
+  full_name='gnmi.Subscription',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='path', full_name='gnmi.Subscription.path', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='mode', full_name='gnmi.Subscription.mode', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='sample_interval', full_name='gnmi.Subscription.sample_interval', index=2,
+      number=3, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='suppress_redundant', full_name='gnmi.Subscription.suppress_redundant', index=3,
+      number=4, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='heartbeat_interval', full_name='gnmi.Subscription.heartbeat_interval', index=4,
+      number=5, type=4, cpp_type=4, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1747,
+  serialized_end=1906,
+)
+
+
+_QOSMARKING = _descriptor.Descriptor(
+  name='QOSMarking',
+  full_name='gnmi.QOSMarking',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='marking', full_name='gnmi.QOSMarking.marking', index=0,
+      number=1, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1908,
+  serialized_end=1937,
+)
+
+
+_ALIAS = _descriptor.Descriptor(
+  name='Alias',
+  full_name='gnmi.Alias',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='path', full_name='gnmi.Alias.path', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='alias', full_name='gnmi.Alias.alias', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1939,
+  serialized_end=1987,
+)
+
+
+_ALIASLIST = _descriptor.Descriptor(
+  name='AliasList',
+  full_name='gnmi.AliasList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='alias', full_name='gnmi.AliasList.alias', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1989,
+  serialized_end=2028,
+)
+
+
+_SETREQUEST = _descriptor.Descriptor(
+  name='SetRequest',
+  full_name='gnmi.SetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='prefix', full_name='gnmi.SetRequest.prefix', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='delete', full_name='gnmi.SetRequest.delete', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='replace', full_name='gnmi.SetRequest.replace', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='update', full_name='gnmi.SetRequest.update', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2031,
+  serialized_end=2160,
+)
+
+
+_SETRESPONSE = _descriptor.Descriptor(
+  name='SetResponse',
+  full_name='gnmi.SetResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='prefix', full_name='gnmi.SetResponse.prefix', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='response', full_name='gnmi.SetResponse.response', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='gnmi.SetResponse.message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='gnmi.SetResponse.timestamp', index=3,
+      number=4, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2163,
+  serialized_end=2295,
+)
+
+
+_UPDATERESULT = _descriptor.Descriptor(
+  name='UpdateResult',
+  full_name='gnmi.UpdateResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='gnmi.UpdateResult.timestamp', index=0,
+      number=1, type=3, cpp_type=2, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+    _descriptor.FieldDescriptor(
+      name='path', full_name='gnmi.UpdateResult.path', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='message', full_name='gnmi.UpdateResult.message', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+    _descriptor.FieldDescriptor(
+      name='op', full_name='gnmi.UpdateResult.op', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _UPDATERESULT_OPERATION,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2298,
+  serialized_end=2500,
+)
+
+
+_GETREQUEST = _descriptor.Descriptor(
+  name='GetRequest',
+  full_name='gnmi.GetRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='prefix', full_name='gnmi.GetRequest.prefix', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='path', full_name='gnmi.GetRequest.path', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='gnmi.GetRequest.type', index=2,
+      number=3, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='encoding', full_name='gnmi.GetRequest.encoding', index=3,
+      number=5, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='use_models', full_name='gnmi.GetRequest.use_models', index=4,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+    _GETREQUEST_DATATYPE,
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2503,
+  serialized_end=2742,
+)
+
+
+_GETRESPONSE = _descriptor.Descriptor(
+  name='GetResponse',
+  full_name='gnmi.GetResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='notification', full_name='gnmi.GetResponse.notification', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='error', full_name='gnmi.GetResponse.error', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=_descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2744,
+  serialized_end=2831,
+)
+
+
+_CAPABILITYREQUEST = _descriptor.Descriptor(
+  name='CapabilityRequest',
+  full_name='gnmi.CapabilityRequest',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2833,
+  serialized_end=2852,
+)
+
+
+_CAPABILITYRESPONSE = _descriptor.Descriptor(
+  name='CapabilityResponse',
+  full_name='gnmi.CapabilityResponse',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='supported_models', full_name='gnmi.CapabilityResponse.supported_models', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='supported_encodings', full_name='gnmi.CapabilityResponse.supported_encodings', index=1,
+      number=2, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='gNMI_version', full_name='gnmi.CapabilityResponse.gNMI_version', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2855,
+  serialized_end=2985,
+)
+
+
+_MODELDATA = _descriptor.Descriptor(
+  name='ModelData',
+  full_name='gnmi.ModelData',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='name', full_name='gnmi.ModelData.name', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='organization', full_name='gnmi.ModelData.organization', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='version', full_name='gnmi.ModelData.version', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=_b("").decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2987,
+  serialized_end=3051,
+)
+
+_NOTIFICATION.fields_by_name['prefix'].message_type = _PATH
+_NOTIFICATION.fields_by_name['update'].message_type = _UPDATE
+_NOTIFICATION.fields_by_name['delete'].message_type = _PATH
+_UPDATE.fields_by_name['path'].message_type = _PATH
+_UPDATE.fields_by_name['value'].message_type = _VALUE
+_UPDATE.fields_by_name['val'].message_type = _TYPEDVALUE
+_TYPEDVALUE.fields_by_name['decimal_val'].message_type = _DECIMAL64
+_TYPEDVALUE.fields_by_name['leaflist_val'].message_type = _SCALARARRAY
+_TYPEDVALUE.fields_by_name['any_val'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['string_val'])
+_TYPEDVALUE.fields_by_name['string_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['int_val'])
+_TYPEDVALUE.fields_by_name['int_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['uint_val'])
+_TYPEDVALUE.fields_by_name['uint_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['bool_val'])
+_TYPEDVALUE.fields_by_name['bool_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['bytes_val'])
+_TYPEDVALUE.fields_by_name['bytes_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['float_val'])
+_TYPEDVALUE.fields_by_name['float_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['decimal_val'])
+_TYPEDVALUE.fields_by_name['decimal_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['leaflist_val'])
+_TYPEDVALUE.fields_by_name['leaflist_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['any_val'])
+_TYPEDVALUE.fields_by_name['any_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['json_val'])
+_TYPEDVALUE.fields_by_name['json_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['json_ietf_val'])
+_TYPEDVALUE.fields_by_name['json_ietf_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_TYPEDVALUE.oneofs_by_name['value'].fields.append(
+  _TYPEDVALUE.fields_by_name['ascii_val'])
+_TYPEDVALUE.fields_by_name['ascii_val'].containing_oneof = _TYPEDVALUE.oneofs_by_name['value']
+_PATH.fields_by_name['elem'].message_type = _PATHELEM
+_PATHELEM_KEYENTRY.containing_type = _PATHELEM
+_PATHELEM.fields_by_name['key'].message_type = _PATHELEM_KEYENTRY
+_VALUE.fields_by_name['type'].enum_type = _ENCODING
+_ERROR.fields_by_name['data'].message_type = google_dot_protobuf_dot_any__pb2._ANY
+_SCALARARRAY.fields_by_name['element'].message_type = _TYPEDVALUE
+_SUBSCRIBEREQUEST.fields_by_name['subscribe'].message_type = _SUBSCRIPTIONLIST
+_SUBSCRIBEREQUEST.fields_by_name['poll'].message_type = _POLL
+_SUBSCRIBEREQUEST.fields_by_name['aliases'].message_type = _ALIASLIST
+_SUBSCRIBEREQUEST.oneofs_by_name['request'].fields.append(
+  _SUBSCRIBEREQUEST.fields_by_name['subscribe'])
+_SUBSCRIBEREQUEST.fields_by_name['subscribe'].containing_oneof = _SUBSCRIBEREQUEST.oneofs_by_name['request']
+_SUBSCRIBEREQUEST.oneofs_by_name['request'].fields.append(
+  _SUBSCRIBEREQUEST.fields_by_name['poll'])
+_SUBSCRIBEREQUEST.fields_by_name['poll'].containing_oneof = _SUBSCRIBEREQUEST.oneofs_by_name['request']
+_SUBSCRIBEREQUEST.oneofs_by_name['request'].fields.append(
+  _SUBSCRIBEREQUEST.fields_by_name['aliases'])
+_SUBSCRIBEREQUEST.fields_by_name['aliases'].containing_oneof = _SUBSCRIBEREQUEST.oneofs_by_name['request']
+_SUBSCRIBERESPONSE.fields_by_name['update'].message_type = _NOTIFICATION
+_SUBSCRIBERESPONSE.fields_by_name['error'].message_type = _ERROR
+_SUBSCRIBERESPONSE.oneofs_by_name['response'].fields.append(
+  _SUBSCRIBERESPONSE.fields_by_name['update'])
+_SUBSCRIBERESPONSE.fields_by_name['update'].containing_oneof = _SUBSCRIBERESPONSE.oneofs_by_name['response']
+_SUBSCRIBERESPONSE.oneofs_by_name['response'].fields.append(
+  _SUBSCRIBERESPONSE.fields_by_name['sync_response'])
+_SUBSCRIBERESPONSE.fields_by_name['sync_response'].containing_oneof = _SUBSCRIBERESPONSE.oneofs_by_name['response']
+_SUBSCRIBERESPONSE.oneofs_by_name['response'].fields.append(
+  _SUBSCRIBERESPONSE.fields_by_name['error'])
+_SUBSCRIBERESPONSE.fields_by_name['error'].containing_oneof = _SUBSCRIBERESPONSE.oneofs_by_name['response']
+_SUBSCRIPTIONLIST.fields_by_name['prefix'].message_type = _PATH
+_SUBSCRIPTIONLIST.fields_by_name['subscription'].message_type = _SUBSCRIPTION
+_SUBSCRIPTIONLIST.fields_by_name['qos'].message_type = _QOSMARKING
+_SUBSCRIPTIONLIST.fields_by_name['mode'].enum_type = _SUBSCRIPTIONLIST_MODE
+_SUBSCRIPTIONLIST.fields_by_name['use_models'].message_type = _MODELDATA
+_SUBSCRIPTIONLIST.fields_by_name['encoding'].enum_type = _ENCODING
+_SUBSCRIPTIONLIST_MODE.containing_type = _SUBSCRIPTIONLIST
+_SUBSCRIPTION.fields_by_name['path'].message_type = _PATH
+_SUBSCRIPTION.fields_by_name['mode'].enum_type = _SUBSCRIPTIONMODE
+_ALIAS.fields_by_name['path'].message_type = _PATH
+_ALIASLIST.fields_by_name['alias'].message_type = _ALIAS
+_SETREQUEST.fields_by_name['prefix'].message_type = _PATH
+_SETREQUEST.fields_by_name['delete'].message_type = _PATH
+_SETREQUEST.fields_by_name['replace'].message_type = _UPDATE
+_SETREQUEST.fields_by_name['update'].message_type = _UPDATE
+_SETRESPONSE.fields_by_name['prefix'].message_type = _PATH
+_SETRESPONSE.fields_by_name['response'].message_type = _UPDATERESULT
+_SETRESPONSE.fields_by_name['message'].message_type = _ERROR
+_UPDATERESULT.fields_by_name['path'].message_type = _PATH
+_UPDATERESULT.fields_by_name['message'].message_type = _ERROR
+_UPDATERESULT.fields_by_name['op'].enum_type = _UPDATERESULT_OPERATION
+_UPDATERESULT_OPERATION.containing_type = _UPDATERESULT
+_GETREQUEST.fields_by_name['prefix'].message_type = _PATH
+_GETREQUEST.fields_by_name['path'].message_type = _PATH
+_GETREQUEST.fields_by_name['type'].enum_type = _GETREQUEST_DATATYPE
+_GETREQUEST.fields_by_name['encoding'].enum_type = _ENCODING
+_GETREQUEST.fields_by_name['use_models'].message_type = _MODELDATA
+_GETREQUEST_DATATYPE.containing_type = _GETREQUEST
+_GETRESPONSE.fields_by_name['notification'].message_type = _NOTIFICATION
+_GETRESPONSE.fields_by_name['error'].message_type = _ERROR
+_CAPABILITYRESPONSE.fields_by_name['supported_models'].message_type = _MODELDATA
+_CAPABILITYRESPONSE.fields_by_name['supported_encodings'].enum_type = _ENCODING
+DESCRIPTOR.message_types_by_name['Notification'] = _NOTIFICATION
+DESCRIPTOR.message_types_by_name['Update'] = _UPDATE
+DESCRIPTOR.message_types_by_name['TypedValue'] = _TYPEDVALUE
+DESCRIPTOR.message_types_by_name['Path'] = _PATH
+DESCRIPTOR.message_types_by_name['PathElem'] = _PATHELEM
+DESCRIPTOR.message_types_by_name['Value'] = _VALUE
+DESCRIPTOR.message_types_by_name['Error'] = _ERROR
+DESCRIPTOR.message_types_by_name['Decimal64'] = _DECIMAL64
+DESCRIPTOR.message_types_by_name['ScalarArray'] = _SCALARARRAY
+DESCRIPTOR.message_types_by_name['SubscribeRequest'] = _SUBSCRIBEREQUEST
+DESCRIPTOR.message_types_by_name['Poll'] = _POLL
+DESCRIPTOR.message_types_by_name['SubscribeResponse'] = _SUBSCRIBERESPONSE
+DESCRIPTOR.message_types_by_name['SubscriptionList'] = _SUBSCRIPTIONLIST
+DESCRIPTOR.message_types_by_name['Subscription'] = _SUBSCRIPTION
+DESCRIPTOR.message_types_by_name['QOSMarking'] = _QOSMARKING
+DESCRIPTOR.message_types_by_name['Alias'] = _ALIAS
+DESCRIPTOR.message_types_by_name['AliasList'] = _ALIASLIST
+DESCRIPTOR.message_types_by_name['SetRequest'] = _SETREQUEST
+DESCRIPTOR.message_types_by_name['SetResponse'] = _SETRESPONSE
+DESCRIPTOR.message_types_by_name['UpdateResult'] = _UPDATERESULT
+DESCRIPTOR.message_types_by_name['GetRequest'] = _GETREQUEST
+DESCRIPTOR.message_types_by_name['GetResponse'] = _GETRESPONSE
+DESCRIPTOR.message_types_by_name['CapabilityRequest'] = _CAPABILITYREQUEST
+DESCRIPTOR.message_types_by_name['CapabilityResponse'] = _CAPABILITYRESPONSE
+DESCRIPTOR.message_types_by_name['ModelData'] = _MODELDATA
+DESCRIPTOR.enum_types_by_name['Encoding'] = _ENCODING
+DESCRIPTOR.enum_types_by_name['SubscriptionMode'] = _SUBSCRIPTIONMODE
+DESCRIPTOR.extensions_by_name['gnmi_service'] = gnmi_service
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Notification = _reflection.GeneratedProtocolMessageType('Notification', (_message.Message,), dict(
+  DESCRIPTOR = _NOTIFICATION,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Notification)
+  ))
+_sym_db.RegisterMessage(Notification)
+
+Update = _reflection.GeneratedProtocolMessageType('Update', (_message.Message,), dict(
+  DESCRIPTOR = _UPDATE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Update)
+  ))
+_sym_db.RegisterMessage(Update)
+
+TypedValue = _reflection.GeneratedProtocolMessageType('TypedValue', (_message.Message,), dict(
+  DESCRIPTOR = _TYPEDVALUE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.TypedValue)
+  ))
+_sym_db.RegisterMessage(TypedValue)
+
+Path = _reflection.GeneratedProtocolMessageType('Path', (_message.Message,), dict(
+  DESCRIPTOR = _PATH,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Path)
+  ))
+_sym_db.RegisterMessage(Path)
+
+PathElem = _reflection.GeneratedProtocolMessageType('PathElem', (_message.Message,), dict(
+
+  KeyEntry = _reflection.GeneratedProtocolMessageType('KeyEntry', (_message.Message,), dict(
+    DESCRIPTOR = _PATHELEM_KEYENTRY,
+    __module__ = 'proto.gnmi.gnmi_pb2'
+    # @@protoc_insertion_point(class_scope:gnmi.PathElem.KeyEntry)
+    ))
+  ,
+  DESCRIPTOR = _PATHELEM,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.PathElem)
+  ))
+_sym_db.RegisterMessage(PathElem)
+_sym_db.RegisterMessage(PathElem.KeyEntry)
+
+Value = _reflection.GeneratedProtocolMessageType('Value', (_message.Message,), dict(
+  DESCRIPTOR = _VALUE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Value)
+  ))
+_sym_db.RegisterMessage(Value)
+
+Error = _reflection.GeneratedProtocolMessageType('Error', (_message.Message,), dict(
+  DESCRIPTOR = _ERROR,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Error)
+  ))
+_sym_db.RegisterMessage(Error)
+
+Decimal64 = _reflection.GeneratedProtocolMessageType('Decimal64', (_message.Message,), dict(
+  DESCRIPTOR = _DECIMAL64,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Decimal64)
+  ))
+_sym_db.RegisterMessage(Decimal64)
+
+ScalarArray = _reflection.GeneratedProtocolMessageType('ScalarArray', (_message.Message,), dict(
+  DESCRIPTOR = _SCALARARRAY,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.ScalarArray)
+  ))
+_sym_db.RegisterMessage(ScalarArray)
+
+SubscribeRequest = _reflection.GeneratedProtocolMessageType('SubscribeRequest', (_message.Message,), dict(
+  DESCRIPTOR = _SUBSCRIBEREQUEST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.SubscribeRequest)
+  ))
+_sym_db.RegisterMessage(SubscribeRequest)
+
+Poll = _reflection.GeneratedProtocolMessageType('Poll', (_message.Message,), dict(
+  DESCRIPTOR = _POLL,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Poll)
+  ))
+_sym_db.RegisterMessage(Poll)
+
+SubscribeResponse = _reflection.GeneratedProtocolMessageType('SubscribeResponse', (_message.Message,), dict(
+  DESCRIPTOR = _SUBSCRIBERESPONSE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.SubscribeResponse)
+  ))
+_sym_db.RegisterMessage(SubscribeResponse)
+
+SubscriptionList = _reflection.GeneratedProtocolMessageType('SubscriptionList', (_message.Message,), dict(
+  DESCRIPTOR = _SUBSCRIPTIONLIST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.SubscriptionList)
+  ))
+_sym_db.RegisterMessage(SubscriptionList)
+
+Subscription = _reflection.GeneratedProtocolMessageType('Subscription', (_message.Message,), dict(
+  DESCRIPTOR = _SUBSCRIPTION,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Subscription)
+  ))
+_sym_db.RegisterMessage(Subscription)
+
+QOSMarking = _reflection.GeneratedProtocolMessageType('QOSMarking', (_message.Message,), dict(
+  DESCRIPTOR = _QOSMARKING,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.QOSMarking)
+  ))
+_sym_db.RegisterMessage(QOSMarking)
+
+Alias = _reflection.GeneratedProtocolMessageType('Alias', (_message.Message,), dict(
+  DESCRIPTOR = _ALIAS,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.Alias)
+  ))
+_sym_db.RegisterMessage(Alias)
+
+AliasList = _reflection.GeneratedProtocolMessageType('AliasList', (_message.Message,), dict(
+  DESCRIPTOR = _ALIASLIST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.AliasList)
+  ))
+_sym_db.RegisterMessage(AliasList)
+
+SetRequest = _reflection.GeneratedProtocolMessageType('SetRequest', (_message.Message,), dict(
+  DESCRIPTOR = _SETREQUEST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.SetRequest)
+  ))
+_sym_db.RegisterMessage(SetRequest)
+
+SetResponse = _reflection.GeneratedProtocolMessageType('SetResponse', (_message.Message,), dict(
+  DESCRIPTOR = _SETRESPONSE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.SetResponse)
+  ))
+_sym_db.RegisterMessage(SetResponse)
+
+UpdateResult = _reflection.GeneratedProtocolMessageType('UpdateResult', (_message.Message,), dict(
+  DESCRIPTOR = _UPDATERESULT,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.UpdateResult)
+  ))
+_sym_db.RegisterMessage(UpdateResult)
+
+GetRequest = _reflection.GeneratedProtocolMessageType('GetRequest', (_message.Message,), dict(
+  DESCRIPTOR = _GETREQUEST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.GetRequest)
+  ))
+_sym_db.RegisterMessage(GetRequest)
+
+GetResponse = _reflection.GeneratedProtocolMessageType('GetResponse', (_message.Message,), dict(
+  DESCRIPTOR = _GETRESPONSE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.GetResponse)
+  ))
+_sym_db.RegisterMessage(GetResponse)
+
+CapabilityRequest = _reflection.GeneratedProtocolMessageType('CapabilityRequest', (_message.Message,), dict(
+  DESCRIPTOR = _CAPABILITYREQUEST,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.CapabilityRequest)
+  ))
+_sym_db.RegisterMessage(CapabilityRequest)
+
+CapabilityResponse = _reflection.GeneratedProtocolMessageType('CapabilityResponse', (_message.Message,), dict(
+  DESCRIPTOR = _CAPABILITYRESPONSE,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.CapabilityResponse)
+  ))
+_sym_db.RegisterMessage(CapabilityResponse)
+
+ModelData = _reflection.GeneratedProtocolMessageType('ModelData', (_message.Message,), dict(
+  DESCRIPTOR = _MODELDATA,
+  __module__ = 'proto.gnmi.gnmi_pb2'
+  # @@protoc_insertion_point(class_scope:gnmi.ModelData)
+  ))
+_sym_db.RegisterMessage(ModelData)
+
+google_dot_protobuf_dot_descriptor__pb2.FileOptions.RegisterExtension(gnmi_service)
+
+DESCRIPTOR.has_options = True
+DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\312>\0050.5.0'))
+_UPDATE.fields_by_name['value'].has_options = True
+_UPDATE.fields_by_name['value']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_PATH.fields_by_name['element'].has_options = True
+_PATH.fields_by_name['element']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_PATHELEM_KEYENTRY.has_options = True
+_PATHELEM_KEYENTRY._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('8\001'))
+_VALUE.has_options = True
+_VALUE._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\030\001'))
+_ERROR.has_options = True
+_ERROR._options = _descriptor._ParseOptions(descriptor_pb2.MessageOptions(), _b('\030\001'))
+_SUBSCRIBERESPONSE.fields_by_name['error'].has_options = True
+_SUBSCRIBERESPONSE.fields_by_name['error']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_SETRESPONSE.fields_by_name['message'].has_options = True
+_SETRESPONSE.fields_by_name['message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_UPDATERESULT.fields_by_name['timestamp'].has_options = True
+_UPDATERESULT.fields_by_name['timestamp']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_UPDATERESULT.fields_by_name['message'].has_options = True
+_UPDATERESULT.fields_by_name['message']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+_GETRESPONSE.fields_by_name['error'].has_options = True
+_GETRESPONSE.fields_by_name['error']._options = _descriptor._ParseOptions(descriptor_pb2.FieldOptions(), _b('\030\001'))
+try:
+  # THESE ELEMENTS WILL BE DEPRECATED.
+  # Please use the generated *_pb2_grpc.py files instead.
+  import grpc
+  from grpc.beta import implementations as beta_implementations
+  from grpc.beta import interfaces as beta_interfaces
+  from grpc.framework.common import cardinality
+  from grpc.framework.interfaces.face import utilities as face_utilities
+
+
+  class gNMIStub(object):
+    # missing associated documentation comment in .proto file
+    pass
+
+    def __init__(self, channel):
+      """Constructor.
+
+      Args:
+        channel: A grpc.Channel.
+      """
+      self.Capabilities = channel.unary_unary(
+          '/gnmi.gNMI/Capabilities',
+          request_serializer=CapabilityRequest.SerializeToString,
+          response_deserializer=CapabilityResponse.FromString,
+          )
+      self.Get = channel.unary_unary(
+          '/gnmi.gNMI/Get',
+          request_serializer=GetRequest.SerializeToString,
+          response_deserializer=GetResponse.FromString,
+          )
+      self.Set = channel.unary_unary(
+          '/gnmi.gNMI/Set',
+          request_serializer=SetRequest.SerializeToString,
+          response_deserializer=SetResponse.FromString,
+          )
+      self.Subscribe = channel.stream_stream(
+          '/gnmi.gNMI/Subscribe',
+          request_serializer=SubscribeRequest.SerializeToString,
+          response_deserializer=SubscribeResponse.FromString,
+          )
+
+
+  class gNMIServicer(object):
+    # missing associated documentation comment in .proto file
+    pass
+
+    def Capabilities(self, request, context):
+      """Capabilities allows the client to retrieve the set of capabilities that
+      is supported by the target. This allows the target to validate the
+      service version that is implemented and retrieve the set of models that
+      the target supports. The models can then be specified in subsequent RPCs
+      to restrict the set of data that is utilized.
+      Reference: gNMI Specification Section 3.2
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def Get(self, request, context):
+      """Retrieve a snapshot of data from the target. A Get RPC requests that the
+      target snapshots a subset of the data tree as specified by the paths
+      included in the message and serializes this to be returned to the
+      client using the specified encoding.
+      Reference: gNMI Specification Section 3.3
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def Set(self, request, context):
+      """Set allows the client to modify the state of data on the target. The
+      paths to modified along with the new values that the client wishes
+      to set the value to.
+      Reference: gNMI Specification Section 3.4
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+    def Subscribe(self, request_iterator, context):
+      """Subscribe allows a client to request the target to send it values
+      of particular paths within the data tree. These values may be streamed
+      at a particular cadence (STREAM), sent one off on a long-lived channel
+      (POLL), or sent as a one-off retrieval (ONCE).
+      Reference: gNMI Specification Section 3.5
+      """
+      context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+      context.set_details('Method not implemented!')
+      raise NotImplementedError('Method not implemented!')
+
+
+  def add_gNMIServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+        'Capabilities': grpc.unary_unary_rpc_method_handler(
+            servicer.Capabilities,
+            request_deserializer=CapabilityRequest.FromString,
+            response_serializer=CapabilityResponse.SerializeToString,
+        ),
+        'Get': grpc.unary_unary_rpc_method_handler(
+            servicer.Get,
+            request_deserializer=GetRequest.FromString,
+            response_serializer=GetResponse.SerializeToString,
+        ),
+        'Set': grpc.unary_unary_rpc_method_handler(
+            servicer.Set,
+            request_deserializer=SetRequest.FromString,
+            response_serializer=SetResponse.SerializeToString,
+        ),
+        'Subscribe': grpc.stream_stream_rpc_method_handler(
+            servicer.Subscribe,
+            request_deserializer=SubscribeRequest.FromString,
+            response_serializer=SubscribeResponse.SerializeToString,
+        ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+        'gnmi.gNMI', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+  class BetagNMIServicer(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    # missing associated documentation comment in .proto file
+    pass
+    def Capabilities(self, request, context):
+      """Capabilities allows the client to retrieve the set of capabilities that
+      is supported by the target. This allows the target to validate the
+      service version that is implemented and retrieve the set of models that
+      the target supports. The models can then be specified in subsequent RPCs
+      to restrict the set of data that is utilized.
+      Reference: gNMI Specification Section 3.2
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def Get(self, request, context):
+      """Retrieve a snapshot of data from the target. A Get RPC requests that the
+      target snapshots a subset of the data tree as specified by the paths
+      included in the message and serializes this to be returned to the
+      client using the specified encoding.
+      Reference: gNMI Specification Section 3.3
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def Set(self, request, context):
+      """Set allows the client to modify the state of data on the target. The
+      paths to modified along with the new values that the client wishes
+      to set the value to.
+      Reference: gNMI Specification Section 3.4
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+    def Subscribe(self, request_iterator, context):
+      """Subscribe allows a client to request the target to send it values
+      of particular paths within the data tree. These values may be streamed
+      at a particular cadence (STREAM), sent one off on a long-lived channel
+      (POLL), or sent as a one-off retrieval (ONCE).
+      Reference: gNMI Specification Section 3.5
+      """
+      context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
+
+
+  class BetagNMIStub(object):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This class was generated
+    only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
+    # missing associated documentation comment in .proto file
+    pass
+    def Capabilities(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Capabilities allows the client to retrieve the set of capabilities that
+      is supported by the target. This allows the target to validate the
+      service version that is implemented and retrieve the set of models that
+      the target supports. The models can then be specified in subsequent RPCs
+      to restrict the set of data that is utilized.
+      Reference: gNMI Specification Section 3.2
+      """
+      raise NotImplementedError()
+    Capabilities.future = None
+    def Get(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Retrieve a snapshot of data from the target. A Get RPC requests that the
+      target snapshots a subset of the data tree as specified by the paths
+      included in the message and serializes this to be returned to the
+      client using the specified encoding.
+      Reference: gNMI Specification Section 3.3
+      """
+      raise NotImplementedError()
+    Get.future = None
+    def Set(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Set allows the client to modify the state of data on the target. The
+      paths to modified along with the new values that the client wishes
+      to set the value to.
+      Reference: gNMI Specification Section 3.4
+      """
+      raise NotImplementedError()
+    Set.future = None
+    def Subscribe(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
+      """Subscribe allows a client to request the target to send it values
+      of particular paths within the data tree. These values may be streamed
+      at a particular cadence (STREAM), sent one off on a long-lived channel
+      (POLL), or sent as a one-off retrieval (ONCE).
+      Reference: gNMI Specification Section 3.5
+      """
+      raise NotImplementedError()
+
+
+  def beta_create_gNMI_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_deserializers = {
+      ('gnmi.gNMI', 'Capabilities'): CapabilityRequest.FromString,
+      ('gnmi.gNMI', 'Get'): GetRequest.FromString,
+      ('gnmi.gNMI', 'Set'): SetRequest.FromString,
+      ('gnmi.gNMI', 'Subscribe'): SubscribeRequest.FromString,
+    }
+    response_serializers = {
+      ('gnmi.gNMI', 'Capabilities'): CapabilityResponse.SerializeToString,
+      ('gnmi.gNMI', 'Get'): GetResponse.SerializeToString,
+      ('gnmi.gNMI', 'Set'): SetResponse.SerializeToString,
+      ('gnmi.gNMI', 'Subscribe'): SubscribeResponse.SerializeToString,
+    }
+    method_implementations = {
+      ('gnmi.gNMI', 'Capabilities'): face_utilities.unary_unary_inline(servicer.Capabilities),
+      ('gnmi.gNMI', 'Get'): face_utilities.unary_unary_inline(servicer.Get),
+      ('gnmi.gNMI', 'Set'): face_utilities.unary_unary_inline(servicer.Set),
+      ('gnmi.gNMI', 'Subscribe'): face_utilities.stream_stream_inline(servicer.Subscribe),
+    }
+    server_options = beta_implementations.server_options(request_deserializers=request_deserializers, response_serializers=response_serializers, thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
+    return beta_implementations.server(method_implementations, options=server_options)
+
+
+  def beta_create_gNMI_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
+    """The Beta API is deprecated for 0.15.0 and later.
+
+    It is recommended to use the GA API (classes and functions in this
+    file not marked beta) for all further purposes. This function was
+    generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
+    request_serializers = {
+      ('gnmi.gNMI', 'Capabilities'): CapabilityRequest.SerializeToString,
+      ('gnmi.gNMI', 'Get'): GetRequest.SerializeToString,
+      ('gnmi.gNMI', 'Set'): SetRequest.SerializeToString,
+      ('gnmi.gNMI', 'Subscribe'): SubscribeRequest.SerializeToString,
+    }
+    response_deserializers = {
+      ('gnmi.gNMI', 'Capabilities'): CapabilityResponse.FromString,
+      ('gnmi.gNMI', 'Get'): GetResponse.FromString,
+      ('gnmi.gNMI', 'Set'): SetResponse.FromString,
+      ('gnmi.gNMI', 'Subscribe'): SubscribeResponse.FromString,
+    }
+    cardinalities = {
+      'Capabilities': cardinality.Cardinality.UNARY_UNARY,
+      'Get': cardinality.Cardinality.UNARY_UNARY,
+      'Set': cardinality.Cardinality.UNARY_UNARY,
+      'Subscribe': cardinality.Cardinality.STREAM_STREAM,
+    }
+    stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, request_serializers=request_serializers, response_deserializers=response_deserializers, thread_pool=pool, thread_pool_size=pool_size)
+    return beta_implementations.dynamic_stub(channel, 'gnmi.gNMI', cardinalities, options=stub_options)
+except ImportError:
+  pass
+# @@protoc_insertion_point(module_scope)
diff --git a/src/device/service/drivers/openconfig/gnmi_pb2.pyi b/src/device/service/drivers/openconfig/gnmi_pb2.pyi
new file mode 100644
index 0000000000000000000000000000000000000000..423bcfb90e1a603c2ebcdc29092569c7695db2d0
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi_pb2.pyi
@@ -0,0 +1,380 @@
+from google.protobuf import any_pb2 as _any_pb2
+from google.protobuf import descriptor_pb2 as _descriptor_pb2
+from google.protobuf.internal import containers as _containers
+from google.protobuf.internal import enum_type_wrapper as _enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from typing import ClassVar as _ClassVar, Iterable as _Iterable, Mapping as _Mapping, Optional as _Optional, Union as _Union
+
+ASCII: Encoding
+BYTES: Encoding
+DESCRIPTOR: _descriptor.FileDescriptor
+EID_EXPERIMENTAL: ExtensionID
+EID_UNSET: ExtensionID
+GNMI_SERVICE_FIELD_NUMBER: _ClassVar[int]
+JSON: Encoding
+JSON_IETF: Encoding
+ON_CHANGE: SubscriptionMode
+PROTO: Encoding
+SAMPLE: SubscriptionMode
+TARGET_DEFINED: SubscriptionMode
+gnmi_service: _descriptor.FieldDescriptor
+
+class CapabilityRequest(_message.Message):
+    __slots__ = ["extension"]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    def __init__(self, extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class CapabilityResponse(_message.Message):
+    __slots__ = ["extension", "gNMI_version", "supported_encodings", "supported_models"]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    GNMI_VERSION_FIELD_NUMBER: _ClassVar[int]
+    SUPPORTED_ENCODINGS_FIELD_NUMBER: _ClassVar[int]
+    SUPPORTED_MODELS_FIELD_NUMBER: _ClassVar[int]
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    gNMI_version: str
+    supported_encodings: _containers.RepeatedScalarFieldContainer[Encoding]
+    supported_models: _containers.RepeatedCompositeFieldContainer[ModelData]
+    def __init__(self, supported_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., supported_encodings: _Optional[_Iterable[_Union[Encoding, str]]] = ..., gNMI_version: _Optional[str] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class Decimal64(_message.Message):
+    __slots__ = ["digits", "precision"]
+    DIGITS_FIELD_NUMBER: _ClassVar[int]
+    PRECISION_FIELD_NUMBER: _ClassVar[int]
+    digits: int
+    precision: int
+    def __init__(self, digits: _Optional[int] = ..., precision: _Optional[int] = ...) -> None: ...
+
+class Error(_message.Message):
+    __slots__ = ["code", "data", "message"]
+    CODE_FIELD_NUMBER: _ClassVar[int]
+    DATA_FIELD_NUMBER: _ClassVar[int]
+    MESSAGE_FIELD_NUMBER: _ClassVar[int]
+    code: int
+    data: _any_pb2.Any
+    message: str
+    def __init__(self, code: _Optional[int] = ..., message: _Optional[str] = ..., data: _Optional[_Union[_any_pb2.Any, _Mapping]] = ...) -> None: ...
+
+class Extension(_message.Message):
+    __slots__ = ["history", "master_arbitration", "registered_ext"]
+    HISTORY_FIELD_NUMBER: _ClassVar[int]
+    MASTER_ARBITRATION_FIELD_NUMBER: _ClassVar[int]
+    REGISTERED_EXT_FIELD_NUMBER: _ClassVar[int]
+    history: History
+    master_arbitration: MasterArbitration
+    registered_ext: RegisteredExtension
+    def __init__(self, registered_ext: _Optional[_Union[RegisteredExtension, _Mapping]] = ..., master_arbitration: _Optional[_Union[MasterArbitration, _Mapping]] = ..., history: _Optional[_Union[History, _Mapping]] = ...) -> None: ...
+
+class GetRequest(_message.Message):
+    __slots__ = ["encoding", "extension", "path", "prefix", "type", "use_models"]
+    class DataType(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+        __slots__ = []
+    ALL: GetRequest.DataType
+    CONFIG: GetRequest.DataType
+    ENCODING_FIELD_NUMBER: _ClassVar[int]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    OPERATIONAL: GetRequest.DataType
+    PATH_FIELD_NUMBER: _ClassVar[int]
+    PREFIX_FIELD_NUMBER: _ClassVar[int]
+    STATE: GetRequest.DataType
+    TYPE_FIELD_NUMBER: _ClassVar[int]
+    USE_MODELS_FIELD_NUMBER: _ClassVar[int]
+    encoding: Encoding
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    path: _containers.RepeatedCompositeFieldContainer[Path]
+    prefix: Path
+    type: GetRequest.DataType
+    use_models: _containers.RepeatedCompositeFieldContainer[ModelData]
+    def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., path: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., type: _Optional[_Union[GetRequest.DataType, str]] = ..., encoding: _Optional[_Union[Encoding, str]] = ..., use_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class GetResponse(_message.Message):
+    __slots__ = ["error", "extension", "notification"]
+    ERROR_FIELD_NUMBER: _ClassVar[int]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    NOTIFICATION_FIELD_NUMBER: _ClassVar[int]
+    error: Error
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    notification: _containers.RepeatedCompositeFieldContainer[Notification]
+    def __init__(self, notification: _Optional[_Iterable[_Union[Notification, _Mapping]]] = ..., error: _Optional[_Union[Error, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class History(_message.Message):
+    __slots__ = ["range", "snapshot_time"]
+    RANGE_FIELD_NUMBER: _ClassVar[int]
+    SNAPSHOT_TIME_FIELD_NUMBER: _ClassVar[int]
+    range: TimeRange
+    snapshot_time: int
+    def __init__(self, snapshot_time: _Optional[int] = ..., range: _Optional[_Union[TimeRange, _Mapping]] = ...) -> None: ...
+
+class MasterArbitration(_message.Message):
+    __slots__ = ["election_id", "role"]
+    ELECTION_ID_FIELD_NUMBER: _ClassVar[int]
+    ROLE_FIELD_NUMBER: _ClassVar[int]
+    election_id: Uint128
+    role: Role
+    def __init__(self, role: _Optional[_Union[Role, _Mapping]] = ..., election_id: _Optional[_Union[Uint128, _Mapping]] = ...) -> None: ...
+
+class ModelData(_message.Message):
+    __slots__ = ["name", "organization", "version"]
+    NAME_FIELD_NUMBER: _ClassVar[int]
+    ORGANIZATION_FIELD_NUMBER: _ClassVar[int]
+    VERSION_FIELD_NUMBER: _ClassVar[int]
+    name: str
+    organization: str
+    version: str
+    def __init__(self, name: _Optional[str] = ..., organization: _Optional[str] = ..., version: _Optional[str] = ...) -> None: ...
+
+class Notification(_message.Message):
+    __slots__ = ["atomic", "delete", "prefix", "timestamp", "update"]
+    ATOMIC_FIELD_NUMBER: _ClassVar[int]
+    DELETE_FIELD_NUMBER: _ClassVar[int]
+    PREFIX_FIELD_NUMBER: _ClassVar[int]
+    TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
+    UPDATE_FIELD_NUMBER: _ClassVar[int]
+    atomic: bool
+    delete: _containers.RepeatedCompositeFieldContainer[Path]
+    prefix: Path
+    timestamp: int
+    update: _containers.RepeatedCompositeFieldContainer[Update]
+    def __init__(self, timestamp: _Optional[int] = ..., prefix: _Optional[_Union[Path, _Mapping]] = ..., update: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., delete: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., atomic: bool = ...) -> None: ...
+
+class Path(_message.Message):
+    __slots__ = ["elem", "element", "origin", "target"]
+    ELEMENT_FIELD_NUMBER: _ClassVar[int]
+    ELEM_FIELD_NUMBER: _ClassVar[int]
+    ORIGIN_FIELD_NUMBER: _ClassVar[int]
+    TARGET_FIELD_NUMBER: _ClassVar[int]
+    elem: _containers.RepeatedCompositeFieldContainer[PathElem]
+    element: _containers.RepeatedScalarFieldContainer[str]
+    origin: str
+    target: str
+    def __init__(self, element: _Optional[_Iterable[str]] = ..., origin: _Optional[str] = ..., elem: _Optional[_Iterable[_Union[PathElem, _Mapping]]] = ..., target: _Optional[str] = ...) -> None: ...
+
+class PathElem(_message.Message):
+    __slots__ = ["key", "name"]
+    class KeyEntry(_message.Message):
+        __slots__ = ["key", "value"]
+        KEY_FIELD_NUMBER: _ClassVar[int]
+        VALUE_FIELD_NUMBER: _ClassVar[int]
+        key: str
+        value: str
+        def __init__(self, key: _Optional[str] = ..., value: _Optional[str] = ...) -> None: ...
+    KEY_FIELD_NUMBER: _ClassVar[int]
+    NAME_FIELD_NUMBER: _ClassVar[int]
+    key: _containers.ScalarMap[str, str]
+    name: str
+    def __init__(self, name: _Optional[str] = ..., key: _Optional[_Mapping[str, str]] = ...) -> None: ...
+
+class Poll(_message.Message):
+    __slots__ = []
+    def __init__(self) -> None: ...
+
+class QOSMarking(_message.Message):
+    __slots__ = ["marking"]
+    MARKING_FIELD_NUMBER: _ClassVar[int]
+    marking: int
+    def __init__(self, marking: _Optional[int] = ...) -> None: ...
+
+class RegisteredExtension(_message.Message):
+    __slots__ = ["id", "msg"]
+    ID_FIELD_NUMBER: _ClassVar[int]
+    MSG_FIELD_NUMBER: _ClassVar[int]
+    id: ExtensionID
+    msg: bytes
+    def __init__(self, id: _Optional[_Union[ExtensionID, str]] = ..., msg: _Optional[bytes] = ...) -> None: ...
+
+class Role(_message.Message):
+    __slots__ = ["id"]
+    ID_FIELD_NUMBER: _ClassVar[int]
+    id: str
+    def __init__(self, id: _Optional[str] = ...) -> None: ...
+
+class ScalarArray(_message.Message):
+    __slots__ = ["element"]
+    ELEMENT_FIELD_NUMBER: _ClassVar[int]
+    element: _containers.RepeatedCompositeFieldContainer[TypedValue]
+    def __init__(self, element: _Optional[_Iterable[_Union[TypedValue, _Mapping]]] = ...) -> None: ...
+
+class SetRequest(_message.Message):
+    __slots__ = ["delete", "extension", "prefix", "replace", "update"]
+    DELETE_FIELD_NUMBER: _ClassVar[int]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    PREFIX_FIELD_NUMBER: _ClassVar[int]
+    REPLACE_FIELD_NUMBER: _ClassVar[int]
+    UPDATE_FIELD_NUMBER: _ClassVar[int]
+    delete: _containers.RepeatedCompositeFieldContainer[Path]
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    prefix: Path
+    replace: _containers.RepeatedCompositeFieldContainer[Update]
+    update: _containers.RepeatedCompositeFieldContainer[Update]
+    def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., delete: _Optional[_Iterable[_Union[Path, _Mapping]]] = ..., replace: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., update: _Optional[_Iterable[_Union[Update, _Mapping]]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class SetResponse(_message.Message):
+    __slots__ = ["extension", "message", "prefix", "response", "timestamp"]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    MESSAGE_FIELD_NUMBER: _ClassVar[int]
+    PREFIX_FIELD_NUMBER: _ClassVar[int]
+    RESPONSE_FIELD_NUMBER: _ClassVar[int]
+    TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    message: Error
+    prefix: Path
+    response: _containers.RepeatedCompositeFieldContainer[UpdateResult]
+    timestamp: int
+    def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., response: _Optional[_Iterable[_Union[UpdateResult, _Mapping]]] = ..., message: _Optional[_Union[Error, _Mapping]] = ..., timestamp: _Optional[int] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class SubscribeRequest(_message.Message):
+    __slots__ = ["extension", "poll", "subscribe"]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    POLL_FIELD_NUMBER: _ClassVar[int]
+    SUBSCRIBE_FIELD_NUMBER: _ClassVar[int]
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    poll: Poll
+    subscribe: SubscriptionList
+    def __init__(self, subscribe: _Optional[_Union[SubscriptionList, _Mapping]] = ..., poll: _Optional[_Union[Poll, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class SubscribeResponse(_message.Message):
+    __slots__ = ["error", "extension", "sync_response", "update"]
+    ERROR_FIELD_NUMBER: _ClassVar[int]
+    EXTENSION_FIELD_NUMBER: _ClassVar[int]
+    SYNC_RESPONSE_FIELD_NUMBER: _ClassVar[int]
+    UPDATE_FIELD_NUMBER: _ClassVar[int]
+    error: Error
+    extension: _containers.RepeatedCompositeFieldContainer[Extension]
+    sync_response: bool
+    update: Notification
+    def __init__(self, update: _Optional[_Union[Notification, _Mapping]] = ..., sync_response: bool = ..., error: _Optional[_Union[Error, _Mapping]] = ..., extension: _Optional[_Iterable[_Union[Extension, _Mapping]]] = ...) -> None: ...
+
+class Subscription(_message.Message):
+    __slots__ = ["heartbeat_interval", "mode", "path", "sample_interval", "suppress_redundant"]
+    HEARTBEAT_INTERVAL_FIELD_NUMBER: _ClassVar[int]
+    MODE_FIELD_NUMBER: _ClassVar[int]
+    PATH_FIELD_NUMBER: _ClassVar[int]
+    SAMPLE_INTERVAL_FIELD_NUMBER: _ClassVar[int]
+    SUPPRESS_REDUNDANT_FIELD_NUMBER: _ClassVar[int]
+    heartbeat_interval: int
+    mode: SubscriptionMode
+    path: Path
+    sample_interval: int
+    suppress_redundant: bool
+    def __init__(self, path: _Optional[_Union[Path, _Mapping]] = ..., mode: _Optional[_Union[SubscriptionMode, str]] = ..., sample_interval: _Optional[int] = ..., suppress_redundant: bool = ..., heartbeat_interval: _Optional[int] = ...) -> None: ...
+
+class SubscriptionList(_message.Message):
+    __slots__ = ["allow_aggregation", "encoding", "mode", "prefix", "qos", "subscription", "updates_only", "use_models"]
+    class Mode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+        __slots__ = []
+    ALLOW_AGGREGATION_FIELD_NUMBER: _ClassVar[int]
+    ENCODING_FIELD_NUMBER: _ClassVar[int]
+    MODE_FIELD_NUMBER: _ClassVar[int]
+    ONCE: SubscriptionList.Mode
+    POLL: SubscriptionList.Mode
+    PREFIX_FIELD_NUMBER: _ClassVar[int]
+    QOS_FIELD_NUMBER: _ClassVar[int]
+    STREAM: SubscriptionList.Mode
+    SUBSCRIPTION_FIELD_NUMBER: _ClassVar[int]
+    UPDATES_ONLY_FIELD_NUMBER: _ClassVar[int]
+    USE_MODELS_FIELD_NUMBER: _ClassVar[int]
+    allow_aggregation: bool
+    encoding: Encoding
+    mode: SubscriptionList.Mode
+    prefix: Path
+    qos: QOSMarking
+    subscription: _containers.RepeatedCompositeFieldContainer[Subscription]
+    updates_only: bool
+    use_models: _containers.RepeatedCompositeFieldContainer[ModelData]
+    def __init__(self, prefix: _Optional[_Union[Path, _Mapping]] = ..., subscription: _Optional[_Iterable[_Union[Subscription, _Mapping]]] = ..., qos: _Optional[_Union[QOSMarking, _Mapping]] = ..., mode: _Optional[_Union[SubscriptionList.Mode, str]] = ..., allow_aggregation: bool = ..., use_models: _Optional[_Iterable[_Union[ModelData, _Mapping]]] = ..., encoding: _Optional[_Union[Encoding, str]] = ..., updates_only: bool = ...) -> None: ...
+
+class TimeRange(_message.Message):
+    __slots__ = ["end", "start"]
+    END_FIELD_NUMBER: _ClassVar[int]
+    START_FIELD_NUMBER: _ClassVar[int]
+    end: int
+    start: int
+    def __init__(self, start: _Optional[int] = ..., end: _Optional[int] = ...) -> None: ...
+
+class TypedValue(_message.Message):
+    __slots__ = ["any_val", "ascii_val", "bool_val", "bytes_val", "decimal_val", "double_val", "float_val", "int_val", "json_ietf_val", "json_val", "leaflist_val", "proto_bytes", "string_val", "uint_val"]
+    ANY_VAL_FIELD_NUMBER: _ClassVar[int]
+    ASCII_VAL_FIELD_NUMBER: _ClassVar[int]
+    BOOL_VAL_FIELD_NUMBER: _ClassVar[int]
+    BYTES_VAL_FIELD_NUMBER: _ClassVar[int]
+    DECIMAL_VAL_FIELD_NUMBER: _ClassVar[int]
+    DOUBLE_VAL_FIELD_NUMBER: _ClassVar[int]
+    FLOAT_VAL_FIELD_NUMBER: _ClassVar[int]
+    INT_VAL_FIELD_NUMBER: _ClassVar[int]
+    JSON_IETF_VAL_FIELD_NUMBER: _ClassVar[int]
+    JSON_VAL_FIELD_NUMBER: _ClassVar[int]
+    LEAFLIST_VAL_FIELD_NUMBER: _ClassVar[int]
+    PROTO_BYTES_FIELD_NUMBER: _ClassVar[int]
+    STRING_VAL_FIELD_NUMBER: _ClassVar[int]
+    UINT_VAL_FIELD_NUMBER: _ClassVar[int]
+    any_val: _any_pb2.Any
+    ascii_val: str
+    bool_val: bool
+    bytes_val: bytes
+    decimal_val: Decimal64
+    double_val: float
+    float_val: float
+    int_val: int
+    json_ietf_val: bytes
+    json_val: bytes
+    leaflist_val: ScalarArray
+    proto_bytes: bytes
+    string_val: str
+    uint_val: int
+    def __init__(self, string_val: _Optional[str] = ..., int_val: _Optional[int] = ..., uint_val: _Optional[int] = ..., bool_val: bool = ..., bytes_val: _Optional[bytes] = ..., float_val: _Optional[float] = ..., double_val: _Optional[float] = ..., decimal_val: _Optional[_Union[Decimal64, _Mapping]] = ..., leaflist_val: _Optional[_Union[ScalarArray, _Mapping]] = ..., any_val: _Optional[_Union[_any_pb2.Any, _Mapping]] = ..., json_val: _Optional[bytes] = ..., json_ietf_val: _Optional[bytes] = ..., ascii_val: _Optional[str] = ..., proto_bytes: _Optional[bytes] = ...) -> None: ...
+
+class Uint128(_message.Message):
+    __slots__ = ["high", "low"]
+    HIGH_FIELD_NUMBER: _ClassVar[int]
+    LOW_FIELD_NUMBER: _ClassVar[int]
+    high: int
+    low: int
+    def __init__(self, high: _Optional[int] = ..., low: _Optional[int] = ...) -> None: ...
+
+class Update(_message.Message):
+    __slots__ = ["duplicates", "path", "val", "value"]
+    DUPLICATES_FIELD_NUMBER: _ClassVar[int]
+    PATH_FIELD_NUMBER: _ClassVar[int]
+    VALUE_FIELD_NUMBER: _ClassVar[int]
+    VAL_FIELD_NUMBER: _ClassVar[int]
+    duplicates: int
+    path: Path
+    val: TypedValue
+    value: Value
+    def __init__(self, path: _Optional[_Union[Path, _Mapping]] = ..., value: _Optional[_Union[Value, _Mapping]] = ..., val: _Optional[_Union[TypedValue, _Mapping]] = ..., duplicates: _Optional[int] = ...) -> None: ...
+
+class UpdateResult(_message.Message):
+    __slots__ = ["message", "op", "path", "timestamp"]
+    class Operation(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+        __slots__ = []
+    DELETE: UpdateResult.Operation
+    INVALID: UpdateResult.Operation
+    MESSAGE_FIELD_NUMBER: _ClassVar[int]
+    OP_FIELD_NUMBER: _ClassVar[int]
+    PATH_FIELD_NUMBER: _ClassVar[int]
+    REPLACE: UpdateResult.Operation
+    TIMESTAMP_FIELD_NUMBER: _ClassVar[int]
+    UPDATE: UpdateResult.Operation
+    message: Error
+    op: UpdateResult.Operation
+    path: Path
+    timestamp: int
+    def __init__(self, timestamp: _Optional[int] = ..., path: _Optional[_Union[Path, _Mapping]] = ..., message: _Optional[_Union[Error, _Mapping]] = ..., op: _Optional[_Union[UpdateResult.Operation, str]] = ...) -> None: ...
+
+class Value(_message.Message):
+    __slots__ = ["type", "value"]
+    TYPE_FIELD_NUMBER: _ClassVar[int]
+    VALUE_FIELD_NUMBER: _ClassVar[int]
+    type: Encoding
+    value: bytes
+    def __init__(self, value: _Optional[bytes] = ..., type: _Optional[_Union[Encoding, str]] = ...) -> None: ...
+
+class ExtensionID(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+    __slots__ = []
+
+class Encoding(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+    __slots__ = []
+
+class SubscriptionMode(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
+    __slots__ = []
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/gnmi_pb2_grpc.py b/src/device/service/drivers/openconfig/gnmi_pb2_grpc.py
new file mode 100644
index 0000000000000000000000000000000000000000..43fb01413a4286917cf4063ffcf66972abcf2e42
--- /dev/null
+++ b/src/device/service/drivers/openconfig/gnmi_pb2_grpc.py
@@ -0,0 +1,185 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+import gnmi_pb2 as gnmi__pb2
+
+
+class gNMIStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.Capabilities = channel.unary_unary(
+                '/gnmi.gNMI/Capabilities',
+                request_serializer=gnmi__pb2.CapabilityRequest.SerializeToString,
+                response_deserializer=gnmi__pb2.CapabilityResponse.FromString,
+                )
+        self.Get = channel.unary_unary(
+                '/gnmi.gNMI/Get',
+                request_serializer=gnmi__pb2.GetRequest.SerializeToString,
+                response_deserializer=gnmi__pb2.GetResponse.FromString,
+                )
+        self.Set = channel.unary_unary(
+                '/gnmi.gNMI/Set',
+                request_serializer=gnmi__pb2.SetRequest.SerializeToString,
+                response_deserializer=gnmi__pb2.SetResponse.FromString,
+                )
+        self.Subscribe = channel.stream_stream(
+                '/gnmi.gNMI/Subscribe',
+                request_serializer=gnmi__pb2.SubscribeRequest.SerializeToString,
+                response_deserializer=gnmi__pb2.SubscribeResponse.FromString,
+                )
+
+
+class gNMIServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def Capabilities(self, request, context):
+        """Capabilities allows the client to retrieve the set of capabilities that
+        is supported by the target. This allows the target to validate the
+        service version that is implemented and retrieve the set of models that
+        the target supports. The models can then be specified in subsequent RPCs
+        to restrict the set of data that is utilized.
+        Reference: gNMI Specification Section 3.2
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Get(self, request, context):
+        """Retrieve a snapshot of data from the target. A Get RPC requests that the
+        target snapshots a subset of the data tree as specified by the paths
+        included in the message and serializes this to be returned to the
+        client using the specified encoding.
+        Reference: gNMI Specification Section 3.3
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Set(self, request, context):
+        """Set allows the client to modify the state of data on the target. The
+        paths to modified along with the new values that the client wishes
+        to set the value to.
+        Reference: gNMI Specification Section 3.4
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Subscribe(self, request_iterator, context):
+        """Subscribe allows a client to request the target to send it values
+        of particular paths within the data tree. These values may be streamed
+        at a particular cadence (STREAM), sent one off on a long-lived channel
+        (POLL), or sent as a one-off retrieval (ONCE).
+        Reference: gNMI Specification Section 3.5
+        """
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_gNMIServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'Capabilities': grpc.unary_unary_rpc_method_handler(
+                    servicer.Capabilities,
+                    request_deserializer=gnmi__pb2.CapabilityRequest.FromString,
+                    response_serializer=gnmi__pb2.CapabilityResponse.SerializeToString,
+            ),
+            'Get': grpc.unary_unary_rpc_method_handler(
+                    servicer.Get,
+                    request_deserializer=gnmi__pb2.GetRequest.FromString,
+                    response_serializer=gnmi__pb2.GetResponse.SerializeToString,
+            ),
+            'Set': grpc.unary_unary_rpc_method_handler(
+                    servicer.Set,
+                    request_deserializer=gnmi__pb2.SetRequest.FromString,
+                    response_serializer=gnmi__pb2.SetResponse.SerializeToString,
+            ),
+            'Subscribe': grpc.stream_stream_rpc_method_handler(
+                    servicer.Subscribe,
+                    request_deserializer=gnmi__pb2.SubscribeRequest.FromString,
+                    response_serializer=gnmi__pb2.SubscribeResponse.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'gnmi.gNMI', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class gNMI(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def Capabilities(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Capabilities',
+            gnmi__pb2.CapabilityRequest.SerializeToString,
+            gnmi__pb2.CapabilityResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Get(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Get',
+            gnmi__pb2.GetRequest.SerializeToString,
+            gnmi__pb2.GetResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Set(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/gnmi.gNMI/Set',
+            gnmi__pb2.SetRequest.SerializeToString,
+            gnmi__pb2.SetResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Subscribe(request_iterator,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.stream_stream(request_iterator, target, '/gnmi.gNMI/Subscribe',
+            gnmi__pb2.SubscribeRequest.SerializeToString,
+            gnmi__pb2.SubscribeResponse.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)