From 8f65918fa23fbe19796917affff3f18bec4c62ff Mon Sep 17 00:00:00 2001
From: hajipour <shajipour@cttc.es>
Date: Wed, 28 Feb 2024 12:29:12 +0000
Subject: [PATCH] service creation and deletion with webui added to pyangbind
 mode and tested

---
 .../drivers/openconfig/OpenConfigDriver.py    |   3 +
 .../VPN/Network_instance_multivendor.py       |   2 +-
 .../rest_server/nbi_plugins/etsi_bwm/Tools.py |  88 ++++++------
 .../l3nm_openconfig/ConfigRules.py            | 132 ++++++++++--------
 .../L3NMOpenConfigServiceHandler.py           |   6 +-
 5 files changed, 131 insertions(+), 100 deletions(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 99ae1c8db..452f2f7c8 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import time
 import json
 import anytree, copy, logging, pytz, queue, re, threading
 #import lxml.etree as ET
@@ -240,6 +241,8 @@ def edit_config(
                         test_option=test_option, error_option=error_option, format=format)
                     if commit_per_rule:
                         netconf_handler.commit()                                                                               # configuration commit
+                    if 'table_connections' in resource_key:
+                        time.sleep(5) # CPU usage might exceed critical level after route redistribution, BGP daemon needs time to reload
                 
                 #results[i] = True
                 results.append(True)
diff --git a/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py b/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py
index a8fc97cf9..13612b607 100644
--- a/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py
+++ b/src/device/service/drivers/openconfig/templates/VPN/Network_instance_multivendor.py
@@ -357,7 +357,7 @@ def create_table_conns(parameters,DEL):
                     with tag('table-connection','xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="delete"'):
                       with tag('src-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'):   text('oc-pol-types:',parameters['src_protocol'])
                       with tag('dst-protocol','xmlns:oc-pol-types="http://openconfig.net/yang/policy-types"'):   text('oc-pol-types:',parameters['dst_protocol'])
-                      with tag('address-family', 'xmlns:oc-types="http://openconfig.net/yang/openconfig-types"'):text('oc-types:',parameters['dst_protocol'])     
+                      with tag('address-family', 'xmlns:oc-types="http://openconfig.net/yang/openconfig-types"'):text('oc-types:',parameters['address_family'])     
             else:
                 with tag('table-connections'):
                     with tag('table-connection'):
diff --git a/src/nbi/service/rest_server/nbi_plugins/etsi_bwm/Tools.py b/src/nbi/service/rest_server/nbi_plugins/etsi_bwm/Tools.py
index 4b7ee7b39..f32fe5699 100644
--- a/src/nbi/service/rest_server/nbi_plugins/etsi_bwm/Tools.py
+++ b/src/nbi/service/rest_server/nbi_plugins/etsi_bwm/Tools.py
@@ -29,6 +29,7 @@ from common.tools.object_factory.Service import json_service_id
 LOGGER = logging.getLogger(__name__)
 
 ENDPOINT_SETTINGS_KEY = '/device[{:s}]/endpoint[{:s}]/vlan[{:d}]/settings'
+DEVICE_SETTINGS_KEY = '/device[{:s}]/settings'
 RE_CONFIG_RULE_IF_SUBIF = re.compile(r'^\/interface\[([^\]]+)\]\/subinterface\[([^\]]+)\]$')
 MEC_CONSIDERED_FIELDS = ['requestType', 'sessionFilter', 'fixedAllocation', 'allocationDirection']
 ALLOCATION_DIRECTION_DESCRIPTIONS = {
@@ -40,7 +41,11 @@ PREFIX_LENGTH = 24
 BGP_AS = 65000
 POLICY_AZ = 'srv_{:d}_a'.format(VLAN_TAG)
 POLICY_ZA = 'srv_{:d}_b'.format(VLAN_TAG)
-BGP_NETWORK_CIDR = '192.168.150.0/24'
+BGP_NEIGHBOR_IP_A = '192.168.150.1'
+BGP_NEIGHBOR_IP_Z = '192.168.150.2'
+ROUTER_ID_A = '200.1.1.1'
+ROUTER_ID_Z = '200.1.1.2'
+ROUTE_DISTINGUISHER = '{:5d}:{:03d}'.format(BGP_AS, VLAN_TAG)
 
 def service_2_bwInfo(service: Service) -> dict:
     response = {}
@@ -80,10 +85,6 @@ def bwInfo_2_service(client, bw_info: dict) -> Service:
     
     service_config_rules = service.service_config.config_rules
 
-    route_distinguisher = '{:5d}:{:03d}'.format(BGP_AS, VLAN_TAG)
-    settings_cr_key = '/settings'
-    settings_cr_value = {'bgp_as':(BGP_AS, True), 'route_distinguisher': (route_distinguisher, True)}
-    update_config_rule_custom(service_config_rules, settings_cr_key, settings_cr_value)
 
     request_cr_key = '/request'
     request_cr_value = {k:bw_info[k] for k in MEC_CONSIDERED_FIELDS}
@@ -101,9 +102,10 @@ def bwInfo_2_service(client, bw_info: dict) -> Service:
         z_ip = bw_info['sessionFilter']['dstAddress']
 
         devices = client.ListDevices(Empty()).devices
-        router_id_counter = 1
+        ip_interface_name_dict = {}
         for device in devices:
             device_endpoint_uuids = {ep.name:ep.endpoint_id.endpoint_uuid.uuid for ep in device.device_endpoints}
+            skip_device = True
             for cr in device.device_config.config_rules:
                 if cr.WhichOneof('config_rule') != 'custom':
                     continue
@@ -111,55 +113,59 @@ def bwInfo_2_service(client, bw_info: dict) -> Service:
                 if not match_subif:
                     continue
                 address_ip = json.loads(cr.custom.resource_value).get('address_ip')
+                short_port_name = match_subif.groups(0)[0]
+                ip_interface_name_dict[address_ip] = short_port_name
                 if address_ip not in [a_ip, z_ip]:
                     continue
-                port_name = 'PORT-' + match_subif.groups(0)[0] # `PORT-` added as prefix
+                port_name = 'PORT-' + short_port_name # `PORT-` added as prefix
                 ep_id = EndPointId()
                 ep_id.endpoint_uuid.uuid = device_endpoint_uuids[port_name]
                 ep_id.device_id.device_uuid.uuid = device.device_id.device_uuid.uuid
                 service.service_endpoint_ids.append(ep_id)
                 # add interface config rules
                 endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device.name, port_name, VLAN_TAG)
-                if address_ip == a_ip:
-                    field_updates = {
+                if address_ip in a_ip:
+                    router_id = ROUTER_ID_A
+                    policy_az = POLICY_AZ
+                    policy_za = POLICY_ZA
+                    neighbor_bgp_interface_address_ip = BGP_NEIGHBOR_IP_Z
+                    self_bgp_interface_address_ip = BGP_NEIGHBOR_IP_A
+                else:
+                    router_id = ROUTER_ID_Z
+                    policy_az = POLICY_ZA
+                    policy_za = POLICY_AZ
+                    neighbor_bgp_interface_address_ip= BGP_NEIGHBOR_IP_A
+                    self_bgp_interface_address_ip = BGP_NEIGHBOR_IP_Z
+                endpoint_field_updates = {
                     'address_ip': (address_ip, True),
-                    'router_id': ('200.1.1.1', True),
-                    'neighbor_address_ip': ('192.168.150.2', True),
-                    'self_bgp_interface_name': ('xe5', True),
-                    'self_bgp_interface_address_ip': ('192.168.150.1', True),
-                    'self_bgp_interface_address_prefix': (PREFIX_LENGTH, True),
-                    'self_bgp_sub_interface_index': (0, True),
-                    'route_distinguisher': (route_distinguisher, True),
-                    'sub_interface_index': (0, True),
-                    'bgp_as': (BGP_AS, True),
-                    'ip_address': (address_ip, True),
-                    'prefix_length': (PREFIX_LENGTH, True),
-                    'policy_AZ'           : (POLICY_AZ, True),
-                    'policy_ZA'           : (POLICY_ZA, True),
                     'address_prefix'     : (PREFIX_LENGTH, True),
-                        }
-                elif address_ip == z_ip:
-                    field_updates = {
-                    'address_ip': (address_ip, True),
-                    'router_id': ('200.1.1.2', True),
-                    'neighbor_address_ip': ('192.168.150.1', True),
-                    'self_bgp_interface_name': ('xe5', True),
-                    'self_bgp_interface_address_ip': ('192.168.150.2', True),
-                    'self_bgp_interface_address_prefix': (PREFIX_LENGTH, True),
-                    'self_bgp_sub_interface_index': (0, True),
-                    'route_distinguisher': (route_distinguisher, True),
                     'sub_interface_index': (0, True),
-                    'bgp_as': (BGP_AS, True),
-                    'ip_address': (address_ip, True),
-                    'prefix_length': (PREFIX_LENGTH, True),
-                    'policy_AZ'           : (POLICY_ZA, True),
-                    'policy_ZA'           : (POLICY_AZ, True),
-                    'address_prefix'     : (PREFIX_LENGTH, True),
                         }
-                router_id_counter += 1
                 LOGGER.debug(f'BEFORE UPDATE -> device.device_config.config_rules: {service_config_rules}')
-                update_config_rule_custom(service_config_rules, endpoint_settings_key, field_updates)
+                update_config_rule_custom(service_config_rules, endpoint_settings_key, endpoint_field_updates)
                 LOGGER.debug(f'AFTER UPDATE -> device.device_config.config_rules: {service_config_rules}')
+                skip_device = False
+            if skip_device:
+                continue
+            device_field_updates = {
+                         'bgp_as':(BGP_AS, True),
+                         'route_distinguisher': (ROUTE_DISTINGUISHER, True),
+                         'router_id': (router_id, True),
+                         'policy_AZ': (policy_az, True),
+                         'policy_ZA': (policy_za, True),
+                         'neighbor_bgp_interface_address_ip': (neighbor_bgp_interface_address_ip, True),
+                         'self_bgp_interface_name': (ip_interface_name_dict[self_bgp_interface_address_ip], True),
+                         'self_bgp_interface_address_ip': (self_bgp_interface_address_ip, True),
+                         'bgp_interface_address_prefix': (PREFIX_LENGTH, True)
+                        }
+            device_settings_key = DEVICE_SETTINGS_KEY.format(device.name)
+            LOGGER.debug(f'BEFORE UPDATE -> device.device_config.config_rules: {service_config_rules}')
+            update_config_rule_custom(service_config_rules, device_settings_key, device_field_updates)
+            LOGGER.debug(f'AFTER UPDATE -> device.device_config.config_rules: {service_config_rules}')
+    
+    settings_cr_key = '/settings'
+    settings_cr_value = {}
+    update_config_rule_custom(service_config_rules, settings_cr_key, settings_cr_value)
 
     service.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
     service.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
diff --git a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py
index 2f518d56a..cee44641a 100644
--- a/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py
+++ b/src/service/service/service_handlers/l3nm_openconfig/ConfigRules.py
@@ -18,29 +18,30 @@ from service.service.service_handler_api.AnyTreeTools import TreeNode
 
 def setup_config_rules(
     service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str,
-    service_settings : TreeNode, endpoint_settings : TreeNode, endpoint_acls : List [Tuple]
+    service_settings : TreeNode, endpoint_settings : TreeNode, endpoint_acls : List [Tuple], device_settings: TreeNode
 ) -> List[Dict]:
 
     if service_settings  is None: return []
     if endpoint_settings is None: return []
+    if device_settings is None: return []
 
     json_settings          : Dict = service_settings.value
     json_endpoint_settings : Dict = endpoint_settings.value
+    json_device_settings   : Dict = device_settings.value
 
     mtu                       = json_settings.get('mtu',                          1450     )  # 1512
     #address_families         = json_settings.get('address_families',             []       )  # ['IPV4']
-    bgp_as                    = json_settings.get('bgp_as',                       65000    )  # 65000
+    bgp_as                    = json_device_settings.get('bgp_as',                       65000    )  # 65000
 
-    router_id                 = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
-    route_distinguisher       = json_settings.get('route_distinguisher',          '65000:101'    )  # '60001:801'
+    router_id                 = json_device_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    route_distinguisher       = json_device_settings.get('route_distinguisher',          '65000:101'    )  # '60001:801'
     sub_interface_index       = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
     vlan_id                   = json_endpoint_settings.get('vlan_id',             1        )  # 400
     address_ip                = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
     address_prefix            = json_endpoint_settings.get('address_prefix',      24       )  # 30
-    neighbor_address_ip       = json_endpoint_settings.get('neighbor_address_ip',          '0.0.0.0')  # '2.2.2.1' 
 
-    policy_import             = json_endpoint_settings.get('policy_AZ',            '2'     )  # 2
-    policy_export             = json_endpoint_settings.get('policy_ZA',            '7'     )  # 30
+    policy_import             = json_device_settings.get('policy_AZ',            '2'     )  # 2
+    policy_export             = json_device_settings.get('policy_ZA',            '7'     )  # 30
     #network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
     network_interface_desc    = json_endpoint_settings.get('ni_description','')
     #network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
@@ -49,10 +50,11 @@ def setup_config_rules(
     #network_instance_name    = '{:s}-NetInst'.format(service_short_uuid)
     network_instance_name     = json_endpoint_settings.get('ni_name',          service_uuid.split('-')[-1])  #ELAN-AC:1
 
-    bgp_if_name = json_endpoint_settings.get('self_bgp_interface_name','')
-    bgp_address_ip = json_endpoint_settings.get('self_bgp_interface_address_ip','')
-    bgp_address_prefix = json_endpoint_settings.get('self_bgp_interface_address_prefix','')
-    bgp_sub_interface_index = json_endpoint_settings.get('self_bgp_sub_interface_index', 0        )
+    self_bgp_if_name          = json_device_settings.get('self_bgp_interface_name', '')
+    self_bgp_address_ip       = json_device_settings.get('self_bgp_interface_address_ip', '')
+    bgp_address_prefix        = json_device_settings.get('bgp_interface_address_prefix', '')
+    bgp_sub_interface_index   = json_device_settings.get('self_bgp_sub_interface_index', 0)
+    neighbor_bgp_if_address_ip= json_device_settings.get('neighbor_bgp_interface_address_ip', '0.0.0.0')  # '2.2.2.1' 
 
     # if_subif_name       = '{:s}.{:d}'.format(endpoint_name, 0)
     if_subif_name       = '{:s}'.format(endpoint_name[5:])
@@ -86,7 +88,7 @@ def setup_config_rules(
                 'type': 'L3VRF',
                 'as': bgp_as,
                 'router_id': router_id, 
-                'neighbors': [{'ip_address': neighbor_address_ip, 'remote_as': bgp_as}]
+                'neighbors': [{'ip_address': neighbor_bgp_if_address_ip, 'remote_as': bgp_as}]
         }),
 
         #Add DIRECTLY CONNECTED protocol to network instance
@@ -96,7 +98,6 @@ def setup_config_rules(
                 'identifier': 'DIRECTLY_CONNECTED', 
                 'protocol_name': 'DIRECTLY_CONNECTED',
         }),
-
         
         #Add STATIC protocol to network instance
         json_config_rule_set(
@@ -131,12 +132,12 @@ def setup_config_rules(
         }), 
 
         json_config_rule_set(
-            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, bgp_if_name), {
+            '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, self_bgp_if_name), {
                 'name'        : network_instance_name, 
-                'id'          : bgp_if_name, 
-                'interface'   : bgp_if_name,
+                'id'          : self_bgp_if_name, 
+                'interface'   : self_bgp_if_name,
                 'subinterface': bgp_sub_interface_index,
-                'address_ip'    : bgp_address_ip, 
+                'address_ip'    : self_bgp_address_ip, 
                 'address_prefix': bgp_address_prefix,
         }), 
 
@@ -215,76 +216,75 @@ def setup_config_rules(
 
 def teardown_config_rules(
     service_uuid : str, connection_uuid : str, device_uuid : str, endpoint_uuid : str, endpoint_name : str,
-    service_settings : TreeNode, endpoint_settings : TreeNode
+    service_settings : TreeNode, endpoint_settings : TreeNode, device_settings: TreeNode
 ) -> List[Dict]:
 
     if service_settings  is None: return []
     if endpoint_settings is None: return []
+    if device_settings is None: return []
 
     json_settings          : Dict = service_settings.value
     json_endpoint_settings : Dict = endpoint_settings.value
+    json_device_settings   : Dict = device_settings.value
 
     service_short_uuid        = service_uuid.split('-')[-1]
     # network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
     network_instance_name     = json_endpoint_settings.get('ni_name', service_short_uuid)  #ELAN-AC:1
     #network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
-    #network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+    # network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
+    network_subinterface_desc = ''
 
-    #mtu                 = json_settings.get('mtu',                          1450     )  # 1512
+    mtu                       = json_settings.get('mtu',                          1450     )  # 1512
     #address_families    = json_settings.get('address_families',             []       )  # ['IPV4']
-    #bgp_as              = json_settings.get('bgp_as',                       65000    )  # 65000
-    route_distinguisher = json_settings.get('route_distinguisher',          '0:0'    )  # '60001:801'
-    #sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
-    #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
-    vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
-    #address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
-    #address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
-    policy_import       = json_endpoint_settings.get('policy_AZ',            '2'      )  # 2
-    policy_export       = json_endpoint_settings.get('policy_ZA',            '7'      )  # 30
-
-    if_subif_name             = '{:s}.{:d}'.format(endpoint_name, vlan_id)
+    bgp_as                    = json_device_settings.get('bgp_as',                       65000    )  # 65000
+    route_distinguisher       = json_device_settings.get('route_distinguisher',          '0:0'    )  # '60001:801'
+    sub_interface_index       = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+    router_id                 = json_device_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+    vlan_id                   = json_endpoint_settings.get('vlan_id',             1        )  # 400
+    address_ip                = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+    address_prefix            = json_endpoint_settings.get('address_prefix',      24       )  # 30
+    policy_import             = json_device_settings.get('policy_AZ',            '2'      )  # 2
+    policy_export             = json_device_settings.get('policy_ZA',            '7'      )  # 30
 
-    json_config_rules = [
-        #Delete table connections
-        json_config_rule_delete(
-            '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(network_instance_name),{
-                'name'          : network_instance_name, 
-                'src_protocol'  : 'DIRECTLY_CONNECTED',
-                'dst_protocol'  : 'BGP',
-                'address_family': 'IPV4', 
-        }),
+    self_bgp_if_name          = json_device_settings.get('self_bgp_interface_name', '')
+    self_bgp_address_ip       = json_device_settings.get('self_bgp_interface_address_ip', '')
+    bgp_address_prefix        = json_device_settings.get('bgp_interface_address_prefix', '')
+    bgp_sub_interface_index   = json_device_settings.get('self_bgp_sub_interface_index', 0)
 
-        
-        json_config_rule_delete(
-            '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
-                'name'          : network_instance_name,
-                'src_protocol'  : 'STATIC',
-                'dst_protocol'  : 'BGP',
-                'address_family': 'IPV4',
-        }),
+    # if_subif_name             = '{:s}.{:d}'.format(endpoint_name, vlan_id)
+    if_subif_name             = '{:s}'.format(endpoint_name[5:])
 
+    json_config_rules = [
         #Delete export routing policy 
-
         json_config_rule_delete(
-            '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
-                'policy_name': '{:s}_export'.format(network_instance_name),
+            # pylint: disable=duplicate-string-formatting-argument
+            '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(policy_export, policy_export), {
+                'policy_name'           : policy_export,
+                'statement_name'        : 'stm_{:s}'.format(policy_export),
+                'ext_community_set_name': 'set_{:s}'.format(policy_export),
+                'policy_result'         : 'ACCEPT_ROUTE',
+                'sequence_id'           : '10'
         }),
         json_config_rule_delete(
             '/routing_policy/bgp_defined_set[{:s}_rt_export][{:s}]'.format(policy_export, route_distinguisher), {
                 'ext_community_set_name': 'set_{:s}'.format(policy_export),
+                'ext_community_member'  : route_distinguisher,
         }),
-
         #Delete import routing policy 
-
         json_config_rule_delete(
-            '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
-                'policy_name': '{:s}_import'.format(network_instance_name),
+            # pylint: disable=duplicate-string-formatting-argument
+            '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(policy_import, policy_import), {
+                'policy_name'           : policy_import,
+                'statement_name'        : 'stm_{:s}'.format(policy_import),
+                'ext_community_set_name': 'set_{:s}'.format(policy_import),
+                'policy_result'         : 'ACCEPT_ROUTE',
+                'sequence_id'           : '10'
         }),
         json_config_rule_delete(
             '/routing_policy/bgp_defined_set[{:s}_rt_import][{:s}]'.format(policy_import, route_distinguisher), {
                 'ext_community_set_name': 'set_{:s}'.format(policy_import),
+                'ext_community_member'  : route_distinguisher,
         }),
-
         #Delete interface; automatically deletes:
         # - /interface[]/subinterface[]
         # json_config_rule_delete('/interface[{:s}]/subinterface[0]'.format(if_subif_name),
@@ -296,6 +296,26 @@ def teardown_config_rules(
         # - /network_instance[]/interface[]
         # - /network_instance[]/protocols[]
         # - /network_instance[]/inter_instance_policies[]
+
+        #Associate interface to network instance
+        json_config_rule_set(
+            '/network_instance[{:s}]/interface[{:s}]'.format('default', if_subif_name), {
+                'name'        : 'default', 
+                'id'          : if_subif_name, 
+                'interface'   : if_subif_name,
+                'subinterface': sub_interface_index,
+                'address_ip'    : address_ip, 
+                'address_prefix': address_prefix,
+        }), 
+        json_config_rule_set(
+            '/network_instance[{:s}]/interface[{:s}]'.format('default', self_bgp_if_name), {
+                'name'        : 'default', 
+                'id'          : self_bgp_if_name, 
+                'interface'   : self_bgp_if_name,
+                'subinterface': bgp_sub_interface_index,
+                'address_ip'    : self_bgp_address_ip, 
+                'address_prefix': bgp_address_prefix,
+        }), 
         json_config_rule_delete('/network_instance[{:s}]'.format(network_instance_name),
         {
             'name': network_instance_name
diff --git a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
index 3f8a6d9dd..d061573db 100644
--- a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
+++ b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
@@ -52,6 +52,7 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                 device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint)
 
                 device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                device_settings = self.__settings_handler.get_device_settings(device_obj)
                 endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid)
                 endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj)
                 endpoint_acls = self.__settings_handler.get_endpoint_acls(device_obj, endpoint_obj)
@@ -59,7 +60,7 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
 
                 json_config_rules = setup_config_rules(
                     service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name,
-                    settings, endpoint_settings, endpoint_acls)
+                    settings, endpoint_settings, endpoint_acls, device_settings)
 
                 if len(json_config_rules) > 0:
                     del device_obj.device_config.config_rules[:]
@@ -90,13 +91,14 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                 device_uuid, endpoint_uuid = get_device_endpoint_uuids(endpoint)
 
                 device_obj = self.__task_executor.get_device(DeviceId(**json_device_id(device_uuid)))
+                device_settings = self.__settings_handler.get_device_settings(device_obj)
                 endpoint_obj = get_endpoint_matching(device_obj, endpoint_uuid)
                 endpoint_settings = self.__settings_handler.get_endpoint_settings(device_obj, endpoint_obj)
                 endpoint_name = endpoint_obj.name
 
                 json_config_rules = teardown_config_rules(
                     service_uuid, connection_uuid, device_uuid, endpoint_uuid, endpoint_name,
-                    settings, endpoint_settings)
+                    settings, endpoint_settings, device_settings)
 
                 if len(json_config_rules) > 0:
                     del device_obj.device_config.config_rules[:]
-- 
GitLab