diff --git a/adapters/adtran_olt/codec/ietf_interfaces.py b/adapters/adtran_olt/codec/ietf_interfaces.py
new file mode 100644
index 0000000..0bdf691
--- /dev/null
+++ b/adapters/adtran_olt/codec/ietf_interfaces.py
@@ -0,0 +1,328 @@
+# CCopyright 2017-present Adtran, Inc.
+#
+# 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.
+
+from twisted.internet.defer import inlineCallbacks, returnValue
+import xmltodict
+import structlog
+from pyvoltha.protos.openflow_13_pb2 import OFPPF_1GB_FD, OFPPF_10GB_FD, OFPPF_40GB_FD, OFPPF_100GB_FD
+from pyvoltha.protos.openflow_13_pb2 import OFPPF_FIBER, OFPPF_COPPER
+from pyvoltha.protos.openflow_13_pb2 import OFPPS_LIVE, OFPPC_PORT_DOWN, OFPPS_LINK_DOWN, OFPPF_OTHER
+from pyvoltha.protos.common_pb2 import OperStatus, AdminState
+
+log = structlog.get_logger()
+
+_ietf_interfaces_config_rpc = """
+    <filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface/>
+      </interfaces>
+    </filter>
+"""
+
+_ietf_interfaces_state_rpc = """
+    <filter xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
+      <interfaces-state xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
+        <interface>
+          <name/>
+          <type/>
+          <admin-status/>
+          <oper-status/>
+          <last-change/>
+          <phys-address/>
+          <speed/>
+        </interface>
+      </interfaces-state>
+    </filter>
+"""
+
+_allowed_with_default_types = ['report-all', 'report-all-tagged', 'trim', 'explicit']
+
+# TODO: Centralize the item below as a function in a core util module
+
+
+def _with_defaults(default_type=None):
+    if default_type is None:
+        return ""
+
+    assert(default_type in _allowed_with_default_types)
+    return """
+    <with-defaults xmlns="urn:ietf:params:xml:ns:yang:ietf-netconf-with-defaults">
+        {}</with-defaults>""".format(default_type)
+
+
+class IetfInterfacesConfig(object):
+    def __init__(self, session):
+        self._session = session
+
+    @inlineCallbacks
+    def get_config(self, source='running', with_defaults=None):
+
+        filter = _ietf_interfaces_config_rpc + _with_defaults(with_defaults)
+
+        request = self._session.get(source, filter=filter)
+        rpc_reply = yield request
+        returnValue(rpc_reply)
+
+    def get_interfaces(self, rpc_reply, interface_type=None):
+        """
+        Get the physical entities of a particular type
+        :param rpc_reply: Reply from previous get or request
+        :param interface_type: (String or List) The type of interface (case-insensitive)
+        :return: list) of OrderDict interface entries
+        """
+        result_dict = xmltodict.parse(rpc_reply.data_xml)
+
+        entries = result_dict['data']['interfaces']
+
+        if interface_type is None:
+            return entries
+
+        # for entry in entries:
+        #     import pprint
+        #     log.info(pprint.PrettyPrinter(indent=2).pformat(entry))
+
+        def _matches(entry, value):
+            if 'type' in entry and '#text' in entry['type']:
+                text_val = entry['type']['#text'].lower()
+                if isinstance(value, list):
+                    return any(v.lower() in text_val for v in value)
+                return value.lower() in text_val
+            return False
+
+        return [entry for entry in entries if _matches(entry, interface_type)]
+
+
+class IetfInterfacesState(object):
+    def __init__(self, session):
+        self._session = session
+
+    @inlineCallbacks
+    def get_state(self):
+        try:
+            request = self._session.get(_ietf_interfaces_state_rpc)
+            rpc_reply = yield request
+            returnValue(rpc_reply)
+
+        except Exception as e:
+            log.exception('get_state', e=e)
+            raise
+
+    @staticmethod
+    def get_interfaces(self, rpc_reply, key='type', key_value=None):
+        """
+        Get the physical entities of a particular type
+        :param key_value: (String or List) The type of interface (case-insensitive)
+        :return: list) of OrderDict interface entries
+        """
+        result_dict = xmltodict.parse(rpc_reply.data_xml)
+        entries = result_dict['data']['interfaces-state']['interface']
+
+        if key_value is None:
+            return entries
+
+        for entry in entries:
+            import pprint
+            log.info(pprint.PrettyPrinter(indent=2).pformat(entry))
+
+        def _matches(entry, key, value):
+            if key in entry and '#text' in entry[key]:
+                text_val = entry[key]['#text'].lower()
+                if isinstance(value, list):
+                    return any(v.lower() in text_val for v in value)
+                return value.lower() in text_val
+            return False
+
+        return [entry for entry in entries if _matches(entry, key, key_value)]
+
+    @staticmethod
+    def _get_admin_state(entry):
+        state_map = {
+            'up': AdminState.ENABLED,
+            'down': AdminState.DISABLED,
+            'testing': AdminState.DISABLED
+        }
+        return state_map.get(entry.get('admin-status', 'down'),
+                             AdminState.UNKNOWN)
+
+    @staticmethod
+    def _get_oper_status(entry):
+        state_map = {
+            'up': OperStatus.ACTIVE,
+            'down': OperStatus.FAILED,
+            'testing': OperStatus.TESTING,
+            'unknown': OperStatus.UNKNOWN,
+            'dormant': OperStatus.DISCOVERED,
+            'not-present': OperStatus.UNKNOWN,
+            'lower-layer-down': OperStatus.FAILED
+        }
+        return state_map.get(entry.get('oper-status', 'down'),
+                             OperStatus.UNKNOWN)
+
+    @staticmethod
+    def _get_mac_addr(entry):
+        mac_addr = entry.get('phys-address', None)
+        if mac_addr is None:
+            import random
+            # TODO: Get with qumram team about phys addr
+            mac_addr = '08:00:{}{}:{}{}:{}{}:00'.format(random.randint(0, 9),
+                                                        random.randint(0, 9),
+                                                        random.randint(0, 9),
+                                                        random.randint(0, 9),
+                                                        random.randint(0, 9),
+                                                        random.randint(0, 9))
+        return mac_addr
+
+    @staticmethod
+    def _get_speed_value(entry):
+        speed = entry.get('speed') or IetfInterfacesState._get_speed_via_name(entry.get('name'))
+        if isinstance(speed, str):
+            return long(speed)
+        return speed
+
+    @staticmethod
+    def _get_speed_via_name(name):
+        speed_map = {
+            'terabit':         1000000000000,
+            'hundred-gigabit':  100000000000,
+            'fourty-gigabit':    40000000000,
+            'ten-gigabit':       10000000000,
+            'gigabit':            1000000000,
+        }
+        for n,v in speed_map.iteritems():
+            if n in name.lower():
+                return v
+        return 0
+
+    @staticmethod
+    def _get_of_state(entry):
+        # If port up and ready: OFPPS_LIVE
+        # If port config bit is down: OFPPC_PORT_DOWN
+        # If port state bit is down: OFPPS_LINK_DOWN
+        # if IetfInterfacesState._get_admin_state(entry) == AdminState.ENABLED:
+        #     return OFPPS_LIVE \
+        #         if IetfInterfacesState._get_oper_status(entry) == OperStatus.ACTIVE \
+        #         else OFPPS_LINK_DOWN
+        #
+        # return OFPPC_PORT_DOWN
+        # TODO: Update of openflow port state is not supported, so always say we are alive
+        return OFPPS_LIVE
+
+    @staticmethod
+    def _get_of_capabilities(entry):
+        # The capabilities field is a bitmap that uses a combination of the following flags :
+        # Capabilities supported by the datapath
+        # enum ofp_capabilities {
+        #    OFPC_FLOW_STATS = 1 << 0,   /* Flow statistics. */
+        #    OFPC_TABLE_STATS = 1 << 1,  /* Table statistics. */
+        #    OFPC_PORT_STATS = 1 << 2,   /* Port statistics. */
+        #    OFPC_GROUP_STATS = 1 << 3,  /* Group statistics. */
+        #    OFPC_IP_REASM = 1 << 5,     /* Can reassemble IP fragments. */
+        #    OFPC_QUEUE_STATS = 1 << 6,  /* Queue statistics. */
+        #    OFPC_PORT_BLOCKED = 1 << 8, /* Switch will block looping ports. */
+        #    OFPC_BUNDLES = 1 << 9,      /* Switch supports bundles. */
+        #    OFPC_FLOW_MONITORING = 1 << 10, /* Switch supports flow monitoring. */
+        # }
+        # enum ofp_port_features {
+        #     OFPPF_10MB_HD = 1 << 0, /* 10 Mb half-duplex rate support. */
+        #     OFPPF_10MB_FD = 1 << 1, /* 10 Mb full-duplex rate support. */
+        #     OFPPF_100MB_HD = 1 << 2, /* 100 Mb half-duplex rate support. */
+        #     OFPPF_100MB_FD = 1 << 3, /* 100 Mb full-duplex rate support. */
+        #     OFPPF_1GB_HD = 1 << 4, /* 1 Gb half-duplex rate support. */
+        #     OFPPF_1GB_FD = 1 << 5, /* 1 Gb full-duplex rate support. */
+        #     OFPPF_10GB_FD = 1 << 6, /* 10 Gb full-duplex rate support. */
+        #     OFPPF_40GB_FD = 1 << 7, /* 40 Gb full-duplex rate support. */
+        #     OFPPF_100GB_FD = 1 << 8, /* 100 Gb full-duplex rate support. */
+        #     OFPPF_1TB_FD = 1 << 9, /* 1 Tb full-duplex rate support. */
+        #     OFPPF_OTHER = 1 << 10, /* Other rate, not in the list. */
+        #     OFPPF_COPPER = 1 << 11, /* Copper medium. */
+        #     OFPPF_FIBER = 1 << 12, /* Fiber medium. */
+        #     OFPPF_AUTONEG = 1 << 13, /* Auto-negotiation. */
+        #     OFPPF_PAUSE = 1 << 14, /* Pause. */
+        #     OFPPF_PAUSE_ASYM = 1 << 15 /* Asymmetric pause. */
+        # }
+        # TODO: Look into adtran-physical-entities and decode xSFP type any other settings
+        return IetfInterfacesState._get_of_speed(entry) | OFPPF_FIBER
+
+    @staticmethod
+    def _get_of_speed(entry):
+        speed = IetfInterfacesState._get_speed_value(entry)
+        speed_map = {
+            1000000000: OFPPF_1GB_FD,
+            10000000000: OFPPF_10GB_FD,
+            40000000000: OFPPF_40GB_FD,
+            100000000000: OFPPF_100GB_FD,
+        }
+        # return speed_map.get(speed, OFPPF_OTHER)
+        # TODO: For now, force 100 GB
+        return OFPPF_100GB_FD
+
+    @staticmethod
+    def _get_port_number(name, if_index):
+        import re
+
+        formats = [
+            'xpon \d/{1,2}\d',                          # OLT version 3 (Feb 2018++)
+            'Hundred-Gigabit-Ethernet \d/\d/{1,2}\d',   # OLT version 2
+            'XPON \d/\d/{1,2}\d',                       # OLT version 2
+            'hundred-gigabit-ethernet \d/{1,2}\d',      # OLT version 1
+            'channel-termination {1,2}\d',              # OLT version 1
+        ]
+        p2 = re.compile('\d+')
+
+        for regex in formats:
+            p = re.compile(regex, re.IGNORECASE)
+            match = p.match(name)
+            if match is not None:
+                return int(p2.findall(name)[-1])
+
+    @staticmethod
+    def get_port_entries(rpc_reply, port_type):
+        """
+        Get the port entries that make up the northbound and
+        southbound interfaces
+
+        :param rpc_reply:
+        :param port_type:
+        :return:
+        """
+        ports = dict()
+        result_dict = xmltodict.parse(rpc_reply.data_xml)
+        entries = result_dict['data']['interfaces-state']['interface']
+        if not isinstance(entries, list):
+            entries = [entries]
+        port_entries = [entry for entry in entries if 'name' in entry and
+                        port_type.lower() in entry['name'].lower()]
+
+        for entry in port_entries:
+            port = {
+                'port_no': IetfInterfacesState._get_port_number(entry.get('name'),
+                                                                entry.get('ifindex')),
+                'name': entry.get('name', 'unknown'),
+                'ifIndex': entry.get('ifIndex'),
+                # 'label': None,
+                'mac_address': IetfInterfacesState._get_mac_addr(entry),
+                'admin_state': IetfInterfacesState._get_admin_state(entry),
+                'oper_status': IetfInterfacesState._get_oper_status(entry),
+                'ofp_state': IetfInterfacesState._get_of_state(entry),
+                'ofp_capabilities': IetfInterfacesState._get_of_capabilities(entry),
+                'current_speed': IetfInterfacesState._get_of_speed(entry),
+                'max_speed': IetfInterfacesState._get_of_speed(entry),
+            }
+            port_no = port['port_no']
+            if port_no not in ports:
+                ports[port_no] = port
+            else:
+                ports[port_no].update(port)
+
+        return ports
