diff --git a/install_requirements.sh b/install_requirements.sh
index 74db1cb342862d08653bab4ac81edbd4f63d4e8f..c59ea7f13909c789fef587192a56876187eb4195 100755
--- a/install_requirements.sh
+++ b/install_requirements.sh
@@ -24,6 +24,22 @@ ALL_COMPONENTS="${ALL_COMPONENTS} dbscanserving opticalattackmitigator opticalat
 ALL_COMPONENTS="${ALL_COMPONENTS} l3_attackmitigator l3_centralizedattackdetector l3_distributedattackdetector"
 TFS_COMPONENTS=${TFS_COMPONENTS:-$ALL_COMPONENTS}
 
+# Some components require libyang built from source code
+# - Ref: https://github.com/CESNET/libyang
+# - Ref: https://github.com/CESNET/libyang-python/
+echo "Installing libyang..."
+sudo apt-get --yes --quiet --quiet update
+sudo apt-get --yes --quiet --quiet install build-essential cmake libpcre2-dev python3-dev python3-cffi
+mkdir libyang
+git clone https://github.com/CESNET/libyang.git libyang
+mkdir libyang/build
+cd libyang/build
+cmake -D CMAKE_BUILD_TYPE:String="Release" ..
+make
+sudo make install
+sudo ldconfig
+cd ../..
+
 echo "Updating PIP, SetupTools and Wheel..."
 pip install --upgrade pip               # ensure next packages get the latest versions
 pip install --upgrade setuptools wheel  # bring basic tooling for other requirements
diff --git a/scripts/run_tests_locally-nbi-ietf-l3vpn.sh b/scripts/run_tests_locally-nbi-ietf-l3vpn.sh
new file mode 100755
index 0000000000000000000000000000000000000000..0bd133e16caac438c8da1a5795fce89e99230c9a
--- /dev/null
+++ b/scripts/run_tests_locally-nbi-ietf-l3vpn.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+# 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.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+# helpful pytest flags: --log-level=INFO -o log_cli=true --verbose --maxfail=1 --durations=0
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    nbi/tests/test_ietf_l3vpn.py
diff --git a/src/nbi/.gitlab-ci.yml b/src/nbi/.gitlab-ci.yml
index 47bd5bcbca76ee62079c68b531e3bf0ab3f4cb4f..8f7f4d6f45d7e4a07856aaf1d67d35d9f76a38cf 100644
--- a/src/nbi/.gitlab-ci.yml
+++ b/src/nbi/.gitlab-ci.yml
@@ -68,6 +68,7 @@ unit_test nbi:
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_l2vpn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_l2vpn.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_network.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_network.xml"
+    - docker exec -i $IMAGE_NAME bash -c "coverage run --append -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_ietf_l3vpn.py --junitxml=/opt/results/${IMAGE_NAME}_report_ietf_l3vpn.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
diff --git a/src/nbi/Dockerfile b/src/nbi/Dockerfile
index 31b826e0133158e694efe4ded76e105d008f8e2e..eda4d295697e94b659f67d75025d1944db703afc 100644
--- a/src/nbi/Dockerfile
+++ b/src/nbi/Dockerfile
@@ -53,6 +53,21 @@ RUN python3 -m grpc_tools.protoc -I=. --python_out=. --grpc_python_out=. *.proto
 RUN rm *.proto
 RUN find . -type f -exec sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' {} \;
 
+# Download, build and install libyang. Note that APT package is outdated
+# - Ref: https://github.com/CESNET/libyang
+# - Ref: https://github.com/CESNET/libyang-python/
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install build-essential cmake libpcre2-dev python3-dev python3-cffi && \
+    rm -rf /var/lib/apt/lists/*
+RUN mkdir -p /var/libyang
+RUN git clone https://github.com/CESNET/libyang.git /var/libyang
+RUN mkdir -p /var/libyang/build
+WORKDIR /var/libyang/build
+RUN cmake -D CMAKE_BUILD_TYPE:String="Release" ..
+RUN make
+RUN make install
+RUN ldconfig
+
 # Create component sub-folders, get specific Python packages
 RUN mkdir -p /var/teraflow/nbi
 WORKDIR /var/teraflow/nbi
diff --git a/src/nbi/README.md b/src/nbi/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..c5ed72704b7d6048d3829eb8f77710e51753b000
--- /dev/null
+++ b/src/nbi/README.md
@@ -0,0 +1,32 @@
+# NBI Component
+
+The NBI component uses libyang to validate and process messages. Follow instructions below to install it.
+
+## Install libyang
+- Ref: https://github.com/CESNET/libyang
+- Ref: https://github.com/CESNET/libyang-python/
+
+__NOTE__: APT package is extremely outdated and does not work for our purposes.
+
+### Build Requisites
+```bash
+sudo apt-get install build-essential cmake libpcre2-dev
+sudo apt-get install python3-dev gcc python3-cffi
+```
+
+### Build from source
+```bash
+mkdir ~/tfs-ctrl/libyang
+git clone https://github.com/CESNET/libyang.git ~/tfs-ctrl/libyang
+mkdir ~/tfs-ctrl/libyang/build
+cd ~/tfs-ctrl/libyang/build
+cmake -D CMAKE_BUILD_TYPE:String="Release" ..
+make
+sudo make install
+sudo ldconfig
+```
+
+### Install Python bindings
+```bash
+pip install libyang==2.8.0
+```
diff --git a/src/nbi/requirements.in b/src/nbi/requirements.in
index a1da58d01b4d0647a668a584e6388ee167210f6b..52094c61f2b50e99a35a8ca999c579422b7f22b7 100644
--- a/src/nbi/requirements.in
+++ b/src/nbi/requirements.in
@@ -17,6 +17,8 @@ Flask==2.1.3
 Flask-HTTPAuth==4.5.0
 Flask-RESTful==0.3.9
 jsonschema==4.4.0
+libyang==2.8.0
+netaddr==0.9.0
 pyang==2.6.0
 git+https://github.com/robshakir/pyangbind.git
 requests==2.27.1
diff --git a/src/nbi/service/__main__.py b/src/nbi/service/__main__.py
index 07cc9193d35b2669c2b4daa8189e5ef520d05248..8834e45a2779c8d422ba1f9878c435f14a2f43db 100644
--- a/src/nbi/service/__main__.py
+++ b/src/nbi/service/__main__.py
@@ -23,6 +23,7 @@ from .rest_server.RestServer import RestServer
 from .rest_server.nbi_plugins.debug_api import register_debug_api
 from .rest_server.nbi_plugins.etsi_bwm import register_etsi_bwm_api
 from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
+from .rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn
 from .rest_server.nbi_plugins.ietf_network import register_ietf_network
 from .rest_server.nbi_plugins.ietf_network_slice import register_ietf_nss
 
@@ -64,6 +65,7 @@ def main():
     register_debug_api(rest_server)
     register_etsi_bwm_api(rest_server)
     register_ietf_l2vpn(rest_server)  # Registering L2VPN entrypoint
+    register_ietf_l3vpn(rest_server)  # Registering L3VPN entrypoint
     register_ietf_network(rest_server)
     register_ietf_nss(rest_server)  # Registering NSS entrypoint
     rest_server.start()
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py
new file mode 100644
index 0000000000000000000000000000000000000000..8490eb91581dc80f837e2baec851553560fc9deb
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/Handlers.py
@@ -0,0 +1,195 @@
+# 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, netaddr
+from typing import Dict, List, Optional, Tuple
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import Service, ServiceStatusEnum
+from common.tools.context_queries.Service import get_service_by_uuid
+from common.tools.grpc.ConfigRules import update_config_rule_custom
+from common.tools.grpc.Constraints import (
+    update_constraint_endpoint_location, update_constraint_sla_availability, update_constraint_sla_capacity,
+    update_constraint_sla_latency
+)
+from common.tools.grpc.EndPointIds import update_endpoint_ids
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+
+LOGGER = logging.getLogger(__name__)
+
+def create_service(
+    service_uuid : str, context_uuid : Optional[str] = DEFAULT_CONTEXT_NAME
+) -> Optional[Exception]:
+    # pylint: disable=no-member
+    service_request = Service()
+    service_request.service_id.context_id.context_uuid.uuid = context_uuid
+    service_request.service_id.service_uuid.uuid = service_uuid
+    service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+
+    try:
+        service_client = ServiceClient()
+        service_client.CreateService(service_request)
+        return None
+    except Exception as e: # pylint: disable=broad-except
+        LOGGER.exception('Unhandled exception creating Service')
+        return e
+
+def process_vpn_service(
+    vpn_service : Dict, errors : List[Dict]
+) -> None:
+    vpn_id = vpn_service['vpn-id']
+    exc = create_service(vpn_id)
+    if exc is not None: errors.append({'error': str(exc)})
+
+def update_service_endpoint(
+    service_uuid : str, site_id : str, device_uuid : str, endpoint_uuid : str,
+    vlan_tag : int, ipv4_address : str, ipv4_prefix_length : int,
+    capacity_gbps : Optional[float] = None, e2e_latency_ms : Optional[float] = None,
+    availability : Optional[float] = None, mtu : Optional[int] = None,
+    context_uuid : Optional[str] = DEFAULT_CONTEXT_NAME, 
+) -> Optional[Exception]:
+    context_client = ContextClient()
+    service = get_service_by_uuid(context_client, service_uuid, context_uuid=context_uuid, rw_copy=True)
+    if service is None: raise Exception('VPN({:s}) not found in database'.format(str(service_uuid)))
+
+    endpoint_ids = service.service_endpoint_ids
+    endpoint_id =  update_endpoint_ids(endpoint_ids, device_uuid, endpoint_uuid)
+
+    constraints  = service.service_constraints
+    update_constraint_endpoint_location(constraints, endpoint_id, region=site_id)
+    if capacity_gbps  is not None: update_constraint_sla_capacity    (constraints, capacity_gbps)
+    if e2e_latency_ms is not None: update_constraint_sla_latency     (constraints, e2e_latency_ms)
+    if availability   is not None: update_constraint_sla_availability(constraints, 1, True, availability)
+
+    config_rules = service.service_config.config_rules
+
+    service_settings_key = '/settings'
+    service_settings = {'address_families': (['IPV4'], True)}
+    if mtu is not None: service_settings['mtu'] = (mtu, True)
+    update_config_rule_custom(config_rules, service_settings_key, service_settings)
+
+    ENDPOINT_SETTINGS_KEY = '/device[{:s}]/endpoint[{:s}]/vlan[{:d}]/settings'
+    endpoint_settings_key = ENDPOINT_SETTINGS_KEY.format(device_uuid, endpoint_uuid, vlan_tag)
+    field_updates = {}
+    if vlan_tag           is not None: field_updates['vlan_tag'     ] = (vlan_tag,           True)
+    if ipv4_address       is not None: field_updates['ip_address'   ] = (ipv4_address,       True)
+    if ipv4_prefix_length is not None: field_updates['prefix_length'] = (ipv4_prefix_length, True)
+    update_config_rule_custom(config_rules, endpoint_settings_key, field_updates)
+
+    try:
+        service_client = ServiceClient()
+        service_client.UpdateService(service)
+        return None
+    except Exception as e: # pylint: disable=broad-except
+        LOGGER.exception('Unhandled exception updating Service')
+        return e
+
+def process_site_network_access(
+    site_id : str, network_access : Dict, site_static_routing : Dict[Tuple[str, str], str], errors : List[Dict]
+) -> None:
+    endpoint_uuid = network_access['site-network-access-id']
+
+    if network_access['site-network-access-type'] != 'ietf-l3vpn-svc:multipoint':
+        MSG = 'Site Network Access Type: {:s}'
+        raise NotImplementedError(MSG.format(str(network_access['site-network-access-type'])))
+
+    device_uuid  = network_access['device-reference']
+    service_uuid = network_access['vpn-attachment']['vpn-id']
+    
+    access_role : str = network_access['vpn-attachment']['site-role']
+    access_role = access_role.replace('ietf-l3vpn-svc:', '').replace('-role', '') # hub/spoke
+    if access_role not in {'hub', 'spoke'}:
+        MSG = 'Site VPN Attackment Role: {:s}'
+        raise NotImplementedError(MSG.format(str(network_access['site-network-access-type'])))
+
+    ipv4_allocation = network_access['ip-connection']['ipv4']
+    if ipv4_allocation['address-allocation-type'] != 'ietf-l3vpn-svc:static-address':
+        MSG = 'Site Network Access IPv4 Allocation Type: {:s}'
+        raise NotImplementedError(MSG.format(str(ipv4_allocation['address-allocation-type'])))
+    ipv4_allocation_addresses = ipv4_allocation['addresses']
+    ipv4_provider_address = ipv4_allocation_addresses['provider-address']
+    #ipv4_customer_address = ipv4_allocation_addresses['customer-address']
+    ipv4_prefix_length    = ipv4_allocation_addresses['prefix-length'   ]
+
+    vlan_tag = None
+    ipv4_provider_range = netaddr.IPNetwork('{:s}/{:d}'.format(ipv4_provider_address, ipv4_prefix_length))
+    for (_, _, lan_tag), next_hop in site_static_routing.items():
+        ip_next_hop = netaddr.IPAddress(next_hop)
+        if ip_next_hop not in ipv4_provider_range: continue
+        vlan_tag = lan_tag
+        break
+
+    ## network_access_static_routing: (lan-range, lan-prefix-len, lan-tag) => next-hop
+    #network_access_static_routing : Dict[Tuple[str, str], str] = {}
+    #for rt_proto in network_access['routing-protocols']['routing-protocol']:
+    #    if rt_proto['type'] != 'ietf-l3vpn-svc:static':
+    #        MSG = 'Site Network Access Routing Protocol Type: {:s}'
+    #        raise NotImplementedError(MSG.format(str(rt_proto['type'])))
+    #    for ipv4_rt in rt_proto['static']['cascaded-lan-prefixes']['ipv4-lan-prefixes']:
+    #        lan_range, lan_prefix = ipv4_rt['lan'].split('/')
+    #        lan_prefix = int(lan_prefix)
+    #        lan_tag   = int(ipv4_rt['lan-tag'].replace('vlan', ''))
+    #        next_hop  = ipv4_rt['next-hop']
+    #        network_access_static_routing[(lan_range, lan_prefix, lan_tag)] = next_hop
+
+    service_mtu              = network_access['service']['svc-mtu']
+    service_input_bandwidth  = network_access['service']['svc-input-bandwidth']
+    service_output_bandwidth = network_access['service']['svc-output-bandwidth']
+    service_bandwidth_bps    = max(service_input_bandwidth, service_output_bandwidth)
+    service_bandwidth_gbps   = service_bandwidth_bps / 1.e9
+
+    max_e2e_latency_ms = None
+    availability       = None
+    for qos_profile_class in network_access['service']['qos']['qos-profile']['classes']['class']:
+        if qos_profile_class['class-id'] != 'qos-realtime':
+            MSG = 'Site Network Access QoS Class Id: {:s}'
+            raise NotImplementedError(MSG.format(str(qos_profile_class['class-id'])))
+
+        if qos_profile_class['direction'] != 'ietf-l3vpn-svc:both':
+            MSG = 'Site Network Access QoS Class Direction: {:s}'
+            raise NotImplementedError(MSG.format(str(qos_profile_class['direction'])))
+
+        max_e2e_latency_ms = qos_profile_class['latency']['latency-boundary']
+        availability       = qos_profile_class['bandwidth']['guaranteed-bw-percent']
+
+    exc = update_service_endpoint(
+        service_uuid, site_id, device_uuid, endpoint_uuid, vlan_tag, ipv4_provider_address, ipv4_prefix_length,
+        capacity_gbps=service_bandwidth_gbps, e2e_latency_ms=max_e2e_latency_ms, availability=availability,
+        mtu=service_mtu
+    )
+    if exc is not None: errors.append({'error': str(exc)})
+
+def process_site(site : Dict, errors : List[Dict]) -> None:
+    site_id = site['site-id']
+
+    if site['management']['type'] != 'ietf-l3vpn-svc:provider-managed':
+        MSG = 'Site Management Type: {:s}'
+        raise NotImplementedError(MSG.format(str(site['management']['type'])))
+
+    # site_static_routing: (lan-range, lan-prefix-len, lan-tag) => next-hop
+    site_static_routing : Dict[Tuple[str, str], str] = {}
+    for rt_proto in site['routing-protocols']['routing-protocol']:
+        if rt_proto['type'] != 'ietf-l3vpn-svc:static':
+            MSG = 'Site Routing Protocol Type: {:s}'
+            raise NotImplementedError(MSG.format(str(rt_proto['type'])))
+        for ipv4_rt in rt_proto['static']['cascaded-lan-prefixes']['ipv4-lan-prefixes']:
+            lan_range, lan_prefix = ipv4_rt['lan'].split('/')
+            lan_prefix = int(lan_prefix)
+            lan_tag   = int(ipv4_rt['lan-tag'].replace('vlan', ''))
+            next_hop  = ipv4_rt['next-hop']
+            site_static_routing[(lan_range, lan_prefix, lan_tag)] = next_hop
+
+    network_accesses : List[Dict] = site['site-network-accesses']['site-network-access']
+    for network_access in network_accesses:
+        process_site_network_access(site_id, network_access, site_static_routing, errors)
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py
new file mode 100644
index 0000000000000000000000000000000000000000..470ff0add7a42ff027f3c6fe95426653aee214a4
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Service.py
@@ -0,0 +1,78 @@
+# 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
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from common.proto.context_pb2 import ServiceStatusEnum
+from common.tools.context_queries.Service import get_service_by_uuid
+from context.client.ContextClient import ContextClient
+from service.client.ServiceClient import ServiceClient
+from ..tools.Authentication import HTTP_AUTH
+from ..tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR
+
+LOGGER = logging.getLogger(__name__)
+
+class L3VPN_Service(Resource):
+    @HTTP_AUTH.login_required
+    def get(self, vpn_id : str):
+        LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
+        LOGGER.debug('Request: {:s}'.format(str(request)))
+
+        try:
+            context_client = ContextClient()
+
+            target = get_service_by_uuid(context_client, vpn_id, rw_copy=True)
+            if target is None:
+                raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
+
+            service_ids = {target.service_id.service_uuid.uuid, target.name} # pylint: disable=no-member
+            if vpn_id not in service_ids:
+                raise Exception('Service retrieval failed. Wrong Service Id was returned')
+
+            service_ready_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
+            service_status = target.service_status.service_status # pylint: disable=no-member
+            response = jsonify({})
+            response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT
+        except Exception as e: # pylint: disable=broad-except
+            LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(vpn_id)))
+            response = jsonify({'error': str(e)})
+            response.status_code = HTTP_SERVERERROR
+        return response
+
+    @HTTP_AUTH.login_required
+    def delete(self, vpn_id : str):
+        LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
+        LOGGER.debug('Request: {:s}'.format(str(request)))
+
+        try:
+            context_client = ContextClient()
+
+            target = get_service_by_uuid(context_client, vpn_id)
+            if target is None:
+                LOGGER.warning('VPN({:s}) not found in database. Nothing done.'.format(str(vpn_id)))
+            else:
+                service_ids = {target.service_id.service_uuid.uuid, target.name} # pylint: disable=no-member
+                if vpn_id not in service_ids:
+                    raise Exception('Service retrieval failed. Wrong Service Id was returned')
+                service_client = ServiceClient()
+                service_client.DeleteService(target.service_id)
+            response = jsonify({})
+            response.status_code = HTTP_NOCONTENT
+        except Exception as e: # pylint: disable=broad-except
+            LOGGER.exception('Something went wrong Deleting VPN({:s})'.format(str(vpn_id)))
+            response = jsonify({'error': str(e)})
+            response.status_code = HTTP_SERVERERROR
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py
new file mode 100644
index 0000000000000000000000000000000000000000..13d5c532478e93ef1bd3b1c644d7f3c3ba927af5
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_Services.py
@@ -0,0 +1,53 @@
+# 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
+from typing import Dict
+from flask import request
+from flask.json import jsonify
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+from nbi.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR
+from nbi.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH
+from .Handlers import process_site, process_vpn_service
+from .YangValidator import YangValidator
+
+LOGGER = logging.getLogger(__name__)
+
+class L3VPN_Services(Resource):
+    @HTTP_AUTH.login_required
+    def get(self):
+        return {}
+
+    @HTTP_AUTH.login_required
+    def post(self):
+        if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
+        request_data : Dict = request.json
+        LOGGER.debug('Request: {:s}'.format(str(request_data)))
+
+        yang_validator = YangValidator('ietf-l3vpn-svc')
+        request_data = yang_validator.parse_to_dict(request_data)
+        yang_validator.destroy()
+
+        errors = []
+
+        for vpn_service in request_data['l3vpn-svc']['vpn-services']['vpn-service']:
+            process_vpn_service(vpn_service, errors)
+
+        for site in request_data['l3vpn-svc']['sites']['site']:
+            process_site(site, errors)
+
+        response = jsonify(errors)
+        response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR
+        return response
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_SiteNetworkAccesses.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_SiteNetworkAccesses.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd0334789af67bb2b9e7083a3794dbd3a7c948df
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/L3VPN_SiteNetworkAccesses.py
@@ -0,0 +1,58 @@
+# 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
+from typing import Dict
+from flask import request
+from flask.json import jsonify
+from flask.wrappers import Response
+from flask_restful import Resource
+from werkzeug.exceptions import UnsupportedMediaType
+from nbi.service.rest_server.nbi_plugins.tools.Authentication import HTTP_AUTH
+from nbi.service.rest_server.nbi_plugins.tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR
+from .Handlers import process_site_network_access
+from .YangValidator import YangValidator
+
+LOGGER = logging.getLogger(__name__)
+
+def process_site_network_accesses(site_id : str) -> Response:
+    if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
+    request_data : Dict = request.json
+    LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
+    LOGGER.debug('Request: {:s}'.format(str(request_data)))
+
+    yang_validator = YangValidator('ietf-l3vpn-svc')
+    request_data = yang_validator.parse_to_dict(request_data)
+    yang_validator.destroy()
+
+    # TODO: retrieve site static routing from service
+    site_static_routing = dict()
+
+    errors = []
+    for network_access in request_data['site-network-accesses']['site-network-access']:
+        exc = process_site_network_access(site_id, network_access, site_static_routing, errors)
+        if exc is not None: errors.append({'error': str(exc)})
+
+    response = jsonify(errors)
+    response.status_code = HTTP_CREATED if len(errors) == 0 else HTTP_SERVERERROR
+    return response
+
+class L3VPN_SiteNetworkAccesses(Resource):
+    @HTTP_AUTH.login_required
+    def post(self, site_id : str):
+        return process_site_network_accesses(site_id)
+
+    @HTTP_AUTH.login_required
+    def put(self, site_id : str):
+        return process_site_network_accesses(site_id)
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/YangValidator.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/YangValidator.py
new file mode 100644
index 0000000000000000000000000000000000000000..d267640dd43d3400517c488c65ae786422c073bc
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/YangValidator.py
@@ -0,0 +1,36 @@
+# 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 libyang, os
+from typing import Dict, Optional
+
+YANG_DIR = os.path.join(os.path.dirname(__file__), 'yang')
+
+class YangValidator:
+    def __init__(self, module_name : str) -> None:
+        self._yang_context = libyang.Context(YANG_DIR)
+        self._yang_module  = self._yang_context.load_module(module_name)
+        self._yang_module.feature_enable_all()
+
+    def parse_to_dict(self, message : Dict) -> Dict:
+        dnode : Optional[libyang.DNode] = self._yang_module.parse_data_dict(
+            message, validate_present=True, validate=True, strict=True
+        )
+        if dnode is None: raise Exception('Unable to parse Message({:s})'.format(str(message)))
+        message = dnode.print_dict()
+        dnode.free()
+        return message
+
+    def destroy(self) -> None:
+        self._yang_context.destroy()
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/__init__.py b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..454e10b841eed19a1837762825b4fd61ae21e4c4
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/__init__.py
@@ -0,0 +1,41 @@
+# 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.
+
+# RFC 8299 - YANG Data Model for L3VPN Service Delivery
+# Ref: https://datatracker.ietf.org/doc/rfc8299
+
+from flask_restful import Resource
+from nbi.service.rest_server.RestServer import RestServer
+from .L3VPN_Services import L3VPN_Services
+from .L3VPN_Service import L3VPN_Service
+from .L3VPN_SiteNetworkAccesses import L3VPN_SiteNetworkAccesses
+
+URL_PREFIX = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc'
+
+def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs):
+    urls = [(URL_PREFIX + url) for url in urls]
+    rest_server.add_resource(resource, *urls, **kwargs)
+
+def register_ietf_l3vpn(rest_server : RestServer):
+    _add_resource(rest_server, L3VPN_Services,
+        '/vpn-services',
+    )
+    _add_resource(rest_server, L3VPN_Service,
+        '/vpn-services/vpn-service=<vpn_id>',
+        '/vpn-services/vpn-service=<vpn_id>/',
+    )
+    _add_resource(rest_server, L3VPN_SiteNetworkAccesses,
+        '/sites/site=<site_id>/site-network-accesses',
+        '/sites/site=<site_id>/site-network-accesses/',
+    )
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-inet-types@2013-07-15.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-inet-types@2013-07-15.yang
new file mode 100644
index 0000000000000000000000000000000000000000..790bafc31dd7dc3582ef1c765fe104145b8a6016
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-inet-types@2013-07-15.yang
@@ -0,0 +1,459 @@
+   module ietf-inet-types {
+
+     namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+     prefix "inet";
+
+     organization
+      "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+     contact
+      "WG Web:   <http://tools.ietf.org/wg/netmod/>
+       WG List:  <mailto:netmod@ietf.org>
+
+       WG Chair: David Kessens
+                 <mailto:david.kessens@nsn.com>
+
+       WG Chair: Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>
+
+       Editor:   Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>";
+
+     description
+      "This module contains a collection of generally useful derived
+       YANG data types for Internet addresses and related things.
+
+       Copyright (c) 2013 IETF Trust and the persons identified as
+       authors of the code.  All rights reserved.
+
+       Redistribution and use in source and binary forms, with or
+       without modification, is permitted pursuant to, and subject
+       to the license terms contained in, the Simplified BSD License
+       set forth in Section 4.c of the IETF Trust's Legal Provisions
+       Relating to IETF Documents
+       (http://trustee.ietf.org/license-info).
+
+       This version of this YANG module is part of RFC 6991; see
+       the RFC itself for full legal notices.";
+
+     revision 2013-07-15 {
+       description
+        "This revision adds the following new data types:
+         - ip-address-no-zone
+         - ipv4-address-no-zone
+         - ipv6-address-no-zone";
+       reference
+        "RFC 6991: Common YANG Data Types";
+     }
+
+     revision 2010-09-24 {
+       description
+        "Initial revision.";
+       reference
+        "RFC 6021: Common YANG Data Types";
+     }
+
+     /*** collection of types related to protocol fields ***/
+
+     typedef ip-version {
+       type enumeration {
+         enum unknown {
+           value "0";
+           description
+            "An unknown or unspecified version of the Internet
+             protocol.";
+         }
+         enum ipv4 {
+           value "1";
+           description
+            "The IPv4 protocol as defined in RFC 791.";
+         }
+         enum ipv6 {
+           value "2";
+           description
+            "The IPv6 protocol as defined in RFC 2460.";
+         }
+       }
+       description
+        "This value represents the version of the IP protocol.
+
+         In the value set and its semantics, this type is equivalent
+         to the InetVersion textual convention of the SMIv2.";
+       reference
+        "RFC  791: Internet Protocol
+         RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+         RFC 4001: Textual Conventions for Internet Network Addresses";
+     }
+
+     typedef dscp {
+       type uint8 {
+         range "0..63";
+       }
+       description
+        "The dscp type represents a Differentiated Services Code Point
+         that may be used for marking packets in a traffic stream.
+
+         In the value set and its semantics, this type is equivalent
+         to the Dscp textual convention of the SMIv2.";
+       reference
+        "RFC 3289: Management Information Base for the Differentiated
+                   Services Architecture
+         RFC 2474: Definition of the Differentiated Services Field
+                   (DS Field) in the IPv4 and IPv6 Headers
+         RFC 2780: IANA Allocation Guidelines For Values In
+                   the Internet Protocol and Related Headers";
+     }
+
+     typedef ipv6-flow-label {
+       type uint32 {
+         range "0..1048575";
+       }
+       description
+        "The ipv6-flow-label type represents the flow identifier or Flow
+         Label in an IPv6 packet header that may be used to
+         discriminate traffic flows.
+
+         In the value set and its semantics, this type is equivalent
+         to the IPv6FlowLabel textual convention of the SMIv2.";
+       reference
+        "RFC 3595: Textual Conventions for IPv6 Flow Label
+         RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+     }
+
+     typedef port-number {
+       type uint16 {
+         range "0..65535";
+       }
+       description
+        "The port-number type represents a 16-bit port number of an
+         Internet transport-layer protocol such as UDP, TCP, DCCP, or
+         SCTP.  Port numbers are assigned by IANA.  A current list of
+         all assignments is available from <http://www.iana.org/>.
+
+         Note that the port number value zero is reserved by IANA.  In
+         situations where the value zero does not make sense, it can
+         be excluded by subtyping the port-number type.
+         In the value set and its semantics, this type is equivalent
+         to the InetPortNumber textual convention of the SMIv2.";
+       reference
+        "RFC  768: User Datagram Protocol
+         RFC  793: Transmission Control Protocol
+         RFC 4960: Stream Control Transmission Protocol
+         RFC 4340: Datagram Congestion Control Protocol (DCCP)
+         RFC 4001: Textual Conventions for Internet Network Addresses";
+     }
+
+     /*** collection of types related to autonomous systems ***/
+
+     typedef as-number {
+       type uint32;
+       description
+        "The as-number type represents autonomous system numbers
+         which identify an Autonomous System (AS).  An AS is a set
+         of routers under a single technical administration, using
+         an interior gateway protocol and common metrics to route
+         packets within the AS, and using an exterior gateway
+         protocol to route packets to other ASes.  IANA maintains
+         the AS number space and has delegated large parts to the
+         regional registries.
+
+         Autonomous system numbers were originally limited to 16
+         bits.  BGP extensions have enlarged the autonomous system
+         number space to 32 bits.  This type therefore uses an uint32
+         base type without a range restriction in order to support
+         a larger autonomous system number space.
+
+         In the value set and its semantics, this type is equivalent
+         to the InetAutonomousSystemNumber textual convention of
+         the SMIv2.";
+       reference
+        "RFC 1930: Guidelines for creation, selection, and registration
+                   of an Autonomous System (AS)
+         RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+         RFC 4001: Textual Conventions for Internet Network Addresses
+         RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+                   Number Space";
+     }
+
+     /*** collection of types related to IP addresses and hostnames ***/
+
+     typedef ip-address {
+       type union {
+         type inet:ipv4-address;
+         type inet:ipv6-address;
+       }
+       description
+        "The ip-address type represents an IP address and is IP
+         version neutral.  The format of the textual representation
+         implies the IP version.  This type supports scoped addresses
+         by allowing zone identifiers in the address format.";
+       reference
+        "RFC 4007: IPv6 Scoped Address Architecture";
+     }
+
+     typedef ipv4-address {
+       type string {
+         pattern
+           '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+         +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+         + '(%[\p{N}\p{L}]+)?';
+       }
+       description
+         "The ipv4-address type represents an IPv4 address in
+          dotted-quad notation.  The IPv4 address may include a zone
+          index, separated by a % sign.
+
+          The zone index is used to disambiguate identical address
+          values.  For link-local addresses, the zone index will
+          typically be the interface index number or the name of an
+          interface.  If the zone index is not present, the default
+          zone of the device will be used.
+
+          The canonical format for the zone index is the numerical
+          format";
+     }
+
+     typedef ipv6-address {
+       type string {
+         pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+               + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+               + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+               + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+               + '(%[\p{N}\p{L}]+)?';
+         pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+               + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+               + '(%.+)?';
+       }
+       description
+        "The ipv6-address type represents an IPv6 address in full,
+         mixed, shortened, and shortened-mixed notation.  The IPv6
+         address may include a zone index, separated by a % sign.
+
+         The zone index is used to disambiguate identical address
+         values.  For link-local addresses, the zone index will
+         typically be the interface index number or the name of an
+         interface.  If the zone index is not present, the default
+         zone of the device will be used.
+
+         The canonical format of IPv6 addresses uses the textual
+         representation defined in Section 4 of RFC 5952.  The
+         canonical format for the zone index is the numerical
+         format as described in Section 11.2 of RFC 4007.";
+       reference
+        "RFC 4291: IP Version 6 Addressing Architecture
+         RFC 4007: IPv6 Scoped Address Architecture
+         RFC 5952: A Recommendation for IPv6 Address Text
+                   Representation";
+     }
+
+     typedef ip-address-no-zone {
+       type union {
+         type inet:ipv4-address-no-zone;
+         type inet:ipv6-address-no-zone;
+       }
+       description
+        "The ip-address-no-zone type represents an IP address and is
+         IP version neutral.  The format of the textual representation
+         implies the IP version.  This type does not support scoped
+         addresses since it does not allow zone identifiers in the
+         address format.";
+       reference
+        "RFC 4007: IPv6 Scoped Address Architecture";
+     }
+
+     typedef ipv4-address-no-zone {
+       type inet:ipv4-address {
+         pattern '[0-9\.]*';
+       }
+       description
+         "An IPv4 address without a zone index.  This type, derived from
+          ipv4-address, may be used in situations where the zone is
+          known from the context and hence no zone index is needed.";
+     }
+
+     typedef ipv6-address-no-zone {
+       type inet:ipv6-address {
+         pattern '[0-9a-fA-F:\.]*';
+       }
+       description
+         "An IPv6 address without a zone index.  This type, derived from
+          ipv6-address, may be used in situations where the zone is
+          known from the context and hence no zone index is needed.";
+       reference
+        "RFC 4291: IP Version 6 Addressing Architecture
+         RFC 4007: IPv6 Scoped Address Architecture
+         RFC 5952: A Recommendation for IPv6 Address Text
+                   Representation";
+     }
+
+     typedef ip-prefix {
+       type union {
+         type inet:ipv4-prefix;
+         type inet:ipv6-prefix;
+       }
+       description
+        "The ip-prefix type represents an IP prefix and is IP
+         version neutral.  The format of the textual representations
+         implies the IP version.";
+     }
+
+     typedef ipv4-prefix {
+       type string {
+         pattern
+            '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+          +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+          + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+       }
+       description
+        "The ipv4-prefix type represents an IPv4 address prefix.
+         The prefix length is given by the number following the
+         slash character and must be less than or equal to 32.
+
+         A prefix length value of n corresponds to an IP address
+         mask that has n contiguous 1-bits from the most
+         significant bit (MSB) and all other bits set to 0.
+
+         The canonical format of an IPv4 prefix has all bits of
+         the IPv4 address set to zero that are not part of the
+         IPv4 prefix.";
+     }
+
+     typedef ipv6-prefix {
+       type string {
+         pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+               + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+               + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+               + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+               + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+         pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+               + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+               + '(/.+)';
+       }
+
+       description
+        "The ipv6-prefix type represents an IPv6 address prefix.
+         The prefix length is given by the number following the
+         slash character and must be less than or equal to 128.
+
+         A prefix length value of n corresponds to an IP address
+         mask that has n contiguous 1-bits from the most
+         significant bit (MSB) and all other bits set to 0.
+
+         The IPv6 address should have all bits that do not belong
+         to the prefix set to zero.
+
+         The canonical format of an IPv6 prefix has all bits of
+         the IPv6 address set to zero that are not part of the
+         IPv6 prefix.  Furthermore, the IPv6 address is represented
+         as defined in Section 4 of RFC 5952.";
+       reference
+        "RFC 5952: A Recommendation for IPv6 Address Text
+                   Representation";
+     }
+
+     /*** collection of domain name and URI types ***/
+
+     typedef domain-name {
+       type string {
+         pattern
+           '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+         + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+         + '|\.';
+         length "1..253";
+       }
+       description
+        "The domain-name type represents a DNS domain name.  The
+         name SHOULD be fully qualified whenever possible.
+
+         Internet domain names are only loosely specified.  Section
+         3.5 of RFC 1034 recommends a syntax (modified in Section
+         2.1 of RFC 1123).  The pattern above is intended to allow
+         for current practice in domain name use, and some possible
+         future expansion.  It is designed to hold various types of
+         domain names, including names used for A or AAAA records
+         (host names) and other records, such as SRV records.  Note
+         that Internet host names have a stricter syntax (described
+         in RFC 952) than the DNS recommendations in RFCs 1034 and
+         1123, and that systems that want to store host names in
+         schema nodes using the domain-name type are recommended to
+         adhere to this stricter standard to ensure interoperability.
+
+         The encoding of DNS names in the DNS protocol is limited
+         to 255 characters.  Since the encoding consists of labels
+         prefixed by a length bytes and there is a trailing NULL
+         byte, only 253 characters can appear in the textual dotted
+         notation.
+
+         The description clause of schema nodes using the domain-name
+         type MUST describe when and how these names are resolved to
+         IP addresses.  Note that the resolution of a domain-name value
+         may require to query multiple DNS records (e.g., A for IPv4
+         and AAAA for IPv6).  The order of the resolution process and
+         which DNS record takes precedence can either be defined
+         explicitly or may depend on the configuration of the
+         resolver.
+
+         Domain-name values use the US-ASCII encoding.  Their canonical
+         format uses lowercase US-ASCII characters.  Internationalized
+         domain names MUST be A-labels as per RFC 5890.";
+       reference
+        "RFC  952: DoD Internet Host Table Specification
+         RFC 1034: Domain Names - Concepts and Facilities
+         RFC 1123: Requirements for Internet Hosts -- Application
+                   and Support
+         RFC 2782: A DNS RR for specifying the location of services
+                   (DNS SRV)
+         RFC 5890: Internationalized Domain Names in Applications
+                   (IDNA): Definitions and Document Framework";
+     }
+
+     typedef host {
+       type union {
+         type inet:ip-address;
+         type inet:domain-name;
+       }
+       description
+        "The host type represents either an IP address or a DNS
+         domain name.";
+     }
+
+     typedef uri {
+       type string;
+       description
+        "The uri type represents a Uniform Resource Identifier
+         (URI) as defined by STD 66.
+
+         Objects using the uri type MUST be in US-ASCII encoding,
+         and MUST be normalized as described by RFC 3986 Sections
+         6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+         percent-encoding is removed, and all case-insensitive
+         characters are set to lowercase except for hexadecimal
+         digits, which are normalized to uppercase as described in
+         Section 6.2.2.1.
+
+         The purpose of this normalization is to help provide
+         unique URIs.  Note that this normalization is not
+         sufficient to provide uniqueness.  Two URIs that are
+         textually distinct after this normalization may still be
+         equivalent.
+
+         Objects using the uri type may restrict the schemes that
+         they permit.  For example, 'data:' and 'urn:' schemes
+         might not be appropriate.
+
+         A zero-length URI is not a valid URI.  This can be used to
+         express 'URI absent' where required.
+
+         In the value set and its semantics, this type is equivalent
+         to the Uri SMIv2 textual convention defined in RFC 5017.";
+       reference
+        "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+         RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                   Group: Uniform Resource Identifiers (URIs), URLs,
+                   and Uniform Resource Names (URNs): Clarifications
+                   and Recommendations
+         RFC 5017: MIB Textual Conventions for Uniform Resource
+                   Identifiers (URIs)";
+     }
+
+   }
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-l3vpn-svc@2018-01-19.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-l3vpn-svc@2018-01-19.yang
new file mode 100644
index 0000000000000000000000000000000000000000..e05e33722f01fc9af9cbeb07092dc6287e8dc6c4
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-l3vpn-svc@2018-01-19.yang
@@ -0,0 +1,2856 @@
+ module ietf-l3vpn-svc {
+  yang-version 1.1;
+  namespace "urn:ietf:params:xml:ns:yang:ietf-l3vpn-svc";
+  prefix l3vpn-svc;
+  import ietf-inet-types {
+   prefix inet;
+  }
+  import ietf-yang-types {
+   prefix yang;
+  }
+  import ietf-netconf-acm {
+   prefix nacm;
+  }
+  organization
+   "IETF L3SM Working Group";
+  contact
+   "WG List: <mailto:l3sm@ietf.org>
+    Editor:
+     L3SM WG
+    Chairs:
+     Adrian Farrel, Qin Wu
+   ";
+  description
+  "This YANG module defines a generic service configuration
+  model for Layer 3 VPNs. This model is common across all
+  vendor implementations.
+
+
+
+
+  Copyright (c) 2018 IETF Trust and the persons
+  identified as authors of the code.  All rights reserved.
+
+  Redistribution and use in source and binary forms, with or
+  without modification, is permitted pursuant to, and subject
+  to the license terms contained in, the Simplified BSD License
+  set forth in Section 4.c of the IETF Trust's Legal Provisions
+  Relating to IETF Documents
+  (https://trustee.ietf.org/license-info).
+
+  This version of this YANG module is part of RFC 8299; see
+  the RFC itself for full legal notices.";
+
+  revision 2018-01-19 {
+   description
+    "Revision of RFC 8049 to fix implementation issues.";
+   reference
+    "RFC 8299";
+   }
+  revision 2017-01-27 {
+   description
+   "Initial document.";
+   reference
+     "RFC 8049.";
+   }
+  /* Features */
+  feature cloud-access {
+   description
+   "Allows the VPN to connect to a CSP.";
+  }
+  feature multicast {
+   description
+   "Enables multicast capabilities in a VPN.";
+  }
+  feature ipv4 {
+   description
+   "Enables IPv4 support in a VPN.";
+  }
+  feature ipv6 {
+   description
+   "Enables IPv6 support in a VPN.";
+  }
+  feature lan-tag {
+   description
+   "Enables LAN Tag support in a VPN Policy filter.";
+  }
+  feature carrierscarrier {
+   description
+
+   "Enables support of CsC.";
+  }
+  feature extranet-vpn {
+   description
+   "Enables support of extranet VPNs.";
+  }
+  feature site-diversity {
+   description
+   "Enables support of site diversity constraints.";
+  }
+  feature encryption {
+   description
+   "Enables support of encryption.";
+  }
+  feature qos {
+   description
+   "Enables support of classes of services.";
+  }
+  feature qos-custom {
+   description
+   "Enables support of the custom QoS profile.";
+  }
+  feature rtg-bgp {
+   description
+   "Enables support of the BGP routing protocol.";
+  }
+  feature rtg-rip {
+   description
+   "Enables support of the RIP routing protocol.";
+  }
+  feature rtg-ospf {
+   description
+   "Enables support of the OSPF routing protocol.";
+  }
+  feature rtg-ospf-sham-link {
+   description
+   "Enables support of OSPF sham links.";
+  }
+  feature rtg-vrrp {
+   description
+   "Enables support of the VRRP routing protocol.";
+  }
+  feature fast-reroute {
+   description
+   "Enables support of Fast Reroute.";
+  }
+  feature bfd {
+   description
+
+   "Enables support of BFD.";
+  }
+  feature always-on {
+   description
+   "Enables support of the 'always-on' access constraint.";
+  }
+  feature requested-type {
+   description
+   "Enables support of the 'requested-type' access constraint.";
+  }
+  feature bearer-reference {
+   description
+   "Enables support of the 'bearer-reference' access constraint.";
+  }
+  feature target-sites {
+   description
+   "Enables support of the 'target-sites' match flow parameter.";
+  }
+  /* Typedefs */
+  typedef svc-id {
+   type string;
+   description
+   "Defines a type of service component identifier.";
+  }
+  typedef template-id {
+   type string;
+   description
+   "Defines a type of service template identifier.";
+  }
+  typedef address-family {
+   type enumeration {
+    enum ipv4 {
+     description
+     "IPv4 address family.";
+    }
+    enum ipv6 {
+     description
+     "IPv6 address family.";
+    }
+   }
+   description
+   "Defines a type for the address family.";
+  }
+  /* Identities */
+  identity site-network-access-type {
+   description
+   "Base identity for site-network-access type.";
+  }
+
+  identity point-to-point {
+   base site-network-access-type;
+   description
+   "Identity for point-to-point connection.";
+  }
+  identity multipoint {
+   base site-network-access-type;
+   description
+   "Identity for multipoint connection.
+   Example: Ethernet broadcast segment.";
+  }
+  identity placement-diversity {
+   description
+   "Base identity for site placement constraints.";
+  }
+  identity bearer-diverse {
+   base placement-diversity;
+   description
+   "Identity for bearer diversity.
+   The bearers should not use common elements.";
+  }
+  identity pe-diverse {
+   base placement-diversity;
+   description
+   "Identity for PE diversity.";
+  }
+  identity pop-diverse {
+   base placement-diversity;
+   description
+   "Identity for POP diversity.";
+  }
+  identity linecard-diverse {
+   base placement-diversity;
+   description
+   "Identity for linecard diversity.";
+  }
+  identity same-pe {
+   base placement-diversity;
+   description
+   "Identity for having sites connected on the same PE.";
+  }
+  identity same-bearer {
+   base placement-diversity;
+   description
+   "Identity for having sites connected using the same bearer.";
+  }
+  identity customer-application {
+   description
+
+   "Base identity for customer application.";
+  }
+  identity web {
+   base customer-application;
+   description
+   "Identity for Web application (e.g., HTTP, HTTPS).";
+  }
+  identity mail {
+   base customer-application;
+   description
+   "Identity for mail application.";
+  }
+  identity file-transfer {
+   base customer-application;
+   description
+   "Identity for file transfer application (e.g., FTP, SFTP).";
+  }
+  identity database {
+   base customer-application;
+   description
+   "Identity for database application.";
+  }
+  identity social {
+   base customer-application;
+   description
+   "Identity for social-network application.";
+  }
+  identity games {
+   base customer-application;
+   description
+   "Identity for gaming application.";
+  }
+  identity p2p {
+   base customer-application;
+   description
+   "Identity for peer-to-peer application.";
+  }
+  identity network-management {
+   base customer-application;
+   description
+   "Identity for management application
+   (e.g., Telnet, syslog, SNMP).";
+  }
+  identity voice {
+   base customer-application;
+   description
+   "Identity for voice application.";
+  }
+
+  identity video {
+   base customer-application;
+   description
+   "Identity for video conference application.";
+  }
+  identity embb {
+   base customer-application;
+   description
+   "Identity for an enhanced Mobile Broadband (eMBB)
+   application.  Note that an eMBB application demands
+   network performance with a wide variety of
+   characteristics, such as data rate, latency,
+   loss rate, reliability, and many other parameters.";
+ }
+ identity urllc {
+   base customer-application;
+   description
+   "Identity for an Ultra-Reliable and Low Latency
+   Communications (URLLC) application.  Note that a
+   URLLC application demands network performance
+   with a wide variety of characteristics, such as latency,
+   reliability, and many other parameters.";
+  }
+  identity mmtc {
+    base customer-application;
+    description
+    "Identity for a massive Machine Type
+    Communications (mMTC) application.  Note that an
+    mMTC application demands network performance
+    with a wide variety of characteristics, such as data
+    rate, latency, loss rate, reliability, and many
+    other parameters.";
+  }
+  identity site-vpn-flavor {
+   description
+   "Base identity for the site VPN service flavor.";
+  }
+  identity site-vpn-flavor-single {
+   base site-vpn-flavor;
+   description
+   "Base identity for the site VPN service flavor.
+   Used when the site belongs to only one VPN.";
+  }
+  identity site-vpn-flavor-multi {
+   base site-vpn-flavor;
+   description
+   "Base identity for the site VPN service flavor.
+   Used when a logical connection of a site
+
+   belongs to multiple VPNs.";
+  }
+  identity site-vpn-flavor-sub {
+   base site-vpn-flavor;
+   description
+   "Base identity for the site VPN service flavor.
+   Used when a site has multiple logical connections.
+   Each connection may belong to different multiple VPNs.";
+  }
+  identity site-vpn-flavor-nni {
+   base site-vpn-flavor;
+   description
+   "Base identity for the site VPN service flavor.
+   Used to describe an NNI option A connection.";
+  }
+  identity management {
+   description
+   "Base identity for site management scheme.";
+  }
+  identity co-managed {
+   base management;
+   description
+   "Base identity for co-managed site.";
+  }
+  identity customer-managed {
+   base management;
+   description
+   "Base identity for customer-managed site.";
+  }
+  identity provider-managed {
+   base management;
+   description
+   "Base identity for provider-managed site.";
+  }
+  identity address-allocation-type {
+   description
+   "Base identity for address-allocation-type for PE-CE link.";
+  }
+  identity provider-dhcp {
+   base address-allocation-type;
+   description
+   "Provider network provides DHCP service to customer.";
+  }
+  identity provider-dhcp-relay {
+   base address-allocation-type;
+   description
+   "Provider network provides DHCP relay service to customer.";
+  }
+
+  identity provider-dhcp-slaac {
+   base address-allocation-type;
+   description
+   "Provider network provides DHCP service to customer,
+   as well as SLAAC.";
+  }
+  identity static-address {
+   base address-allocation-type;
+   description
+   "Provider-to-customer addressing is static.";
+  }
+  identity slaac {
+   base address-allocation-type;
+   description
+   "Use IPv6 SLAAC.";
+  }
+  identity site-role {
+   description
+   "Base identity for site type.";
+  }
+  identity any-to-any-role {
+   base site-role;
+   description
+   "Site in an any-to-any IP VPN.";
+  }
+  identity spoke-role {
+   base site-role;
+   description
+   "Spoke site in a Hub-and-Spoke IP VPN.";
+  }
+  identity hub-role {
+   base site-role;
+   description
+   "Hub site in a Hub-and-Spoke IP VPN.";
+  }
+  identity vpn-topology {
+   description
+   "Base identity for VPN topology.";
+  }
+  identity any-to-any {
+   base vpn-topology;
+   description
+   "Identity for any-to-any VPN topology.";
+  }
+  identity hub-spoke {
+   base vpn-topology;
+   description
+   "Identity for Hub-and-Spoke VPN topology.";
+
+  }
+  identity hub-spoke-disjoint {
+   base vpn-topology;
+   description
+   "Identity for Hub-and-Spoke VPN topology
+   where Hubs cannot communicate with each other.";
+  }
+  identity multicast-tree-type {
+   description
+   "Base identity for multicast tree type.";
+  }
+  identity ssm-tree-type {
+   base multicast-tree-type;
+   description
+   "Identity for SSM tree type.";
+  }
+  identity asm-tree-type {
+   base multicast-tree-type;
+   description
+   "Identity for ASM tree type.";
+  }
+  identity bidir-tree-type {
+   base multicast-tree-type;
+   description
+   "Identity for bidirectional tree type.";
+  }
+  identity multicast-rp-discovery-type {
+   description
+   "Base identity for RP discovery type.";
+  }
+  identity auto-rp {
+   base multicast-rp-discovery-type;
+   description
+   "Base identity for Auto-RP discovery type.";
+  }
+  identity static-rp {
+   base multicast-rp-discovery-type;
+   description
+   "Base identity for static type.";
+  }
+  identity bsr-rp {
+   base multicast-rp-discovery-type;
+   description
+   "Base identity for BSR discovery type.";
+  }
+  identity routing-protocol-type {
+   description
+   "Base identity for routing protocol type.";
+
+  }
+  identity ospf {
+   base routing-protocol-type;
+   description
+   "Identity for OSPF protocol type.";
+  }
+  identity bgp {
+   base routing-protocol-type;
+   description
+   "Identity for BGP protocol type.";
+  }
+  identity static {
+   base routing-protocol-type;
+   description
+   "Identity for static routing protocol type.";
+  }
+  identity rip {
+   base routing-protocol-type;
+   description
+   "Identity for RIP protocol type.";
+  }
+  identity vrrp {
+   base routing-protocol-type;
+   description
+   "Identity for VRRP protocol type.
+   This is to be used when LANs are directly connected
+   to PE routers.";
+  }
+  identity direct {
+   base routing-protocol-type;
+   description
+   "Identity for direct protocol type.";
+  }
+  identity protocol-type {
+   description
+   "Base identity for protocol field type.";
+  }
+  identity tcp {
+   base protocol-type;
+   description
+   "TCP protocol type.";
+  }
+  identity udp {
+   base protocol-type;
+   description
+   "UDP protocol type.";
+  }
+
+
+  identity icmp {
+   base protocol-type;
+   description
+   "ICMP protocol type.";
+  }
+  identity icmp6 {
+   base protocol-type;
+   description
+   "ICMPv6 protocol type.";
+  }
+  identity gre {
+   base protocol-type;
+   description
+   "GRE protocol type.";
+  }
+  identity ipip {
+   base protocol-type;
+   description
+   "IP-in-IP protocol type.";
+  }
+  identity hop-by-hop {
+   base protocol-type;
+   description
+   "Hop-by-Hop IPv6 header type.";
+  }
+  identity routing {
+   base protocol-type;
+   description
+   "Routing IPv6 header type.";
+  }
+  identity esp {
+   base protocol-type;
+   description
+   "ESP header type.";
+  }
+  identity ah {
+   base protocol-type;
+   description
+   "AH header type.";
+  }
+  identity vpn-policy-filter-type {
+   description
+   "Base identity for VPN Policy filter type.";
+  }
+  identity ipv4 {
+    base vpn-policy-filter-type;
+    description
+    "Identity for IPv4 Prefix filter type.";
+
+  }
+  identity ipv6 {
+    base vpn-policy-filter-type;
+    description
+    "Identity for IPv6 Prefix filter type.";
+ }
+  identity lan {
+    base vpn-policy-filter-type;
+    description
+    "Identity for LAN Tag filter type.";
+ }
+
+  identity qos-profile-direction {
+   description
+   "Base identity for QoS profile direction.";
+  }
+
+  identity site-to-wan {
+    base qos-profile-direction;
+    description
+    "Identity for Site-to-WAN direction.";
+  }
+  identity wan-to-site {
+    base qos-profile-direction;
+    description
+    "Identity for WAN-to-Site direction.";
+  }
+  identity both {
+    base qos-profile-direction;
+    description
+    "Identity for both WAN-to-Site direction
+    and Site-to-WAN direction.";
+  }
+  /* Groupings */
+  grouping vpn-service-cloud-access {
+   container cloud-accesses {
+    if-feature cloud-access;
+    list cloud-access {
+     key cloud-identifier;
+     leaf cloud-identifier {
+      type leafref {
+       path "/l3vpn-svc/vpn-profiles/"+
+       "valid-provider-identifiers/cloud-identifier/id";
+      }
+      description
+      "Identification of cloud service.
+      Local administration meaning.";
+     }
+
+     choice list-flavor {
+      case permit-any {
+       leaf permit-any {
+        type empty;
+        description
+        "Allows all sites.";
+       }
+      }
+      case deny-any-except {
+       leaf-list permit-site {
+        type leafref {
+         path "/l3vpn-svc/sites/site/site-id";
+        }
+        description
+        "Site ID to be authorized.";
+       }
+      }
+      case permit-any-except {
+       leaf-list deny-site {
+        type leafref {
+        path "/l3vpn-svc/sites/site/site-id";
+       }
+       description
+       "Site ID to be denied.";
+       }
+      }
+      description
+      "Choice for cloud access policy.  By
+      default, all sites in the IP VPN MUST
+      be authorized to access the cloud.";
+     }
+     container address-translation {
+      container nat44 {
+       leaf enabled {
+        type boolean;
+         default false;
+         description
+         "Controls whether or not Network address
+         translation from IPv4 to IPv4 (NAT44)
+         [RFC3022] is required.";
+       }
+       leaf nat44-customer-address {
+        type inet:ipv4-address;
+         description
+         "Address to be used for network address
+         translation from IPv4 to IPv4.  This is
+         to be used if the customer is providing
+         the IPv4 address.  If the customer address
+
+         is not set, the model assumes that the
+         provider will allocate the address.";
+       }
+       description
+       "IPv4-to-IPv4 translation.";
+      }
+      description
+      "Container for NAT.";
+     }
+     description
+     "Cloud access configuration.";
+    }
+    description
+    "Container for cloud access configurations.";
+   }
+   description
+   "Grouping for VPN cloud definition.";
+  }
+  grouping multicast-rp-group-cfg {
+   choice group-format {
+    mandatory true;
+    case singleaddress {
+     leaf group-address {
+      type inet:ip-address;
+      description
+      "A single multicast group address.";
+     }
+    }
+    case startend {
+     leaf group-start {
+      type inet:ip-address;
+      description
+      "The first multicast group address in
+      the multicast group address range.";
+     }
+     leaf group-end {
+      type inet:ip-address;
+      description
+      "The last multicast group address in
+      the multicast group address range.";
+     }
+    }
+    description
+    "Choice for multicast group format.";
+   }
+   description
+   "This grouping defines multicast group or
+   multicast groups for RP-to-group mapping.";
+
+  }
+  grouping vpn-service-multicast {
+   container multicast {
+    if-feature multicast;
+    leaf enabled {
+     type boolean;
+     default false;
+     description
+     "Enables multicast.";
+    }
+    container customer-tree-flavors {
+     leaf-list tree-flavor {
+      type identityref {
+       base multicast-tree-type;
+      }
+      description
+       "Type of tree to be used.";
+     }
+     description
+     "Type of trees used by customer.";
+    }
+    container rp {
+     container rp-group-mappings {
+      list rp-group-mapping {
+       key id;
+       leaf id {
+        type uint16;
+        description
+        "Unique identifier for the mapping.";
+       }
+       container provider-managed {
+        leaf enabled {
+         type boolean;
+         default false;
+         description
+         "Set to true if the Rendezvous Point (RP)
+         must be a provider-managed node.  Set to false
+         if it is a customer-managed node.";
+        }
+        leaf rp-redundancy {
+         type boolean;
+         default false;
+         description
+         "If true, a redundancy mechanism for the RP
+         is required.";
+        }
+        leaf optimal-traffic-delivery {
+         type boolean;
+
+         default false;
+         description
+         "If true, the SP must ensure that
+         traffic uses an optimal path.  An SP may use
+         Anycast RP or RP-tree-to-SPT switchover
+         architectures.";
+        }
+        description
+        "Parameters for a provider-managed RP.";
+       }
+       leaf rp-address {
+        when "../provider-managed/enabled = 'false'" {
+         description
+         "Relevant when the RP is not provider-managed.";
+        }
+        type inet:ip-address;
+          mandatory true;
+        description
+        "Defines the address of the RP.
+        Used if the RP is customer-managed.";
+       }
+       container groups {
+        list group {
+         key id;
+         leaf id {
+          type uint16;
+          description
+          "Identifier for the group.";
+         }
+         uses multicast-rp-group-cfg;
+         description
+         "List of multicast groups.";
+        }
+        description
+        "Multicast groups associated with the RP.";
+       }
+       description
+       "List of RP-to-group mappings.";
+      }
+      description
+      "RP-to-group mappings parameters.";
+     }
+     container rp-discovery {
+      leaf rp-discovery-type {
+       type identityref {
+        base multicast-rp-discovery-type;
+        }
+       default static-rp;
+
+       description
+       "Type of RP discovery used.";
+      }
+      container bsr-candidates {
+        when "derived-from-or-self(../rp-discovery-type, "+
+            "'l3vpn-svc:bsr-rp')" {
+        description
+        "Only applicable if discovery type
+        is BSR-RP.";
+       }
+       leaf-list bsr-candidate-address {
+        type inet:ip-address;
+         description
+         "Address of BSR candidate.";
+       }
+       description
+       "Container for List of Customer
+       BSR candidate's addresses.";
+      }
+      description
+      "RP discovery parameters.";
+     }
+     description
+     "RP parameters.";
+    }
+    description
+    "Multicast global parameters for the VPN service.";
+   }
+   description
+   "Grouping for multicast VPN definition.";
+  }
+  grouping vpn-service-mpls {
+   leaf carrierscarrier {
+    if-feature carrierscarrier;
+     type boolean;
+     default false;
+     description
+     "The VPN is using CsC, and so MPLS is required.";
+   }
+   description
+   "Grouping for MPLS CsC definition.";
+  }
+  grouping customer-location-info {
+   container locations {
+    list location {
+     key location-id;
+     leaf location-id {
+      type svc-id;
+
+      description
+      "Identifier for a particular location.";
+     }
+     leaf address {
+      type string;
+      description
+      "Address (number and street) of the site.";
+     }
+     leaf postal-code {
+      type string;
+      description
+      "Postal code of the site.";
+     }
+     leaf state {
+      type string;
+      description
+      "State of the site.  This leaf can also be
+      used to describe a region for a country that
+      does not have states.";
+     }
+     leaf city {
+      type string;
+      description
+      "City of the site.";
+     }
+     leaf country-code {
+      type string {
+       pattern '[A-Z]{2}';
+      }
+      description
+      "Country of the site.
+      Expressed as ISO ALPHA-2 code.";
+     }
+     description
+     "Location of the site.";
+    }
+    description
+    "List of locations for the site.";
+   }
+   description
+   "This grouping defines customer location parameters.";
+  }
+  grouping site-group {
+   container groups {
+    list group {
+     key group-id;
+     leaf group-id {
+      type string;
+
+      description
+      "Group-id the site belongs to.";
+     }
+     description
+     "List of group-ids.";
+    }
+    description
+    "Groups the site or site-network-access belongs to.";
+   }
+   description
+   "Grouping definition to assign
+   group-ids to site or site-network-access.";
+  }
+  grouping site-diversity {
+   container site-diversity {
+    if-feature site-diversity;
+    uses site-group;
+    description
+    "Diversity constraint type.  All
+    site-network-accesses will inherit
+    the group values defined here.";
+   }
+   description
+   "This grouping defines site
+   diversity parameters.";
+  }
+  grouping access-diversity {
+   container access-diversity {
+    if-feature site-diversity;
+    uses site-group;
+    container constraints {
+     list constraint {
+      key constraint-type;
+      leaf constraint-type {
+       type identityref {
+        base placement-diversity;
+       }
+       description
+       "Diversity constraint type.";
+      }
+      container target {
+       choice target-flavor {
+        default id;
+        case id {
+         list group {
+          key group-id;
+          leaf group-id {
+           type string;
+
+           description
+           "The constraint will be applied against
+           this particular group-id for this site
+           network access level.";
+          }
+          description
+          "List of group-ids associated with one specific
+          constraint for this site network access level.";
+         }
+        }
+        case all-accesses {
+         leaf all-other-accesses {
+          type empty;
+          description
+          "The constraint will be applied against
+          all other site network accesses of this site.";
+         }
+        }
+        case all-groups {
+         leaf all-other-groups {
+          type empty;
+          description
+          "The constraint will be applied against
+          all other groups managed by the customer.";
+         }
+        }
+        description
+        "Choice for the target flavor definition.";
+       }
+       description
+       "The constraint will be applied against a
+       Specific target, and the target can be a list
+       of group-ids,all other site network accesses of
+       this site, or all other groups managed by the
+       customer.";
+      }
+      description
+      "List of constraints.";
+     }
+     description
+     "Placement constraints for this site network access.";
+    }
+    description
+    "Diversity parameters.";
+   }
+   description
+   "This grouping defines access diversity parameters.";
+  }
+
+  grouping operational-requirements {
+    leaf requested-site-start {
+     type yang:date-and-time;
+      description
+      "Optional leaf indicating requested date and
+      time when the service at a particular site is
+      expected to start.";
+   }
+
+   leaf requested-site-stop {
+     type yang:date-and-time;
+      description
+      "Optional leaf indicating requested date and
+      time when the service at a particular site is
+      expected to stop.";
+   }
+   description
+   "This grouping defines some operational
+   parameters.";
+  }
+  grouping operational-requirements-ops {
+    leaf actual-site-start {
+     type yang:date-and-time;
+     config false;
+      description
+      "Optional leaf indicating actual date and
+      time when the service at a particular site
+      actually started.";
+   }
+   leaf actual-site-stop {
+    type yang:date-and-time;
+    config false;
+      description
+      "Optional leaf indicating actual date and
+      time when the service at a particular site
+      actually stopped.";
+   }
+   description
+   "This grouping defines some operational
+   parameters.";
+  }
+  grouping flow-definition {
+   container match-flow {
+    leaf dscp {
+     type inet:dscp;
+      description
+      "DSCP value.";
+    }
+
+    leaf dot1p {
+     type uint8 {
+      range "0..7";
+     }
+     description
+     "802.1p matching.";
+    }
+    leaf ipv4-src-prefix {
+     type inet:ipv4-prefix;
+      description
+      "Match on IPv4 src address.";
+    }
+    leaf ipv6-src-prefix {
+     type inet:ipv6-prefix;
+      description
+      "Match on IPv6 src address.";
+    }
+    leaf ipv4-dst-prefix {
+     type inet:ipv4-prefix;
+      description
+      "Match on IPv4 dst address.";
+    }
+    leaf ipv6-dst-prefix {
+     type inet:ipv6-prefix;
+     description
+     "Match on IPv6 dst address.";
+    }
+    leaf l4-src-port {
+     type inet:port-number;
+         must "current() < ../l4-src-port-range/lower-port or "+
+         "current() > ../l4-src-port-range/upper-port" {
+      description
+      "If l4-src-port and l4-src-port-range/lower-port and
+      upper-port are set at the same time, l4-src-port
+      should not overlap with l4-src-port-range.";
+      }
+      description
+      "Match on Layer 4 src port.";
+    }
+    leaf-list target-sites {
+      if-feature target-sites;
+      type svc-id;
+      description
+      "Identify a site as traffic destination.";
+    }
+    container l4-src-port-range {
+      leaf lower-port {
+      type inet:port-number;
+
+      description
+      "Lower boundary for port.";
+     }
+     leaf upper-port {
+      type inet:port-number;
+      must ". >= ../lower-port" {
+       description
+       "Upper boundary for port.  If it
+       exists, the upper boundary must be
+       higher than the lower boundary.";
+      }
+      description
+      "Upper boundary for port.";
+     }
+      description
+      "Match on Layer 4 src port range.  When
+      only the lower-port is present, it represents
+      a single port.  When both the lower-port and
+      upper-port are specified, it implies
+      a range inclusive of both values.";
+    }
+    leaf l4-dst-port {
+     type inet:port-number;
+          must "current() < ../l4-dst-port-range/lower-port or "+
+          "current() > ../l4-dst-port-range/upper-port" {
+      description
+      "If l4-dst-port and l4-dst-port-range/lower-port
+      and upper-port are set at the same time,
+      l4-dst-port should not overlap with
+      l4-src-port-range.";
+      }
+      description
+      "Match on Layer 4 dst port.";
+    }
+    container l4-dst-port-range {
+     leaf lower-port {
+      type inet:port-number;
+      description
+      "Lower boundary for port.";
+     }
+     leaf upper-port {
+      type inet:port-number;
+      must ". >= ../lower-port" {
+      description
+      "Upper boundary must be
+      higher than lower boundary.";
+      }
+      description
+
+      "Upper boundary for port.  If it exists,
+      upper boundary must be higher than lower
+      boundary.";
+     }
+     description
+     "Match on Layer 4 dst port range.  When only
+     lower-port is present, it represents a single
+     port.  When both lower-port and upper-port are
+     specified, it implies a range inclusive of both
+     values.";
+    }
+    leaf protocol-field {
+     type union {
+      type uint8;
+      type identityref {
+       base protocol-type;
+      }
+     }
+     description
+     "Match on IPv4 protocol or IPv6 Next Header field.";
+    }
+    description
+    "Describes flow-matching criteria.";
+   }
+   description
+   "Flow definition based on criteria.";
+  }
+  grouping site-service-basic {
+   leaf svc-input-bandwidth {
+     type uint64;
+     units bps;
+     mandatory true;
+      description
+      "From the customer site's perspective, the service
+      input bandwidth of the connection or download
+      bandwidth from the SP to the site.";
+   }
+   leaf svc-output-bandwidth {
+    type uint64;
+    units bps;
+    mandatory true;
+      description
+      "From the customer site's perspective, the service
+      output bandwidth of the connection or upload
+      bandwidth from the site to the SP.";
+   }
+   leaf svc-mtu {
+    type uint16;
+
+    units bytes;
+    mandatory true;
+     description
+     "MTU at service level.  If the service is IP,
+     it refers to the IP MTU.  If CsC is enabled,
+     the requested 'svc-mtu' leaf will refer to the
+     MPLS MTU and not to the IP MTU.";
+   }
+   description
+   "Defines basic service parameters for a site.";
+  }
+  grouping site-protection {
+   container traffic-protection {
+    if-feature fast-reroute;
+    leaf enabled {
+     type boolean;
+     default false;
+      description
+      "Enables traffic protection of access link.";
+    }
+    description
+    "Fast Reroute service parameters for the site.";
+   }
+   description
+   "Defines protection service parameters for a site.";
+  }
+  grouping site-service-mpls {
+   container carrierscarrier {
+    if-feature carrierscarrier;
+    leaf signalling-type {
+     type enumeration {
+     enum ldp {
+      description
+      "Use LDP as the signalling protocol
+      between the PE and the CE.  In this case,
+      an IGP routing protocol must also be activated.";
+      }
+     enum bgp {
+      description
+      "Use BGP (as per RFC 8277) as the signalling protocol
+      between the PE and the CE.
+      In this case, BGP must also be configured as
+      the routing protocol.";
+      }
+     }
+     default bgp;
+     description
+     "MPLS signalling type.";
+
+    }
+      description
+      "This container is used when the customer provides
+      MPLS-based services.  This is only used in the case
+      of CsC (i.e., a customer builds an MPLS service using
+      an IP VPN to carry its traffic).";
+   }
+      description
+      "Defines MPLS service parameters for a site.";
+  }
+  grouping site-service-qos-profile {
+   container qos {
+    if-feature qos;
+    container qos-classification-policy {
+     list rule {
+      key id;
+      ordered-by user;
+      leaf id {
+       type string;
+       description
+       "A description identifying the
+        qos-classification-policy rule.";
+      }
+      choice match-type {
+       default match-flow;
+       case match-flow {
+       uses flow-definition;
+       }
+       case match-application {
+        leaf match-application {
+         type identityref {
+          base customer-application;
+         }
+          description
+          "Defines the application to match.";
+        }
+       }
+       description
+       "Choice for classification.";
+      }
+      leaf target-class-id {
+       type string;
+       description
+       "Identification of the class of service.
+       This identifier is internal to the administration.";
+      }
+      description
+      "List of marking rules.";
+
+     }
+     description
+     "Configuration of the traffic classification policy.";
+    }
+    container qos-profile {
+     choice qos-profile {
+      description
+      "Choice for QoS profile.
+      Can be standard profile or customized profile.";
+      case standard {
+       description
+       "Standard QoS profile.";
+       leaf profile {
+        type leafref {
+        path "/l3vpn-svc/vpn-profiles/valid-provider-identifiers"+
+            "/qos-profile-identifier/id";
+        }
+        description
+        "QoS profile to be used.";
+       }
+      }
+      case custom {
+       description
+       "Customized QoS profile.";
+        container classes {
+         if-feature qos-custom;
+         list class {
+          key class-id;
+          leaf class-id {
+          type string;
+                   description
+                   "Identification of the class of service.
+                   This identifier is internal to the
+                   administration.";
+          }
+          leaf direction {
+                   type identityref {
+                    base qos-profile-direction;
+                    }
+                   default both;
+                    description
+                    "The direction to which the QoS profile
+                    is applied.";
+                 }
+                  leaf rate-limit {
+                   type decimal64 {
+                    fraction-digits 5;
+                    range "0..100";
+
+           }
+                   units percent;
+                    description
+                    "To be used if the class must be rate-limited.
+                    Expressed as percentage of the service
+                    bandwidth.";
+         }
+         container latency {
+          choice flavor {
+           case lowest {
+            leaf use-lowest-latency {
+             type empty;
+              description
+              "The traffic class should use the path with the
+              lowest latency.";
+            }
+           }
+           case boundary {
+            leaf latency-boundary {
+             type uint16;
+             units msec;
+             default 400;
+              description
+              "The traffic class should use a path with a
+              defined maximum latency.";
+            }
+           }
+           description
+           "Latency constraint on the traffic class.";
+          }
+          description
+          "Latency constraint on the traffic class.";
+         }
+         container jitter {
+          choice flavor {
+           case lowest {
+            leaf use-lowest-jitter {
+             type empty;
+              description
+              "The traffic class should use the path with the
+              lowest jitter.";
+            }
+           }
+           case boundary {
+            leaf latency-boundary {
+             type uint32;
+             units usec;
+             default 40000;
+
+              description
+              "The traffic class should use a path with a
+              defined maximum jitter.";
+            }
+           }
+           description
+           "Jitter constraint on the traffic class.";
+          }
+          description
+          "Jitter constraint on the traffic class.";
+         }
+         container bandwidth {
+          leaf guaranteed-bw-percent {
+           type decimal64 {
+                   fraction-digits 5;
+                   range "0..100";
+           }
+           units percent;
+           mandatory true;
+            description
+            "To be used to define the guaranteed bandwidth
+            as a percentage of the available service bandwidth.";
+          }
+          leaf end-to-end {
+           type empty;
+            description
+            "Used if the bandwidth reservation
+            must be done on the MPLS network too.";
+          }
+          description
+          "Bandwidth constraint on the traffic class.";
+         }
+         description
+         "List of classes of services.";
+        }
+        description
+        "Container for list of classes of services.";
+       }
+      }
+     }
+     description
+     "QoS profile configuration.";
+    }
+    description
+    "QoS configuration.";
+   }
+   description
+   "This grouping defines QoS parameters for a site.";
+
+  }
+  grouping site-security-authentication {
+   container authentication {
+      description
+      "Authentication parameters.";
+   }
+   description
+   "This grouping defines authentication parameters for a site.";
+  }
+  grouping site-security-encryption {
+   container encryption {
+    if-feature encryption;
+    leaf enabled {
+     type boolean;
+     default false;
+      description
+      "If true, traffic encryption on the connection is required.";
+    }
+    leaf layer {
+       when "../enabled = 'true'" {
+          description
+          "Require a value for layer when enabled is true.";
+        }
+     type enumeration {
+      enum layer2 {
+       description
+       "Encryption will occur at Layer 2.";
+      }
+      enum layer3 {
+       description
+       "Encryption will occur at Layer 3.
+       For example, IPsec may be used when
+       a customer requests Layer 3 encryption.";
+      }
+     }
+     description
+      "Layer on which encryption is applied.";
+    }
+    container encryption-profile {
+     choice profile {
+      case provider-profile {
+       leaf profile-name {
+        type leafref {
+         path "/l3vpn-svc/vpn-profiles/valid-provider-identifiers"+
+                 "/encryption-profile-identifier/id";
+        }
+          description
+          "Name of the SP profile to be applied.";
+
+       }
+      }
+      case customer-profile {
+       leaf algorithm {
+        type string;
+          description
+          "Encryption algorithm to be used.";
+       }
+       choice key-type {
+        default psk;
+        case psk {
+         leaf preshared-key {
+          type string;
+          description
+          "Pre-Shared Key (PSK) coming from the customer.";
+         }
+        }
+        description
+        "Type of keys to be used.";
+       }
+      }
+      description
+      "Choice of encryption profile.  The encryption
+      profile can be the provider profile or customer profile.";
+     }
+     description
+     "Profile of encryption to be applied.";
+    }
+    description
+    "Encryption parameters.";
+   }
+   description
+   "This grouping defines encryption parameters for a site.";
+  }
+  grouping site-attachment-bearer {
+   container bearer {
+    container requested-type {
+     if-feature requested-type;
+     leaf requested-type {
+      type string;
+      description
+      "Type of requested bearer: Ethernet, DSL,
+      Wireless, etc. Operator specific.";
+     }
+     leaf strict {
+      type boolean;
+      default false;
+      description
+
+      "Defines whether requested-type is a preference
+      or a strict requirement.";
+     }
+      description
+      "Container for requested-type.";
+    }
+    leaf always-on {
+     if-feature always-on;
+     type boolean;
+     default true;
+      description
+      "Request for an always-on access type.
+      For example, this could mean no dial access type.";
+    }
+    leaf bearer-reference {
+     if-feature bearer-reference;
+     type string;
+      description
+      "This is an internal reference for the SP.";
+    }
+      description
+      "Bearer-specific parameters.
+      To be augmented.";
+   }
+   description
+   "Defines physical properties of a site attachment.";
+  }
+  grouping site-routing {
+   container routing-protocols {
+    list routing-protocol {
+     key type;
+     leaf type {
+      type identityref {
+       base routing-protocol-type;
+      }
+      description
+      "Type of routing protocol.";
+     }
+     container ospf {
+      when "derived-from-or-self(../type, 'l3vpn-svc:ospf')" {
+      description
+      "Only applies when protocol is OSPF.";
+      }
+      if-feature rtg-ospf;
+      leaf-list address-family {
+       type address-family;
+           min-elements "1";
+          description
+
+          "If OSPF is used on this site, this node
+          contains a configured value.  This node
+          contains at least one address family
+          to be activated.";
+      }
+      leaf area-address {
+       type yang:dotted-quad;
+       mandatory true;
+          description
+          "Area address.";
+      }
+      leaf metric {
+       type uint16;
+       default 1;
+          description
+          "Metric of the PE-CE link.  It is used
+          in the routing state calculation and
+          path selection.";
+      }
+      container sham-links {
+       if-feature rtg-ospf-sham-link;
+       list sham-link {
+        key target-site;
+        leaf target-site {
+         type svc-id;
+          description
+          "Target site for the sham link connection.
+          The site is referred to by its ID.";
+        }
+        leaf metric {
+         type uint16;
+         default 1;
+          description
+          "Metric of the sham link.  It is used in
+          the routing state calculation and path
+          selection.  The default value is set
+          to 1.";
+        }
+          description
+          "Creates a sham link with another site.";
+       }
+       description
+       "List of sham links.";
+      }
+      description
+      "OSPF-specific configuration.";
+     }
+     container bgp {
+
+      when "derived-from-or-self(../type, 'l3vpn-svc:bgp')" {
+       description
+       "Only applies when protocol is BGP.";
+      }
+      if-feature rtg-bgp;
+      leaf autonomous-system {
+       type uint32;
+       mandatory true;
+          description
+          "Customer AS number in case the customer
+          requests BGP routing.";
+      }
+      leaf-list address-family {
+       type address-family;
+           min-elements "1";
+          description
+          "If BGP is used on this site, this node
+          contains a configured value.  This node
+          contains at least one address family
+          to be activated.";
+      }
+      description
+      "BGP-specific configuration.";
+     }
+     container static {
+      when "derived-from-or-self(../type, 'l3vpn-svc:static')" {
+        description
+        "Only applies when protocol is static.
+        BGP activation requires the SP to know
+        the address of the customer peer.  When
+        BGP is enabled, the 'static-address'
+        allocation type for the IP connection
+        MUST be used.";
+      }
+      container cascaded-lan-prefixes {
+       list ipv4-lan-prefixes {
+        if-feature ipv4;
+        key "lan next-hop";
+        leaf lan {
+         type inet:ipv4-prefix;
+         description
+         "LAN prefixes.";
+        }
+        leaf lan-tag {
+         type string;
+          description
+          "Internal tag to be used in VPN policies.";
+        }
+
+        leaf next-hop {
+         type inet:ipv4-address;
+          description
+          "Next-hop address to use on the customer side.";
+        }
+        description
+        "List of LAN prefixes for the site.";
+       }
+       list ipv6-lan-prefixes {
+        if-feature ipv6;
+        key "lan next-hop";
+        leaf lan {
+         type inet:ipv6-prefix;
+          description
+          "LAN prefixes.";
+        }
+        leaf lan-tag {
+         type string;
+         description
+         "Internal tag to be used in VPN policies.";
+        }
+        leaf next-hop {
+         type inet:ipv6-address;
+          description
+          "Next-hop address to use on the customer side.";
+        }
+        description
+        "List of LAN prefixes for the site.";
+       }
+       description
+       "LAN prefixes from the customer.";
+      }
+      description
+      "Configuration specific to static routing.";
+     }
+     container rip {
+      when "derived-from-or-self(../type, 'l3vpn-svc:rip')" {
+       description
+       "Only applies when the protocol is RIP.  For IPv4,
+       the model assumes that RIP version 2 is used.";
+      }
+      if-feature rtg-rip;
+      leaf-list address-family {
+       type address-family;
+           min-elements "1";
+          description
+          "If RIP is used on this site, this node
+          contains a configured value.  This node
+
+          contains at least one address family
+          to be activated.";
+      }
+      description
+      "Configuration specific to RIP routing.";
+     }
+     container vrrp {
+      when "derived-from-or-self(../type, 'l3vpn-svc:vrrp')" {
+       description
+       "Only applies when protocol is VRRP.";
+      }
+      if-feature rtg-vrrp;
+      leaf-list address-family {
+       type address-family;
+           min-elements "1";
+          description
+          "If VRRP is used on this site, this node
+          contains a configured value.  This node contains
+          at least one address family to be activated.";
+      }
+      description
+      "Configuration specific to VRRP routing.";
+     }
+     description
+     "List of routing protocols used on
+     the site.  This list can be augmented.";
+    }
+    description
+    "Defines routing protocols.";
+   }
+   description
+   "Grouping for routing protocols.";
+  }
+  grouping site-attachment-ip-connection {
+    container ip-connection {
+      container ipv4 {
+      if-feature ipv4;
+       leaf address-allocation-type {
+       type identityref {
+        base address-allocation-type;
+      }
+      must "not(derived-from-or-self(current(), 'l3vpn-svc:slaac') or "+
+          "derived-from-or-self(current(), "+
+          "'l3vpn-svc:provider-dhcp-slaac'))" {
+      error-message "SLAAC is only applicable to IPv6";
+      }
+      description
+      "Defines how addresses are allocated.
+
+      If there is no value for the address
+      allocation type, then IPv4 is not enabled.";
+     }
+    container provider-dhcp {
+      when "derived-from-or-self(../address-allocation-type, "+
+      "'l3vpn-svc:provider-dhcp')" {
+      description
+      "Only applies when addresses are allocated by DHCP.";
+    }
+      leaf provider-address {
+       type inet:ipv4-address;
+          description
+          "Address of provider side.  If provider-address is not
+          specified, then prefix length should not be specified
+          either.  It also implies provider-dhcp allocation is
+          not enabled.  If provider-address is specified, then
+          the prefix length may or may not be specified.";
+      }
+      leaf prefix-length {
+       type uint8 {
+       range "0..32";
+       }
+          must "(../provider-address)" {
+           error-message
+           "If the prefix length is specified, provider-address
+           must also be specified.";
+              description
+              "If the prefix length is specified, provider-address
+              must also be specified.";
+         }
+      description
+      "Subnet prefix length expressed in bits.
+      If not specified, or specified as zero,
+      this means the customer leaves the actual
+      prefix length value to the provider.";
+      }
+      choice address-assign {
+       default number;
+       case number {
+        leaf number-of-dynamic-address {
+         type uint16;
+         default 1;
+          description
+          "Describes the number of IP addresses
+          the customer requires.";
+        }
+       }
+       case explicit {
+
+        container customer-addresses {
+         list address-group {
+          key "group-id";
+          leaf group-id {
+          type string;
+          description
+          "Group-id for the address range from
+          start-address to end-address.";
+          }
+         leaf start-address {
+          type inet:ipv4-address;
+           description
+           "First address.";
+          }
+         leaf end-address {
+          type inet:ipv4-address;
+          description
+          "Last address.";
+          }
+          description
+          "Describes IP addresses allocated by DHCP.
+          When only start-address or only end-address
+          is present, it represents a single address.
+          When both start-address and end-address are
+          specified, it implies a range inclusive of both
+          addresses.  If no address is specified, it implies
+          customer addresses group is not supported.";
+         }
+          description
+          "Container for customer addresses is allocated by DHCP.";
+        }
+      }
+          description
+          "Choice for the way to assign addresses.";
+      }
+          description
+          "DHCP allocated addresses related parameters.";
+     }
+  container dhcp-relay {
+    when "derived-from-or-self(../address-allocation-type, "+
+    "'l3vpn-svc:provider-dhcp-relay')" {
+      description
+      "Only applies when provider is required to implement
+      DHCP relay function.";
+   }
+  leaf provider-address {
+   type inet:ipv4-address;
+      description
+
+      "Address of provider side.  If provider-address is not
+      specified, then prefix length should not be specified
+      either.  It also implies provider-dhcp allocation is
+      not enabled.  If provider-address is specified, then
+      prefix length may or may not be specified.";
+  }
+  leaf prefix-length {
+   type uint8 {
+   range "0..32";
+   }
+  must "(../provider-address)" {
+   error-message
+      "If prefix length is specified, provider-address
+       must also be specified.";
+      description
+      "If prefix length is specified, provider-address
+      must also be specified.";
+ }
+      description
+      "Subnet prefix length expressed in bits.  If not
+      specified, or specified as zero, this means the
+      customer leaves the actual prefix length value
+      to the provider.";
+  }
+  container customer-dhcp-servers {
+   leaf-list server-ip-address {
+   type inet:ipv4-address;
+      description
+      "IP address of customer DHCP server.";
+  }
+  description
+  "Container for list of customer DHCP servers.";
+  }
+  description
+  "DHCP relay provided by operator.";
+ }
+  container addresses {
+    when "derived-from-or-self(../address-allocation-type, "+
+    "'l3vpn-svc:static-address')" {
+    description
+    "Only applies when protocol allocation type is static.";
+     }
+      leaf provider-address {
+       type inet:ipv4-address;
+          description
+          "IPv4 Address List of the provider side.
+          When the protocol allocation type is static,
+          the provider address must be configured.";
+
+      }
+      leaf customer-address {
+       type inet:ipv4-address;
+          description
+          "IPv4 Address of customer side.";
+      }
+      leaf prefix-length {
+       type uint8 {
+        range "0..32";
+       }
+      description
+      "Subnet prefix length expressed in bits.
+      It is applied to both provider-address
+      and customer-address.";
+      }
+      description
+      "Describes IPv4 addresses used.";
+     }
+     description
+     "IPv4-specific parameters.";
+    }
+    container ipv6 {
+     if-feature ipv6;
+     leaf address-allocation-type {
+      type identityref {
+       base address-allocation-type;
+      }
+      description
+      "Defines how addresses are allocated.
+      If there is no value for the address
+      allocation type, then IPv6 is
+      not enabled.";
+     }
+
+    container provider-dhcp {
+       when "derived-from-or-self(../address-allocation-type, "+
+       "'l3vpn-svc:provider-dhcp') "+
+       "or derived-from-or-self(../address-allocation-type, "+
+       "'l3vpn-svc:provider-dhcp-slaac')" {
+       description
+       "Only applies when addresses are allocated by DHCP.";
+        }
+           leaf provider-address {
+            type inet:ipv6-address;
+            description
+            "Address of the provider side.  If provider-address
+            is not specified, then prefix length should not be
+            specified either.  It also implies provider-dhcp
+
+            allocation is not enabled.  If provider-address is
+            specified, then prefix length may or may
+            not be specified.";
+          }
+       leaf prefix-length {
+        type uint8 {
+        range "0..128";
+        }
+            must "(../provider-address)" {
+              error-message
+              "If prefix length is specified, provider-address
+              must also be specified.";
+              description
+              "If prefix length is specified, provider-address
+              must also be specified.";
+             }
+        description
+        "Subnet prefix length expressed in bits.  If not
+        specified, or specified as zero, this means the
+        customer leaves the actual prefix length value
+        to the provider.";
+      }
+         choice address-assign {
+          default number;
+          case number {
+           leaf number-of-dynamic-address {
+            type uint16;
+            default 1;
+            description
+            "Describes the number of IP addresses the customer
+            requires.";
+           }
+          }
+          case explicit {
+           container customer-addresses {
+            list address-group {
+                  key "group-id";
+                  leaf group-id {
+                  type string;
+                  description
+                  "Group-id for the address range from
+                  start-address to end-address.";
+              }
+                  leaf start-address {
+                   type inet:ipv6-address;
+                   description
+                   "First address.";
+                   }
+
+                  leaf end-address {
+                   type inet:ipv6-address;
+                   description
+                   "Last address.";
+                   }
+                  description
+                  "Describes IP addresses allocated by DHCP.  When only
+                  start-address or only end-address is present, it
+                  represents a single address.  When both start-address
+                  and end-address are specified, it implies a range
+                  inclusive of both addresses.  If no address is
+                  specified, it implies customer addresses group is
+                  not supported.";
+           }
+            description
+            "Container for customer addresses allocated by DHCP.";
+          }
+         }
+          description
+          "Choice for the way to assign addresses.";
+         }
+          description
+          "DHCP allocated addresses related parameters.";
+         }
+    container dhcp-relay {
+     when "derived-from-or-self(../address-allocation-type, "+
+          "'l3vpn-svc:provider-dhcp-relay')" {
+       description
+       "Only applies when the provider is required
+       to implement DHCP relay function.";
+       }
+         leaf provider-address {
+          type inet:ipv6-address;
+           description
+           "Address of the provider side.  If provider-address is
+           not specified, then prefix length should not be
+           specified either.  It also implies provider-dhcp
+           allocation is not enabled.  If provider address
+           is specified, then prefix length may or may
+           not be specified.";
+           }
+         leaf prefix-length {
+          type uint8 {
+           range "0..128";
+           }
+          must "(../provider-address)" {
+           error-message
+            "If prefix length is specified, provider-address
+
+            must also be specified.";
+           description
+           "If prefix length is specified, provider-address
+           must also be specified.";
+            }
+          description
+          "Subnet prefix length expressed in bits.  If not
+          specified, or specified as zero, this means the
+          customer leaves the actual prefix length value
+          to the provider.";
+          }
+     container customer-dhcp-servers {
+      leaf-list server-ip-address {
+       type inet:ipv6-address;
+        description
+        "This node contains the IP address of
+        the customer DHCP server.  If the DHCP relay
+        function is implemented by the
+        provider, this node contains the
+        configured value.";
+      }
+       description
+       "Container for list of customer DHCP servers.";
+      }
+     description
+     "DHCP relay provided by operator.";
+     }
+    container addresses {
+     when "derived-from-or-self(../address-allocation-type, "+
+         "'l3vpn-svc:static-address')" {
+      description
+      "Only applies when protocol allocation type is static.";
+      }
+     leaf provider-address {
+      type inet:ipv6-address;
+       description
+       "IPv6 Address of the provider side.  When the protocol
+       allocation type is static, the provider address
+       must be configured.";
+      }
+     leaf customer-address {
+      type inet:ipv6-address;
+       description
+       "The IPv6 Address of the customer side.";
+      }
+     leaf prefix-length {
+      type uint8 {
+       range "0..128";
+
+      }
+      description
+      "Subnet prefix length expressed in bits.
+      It is applied to both provider-address and
+      customer-address.";
+     }
+     description
+     "Describes IPv6 addresses used.";
+     }
+     description
+     "IPv6-specific parameters.";
+    }
+    container oam {
+     container bfd {
+      if-feature bfd;
+      leaf enabled {
+       type boolean;
+       default false;
+       description
+       "If true, BFD activation is required.";
+      }
+      choice holdtime {
+       default fixed;
+       case fixed {
+        leaf fixed-value {
+         type uint32;
+         units msec;
+          description
+          "Expected BFD holdtime expressed in msec.  The customer
+          may impose some fixed values for the holdtime period
+          if the provider allows the customer use this function.
+          If the provider doesn't allow the customer to use this
+          function, the fixed-value will not be set.";
+        }
+       }
+       case profile {
+        leaf profile-name {
+         type leafref {
+          path "/l3vpn-svc/vpn-profiles/valid-provider-identifiers/"+
+                  "bfd-profile-identifier/id";
+         }
+         description
+         "Well-known SP profile name.  The provider can propose
+         some profiles to the customer, depending on the service
+         level the customer wants to achieve.  Profile names
+         must be communicated to the customer.";
+        }
+        description
+
+        "Well-known SP profile.";
+       }
+       description
+       "Choice for holdtime flavor.";
+      }
+      description
+      "Container for BFD.";
+     }
+     description
+     "Defines the Operations, Administration, and Maintenance (OAM)
+     mechanisms used on the connection.  BFD is set as a fault
+     detection mechanism, but the 'oam' container can easily
+     be augmented by other mechanisms";
+    }
+    description
+    "Defines connection parameters.";
+   }
+   description
+   "This grouping defines IP connection parameters.";
+  }
+  grouping site-service-multicast {
+   container multicast {
+    if-feature multicast;
+    leaf multicast-site-type {
+     type enumeration {
+      enum receiver-only {
+       description
+       "The site only has receivers.";
+      }
+      enum source-only {
+       description
+       "The site only has sources.";
+      }
+      enum source-receiver {
+       description
+       "The site has both sources and receivers.";
+      }
+     }
+     default source-receiver;
+     description
+     "Type of multicast site.";
+    }
+    container multicast-address-family {
+     leaf ipv4 {
+      if-feature ipv4;
+      type boolean;
+      default false;
+      description
+
+      "Enables IPv4 multicast.";
+     }
+     leaf ipv6 {
+      if-feature ipv6;
+      type boolean;
+      default false;
+      description
+      "Enables IPv6 multicast.";
+     }
+     description
+     "Defines protocol to carry multicast.";
+     }
+    leaf protocol-type {
+     type enumeration {
+      enum host {
+       description
+       "Hosts are directly connected to the provider network.
+       Host protocols such as IGMP or MLD are required.";
+      }
+      enum router {
+       description
+       "Hosts are behind a customer router.
+       PIM will be implemented.";
+      }
+      enum both {
+       description
+       "Some hosts are behind a customer router, and
+       some others are directly connected to the
+       provider network.  Both host and routing protocols
+       must be used.  Typically, IGMP and PIM will be
+       implemented.";
+      }
+     }
+     default "both";
+     description
+     "Multicast protocol type to be used with the customer site.";
+    }
+    description
+    "Multicast parameters for the site.";
+   }
+   description
+   "Multicast parameters for the site.";
+  }
+  grouping site-management {
+   container management {
+    leaf type {
+     type identityref {
+      base management;
+
+     }
+     mandatory true;
+     description
+     "Management type of the connection.";
+    }
+    description
+    "Management configuration.";
+   }
+   description
+   "Management parameters for the site.";
+  }
+  grouping site-devices {
+   container devices {
+    when "derived-from-or-self(../management/type, "+
+    "'l3vpn-svc:provider-managed') or "+
+    "derived-from-or-self(../management/type, 'l3vpn-svc:co-managed')" {
+    description
+    "Applicable only for provider-managed or
+    co-managed device.";
+   }
+   list device {
+    key device-id;
+    leaf device-id {
+     type svc-id;
+     description
+     "Identifier for the device.";
+    }
+    leaf location {
+     type leafref {
+      path "../../../locations/"+
+      "location/location-id";
+     }
+     mandatory true;
+     description
+      "Location of the device.";
+     }
+    container management {
+     when "derived-from-or-self(../../../management/type,"+
+       "'l3vpn-svc:co-managed')" {
+       description
+        "Applicable only for co-managed device.";
+      }
+     leaf address-family {
+      type address-family;
+      description
+      "Address family used for management.";
+     }
+     leaf address {
+
+          when "(../address-family)" {
+            description
+            "If address-family is specified, then address should
+            also be specified.  If address-family is not specified,
+            then address should also not be specified.";
+            }
+          type inet:ip-address;
+          mandatory true;
+      description
+      "Management address.";
+      }
+     description
+      "Management configuration.  Applicable only for
+       co-managed device.";
+     }
+     description
+     "List of devices requested by customer.";
+    }
+    description
+    "Device configuration.";
+   }
+   description
+   "Grouping for device allocation.";
+  }
+  grouping site-vpn-flavor {
+   leaf site-vpn-flavor {
+    type identityref {
+     base site-vpn-flavor;
+    }
+    default site-vpn-flavor-single;
+    description
+    "Defines the way the VPN multiplexing is done, e.g., whether
+    the site belongs to a single VPN site or a multiVPN; or, in the case
+    of a multiVPN, whether the logical accesses of the sites belong
+    to the same set of VPNs or each logical access maps to
+    different VPNs.";
+   }
+   description
+   "Grouping for site VPN flavor.";
+  }
+  grouping site-vpn-policy {
+   container vpn-policies {
+    list vpn-policy {
+     key vpn-policy-id;
+     leaf vpn-policy-id {
+      type svc-id;
+      description
+      "Unique identifier for the VPN policy.";
+
+     }
+     list entries {
+      key id;
+      leaf id {
+       type svc-id;
+       description
+       "Unique identifier for the policy entry.";
+      }
+      container filters {
+       list filter {
+        key type;
+        ordered-by user;
+        leaf type {
+         type identityref {
+          base vpn-policy-filter-type;
+          }
+         description
+         "Type of VPN Policy filter.";
+         }
+         leaf-list lan-tag {
+         when "derived-from-or-self(../type, 'l3vpn-svc:lan')" {
+          description
+          "Only applies when the VPN Policy filter is a
+          LAN Tag filter.";
+         }
+          if-feature lan-tag;
+          type string;
+          description
+          "List of 'lan-tag' items to be matched.  LAN Tag
+          is an Internal tag to be used in VPN policies ";
+         }
+         leaf-list ipv4-lan-prefix {
+         when "derived-from-or-self(../type, 'l3vpn-svc:ipv4')" {
+           description
+           "Only applies when VPN Policy filter is IPv4 Prefix filter.";
+          }
+          if-feature ipv4;
+          type inet:ipv4-prefix;
+          description
+          "List of IPv4 prefixes as LAN Prefixes to be matched.";
+         }
+         leaf-list ipv6-lan-prefix {
+         when "derived-from-or-self(../type, 'l3vpn-svc:ipv6')" {
+         description
+         "Only applies when VPN Policy filter is IPv6 Prefix filter.";
+          }
+          if-feature ipv6;
+          type inet:ipv6-prefix;
+
+          description
+          "List of IPv6 prefixes as LAN prefixes to be matched.";
+         }
+          description
+          "List of filters used on the site.  This list can
+          be augmented.";
+       }
+       description
+       "If a more-granular VPN attachment is necessary, filtering can
+       be used.  If used, it permits the splitting of site LANs among
+       multiple VPNs.  The Site LAN can be split based on either LAN
+       Tag or LAN prefix.  If no filter is used, all the LANs will be
+       part of the same VPNs with the same role.";
+      }
+      list vpn {
+       key vpn-id;
+       leaf vpn-id {
+        type leafref {
+         path "/l3vpn-svc/vpn-services/"+
+          "vpn-service/vpn-id";
+        }
+        mandatory true;
+        description
+        "Reference to an IP VPN.";
+       }
+       leaf site-role {
+        type identityref {
+         base site-role;
+        }
+        default any-to-any-role;
+        description
+        "Role of the site in the IP VPN.";
+       }
+       description
+       "List of VPNs the LAN is associated with.";
+      }
+      description
+      "List of entries for export policy.";
+     }
+     description
+     "List of VPN policies.";
+    }
+    description
+    "VPN policy.";
+   }
+   description
+   "VPN policy parameters for the site.";
+  }
+
+  grouping site-maximum-routes {
+   container maximum-routes {
+    list address-family {
+     key af;
+     leaf af {
+      type address-family;
+      description
+      "Address family.";
+     }
+     leaf maximum-routes {
+      type uint32;
+      description
+      "Maximum prefixes the VRF can accept
+      for this address family.";
+     }
+     description
+     "List of address families.";
+    }
+    description
+    "Defines 'maximum-routes' for the VRF.";
+   }
+   description
+   "Defines 'maximum-routes' for the site.";
+  }
+  grouping site-security {
+   container security {
+    uses site-security-authentication;
+    uses site-security-encryption;
+    description
+    "Site-specific security parameters.";
+   }
+   description
+   "Grouping for security parameters.";
+  }
+  grouping site-service {
+   container service {
+    uses site-service-qos-profile;
+    uses site-service-mpls;
+    uses site-service-multicast;
+    description
+    "Service parameters on the attachment.";
+   }
+   description
+   "Grouping for service parameters.";
+  }
+  grouping site-network-access-service {
+   container service {
+    uses site-service-basic;
+
+    uses site-service-qos-profile;
+    uses site-service-mpls;
+    uses site-service-multicast;
+    description
+    "Service parameters on the attachment.";
+   }
+   description
+   "Grouping for service parameters.";
+  }
+  grouping vpn-extranet {
+   container extranet-vpns {
+    if-feature extranet-vpn;
+    list extranet-vpn {
+     key vpn-id;
+     leaf vpn-id {
+      type svc-id;
+      description
+      "Identifies the target VPN the local VPN want to access.";
+     }
+     leaf local-sites-role {
+      type identityref {
+       base site-role;
+      }
+      default any-to-any-role;
+      description
+      "This describes the role of the
+      local sites in the target VPN topology.  In the any-to-any VPN
+      service topology, the local sites must have the same role, which
+      will be 'any-to-any-role'.  In the Hub-and-Spoke VPN service
+      topology or the Hub-and-Spoke disjoint VPN service topology,
+      the local sites must have a Hub role or a Spoke role.";
+     }
+     description
+     "List of extranet VPNs or target VPNs the local VPN is
+     attached to.";
+    }
+    description
+    "Container for extranet VPN configuration.";
+   }
+   description
+   "Grouping for extranet VPN configuration.
+   This provides an easy way to interconnect
+   all sites from two VPNs.";
+  }
+  grouping site-attachment-availability {
+   container availability {
+    leaf access-priority {
+     type uint32;
+
+     default 100;
+     description
+     "Defines the priority for the access.
+     The higher the access-priority value,
+     the higher the preference of the
+     access will be.";
+    }
+    description
+    "Availability parameters (used for multihoming).";
+   }
+   description
+   "Defines availability parameters for a site.";
+  }
+  grouping access-vpn-policy {
+   container vpn-attachment {
+    choice attachment-flavor {
+     case vpn-policy-id {
+      leaf vpn-policy-id {
+       type leafref {
+        path "../../../../"+
+         "vpn-policies/vpn-policy/"+
+         "vpn-policy-id";
+       }
+       description
+       "Reference to a VPN policy.  When referencing VPN
+       policy for attachment, the vpn-policy-id must be
+       configured.";
+      }
+     }
+     case vpn-id {
+      leaf vpn-id {
+       type leafref {
+        path "/l3vpn-svc/vpn-services"+
+         "/vpn-service/vpn-id";
+       }
+       description
+       "Reference to an IP VPN.  Referencing a vpn-id provides
+       an easy way to attach a particular logical access to
+       a VPN.  In this case, vpn-id must be configured.";
+      }
+      leaf site-role {
+       type identityref {
+        base site-role;
+       }
+       default any-to-any-role;
+       description
+       "Role of the site in the IP VPN.  When referencing a vpn-id,
+       the site-role setting must be added to express the role of
+
+       the site in the target VPN service topology.";
+      }
+     }
+     mandatory true;
+     description
+     "Choice for VPN attachment flavor.  A choice is implemented
+     to allow the user to choose the flavor that provides the
+     best fit.";
+    }
+    description
+    "Defines VPN attachment of a site.";
+   }
+   description
+   "Defines the VPN attachment rules for
+   a site's logical access.";
+  }
+  grouping vpn-profile-cfg {
+   container valid-provider-identifiers {
+    list cloud-identifier {
+     if-feature cloud-access;
+     key id;
+     leaf id {
+      type string;
+      description
+      "Identification of cloud service.
+      Local administration meaning.";
+     }
+     description
+     "List for Cloud Identifiers.";
+    }
+    list encryption-profile-identifier {
+     key id;
+     leaf id {
+      type string;
+      description
+      "Identification of the SP encryption profile
+      to be used.  Local administration meaning.";
+     }
+     description
+     "List for encryption profile identifiers.";
+    }
+    list qos-profile-identifier {
+     key id;
+     leaf id {
+      type string;
+      description
+      "Identification of the QoS Profile to be used.
+      Local administration meaning.";
+
+     }
+     description
+     "List for QoS Profile Identifiers.";
+    }
+    list bfd-profile-identifier {
+     key id;
+     leaf id {
+      type string;
+      description
+      "Identification of the SP BFD Profile to be used.
+      Local administration meaning.";
+     }
+     description
+     "List for BFD Profile identifiers.";
+    }
+      nacm:default-deny-write;
+      description
+      "Container for Valid Provider Identifies.";
+   }
+    description
+    "Grouping for VPN Profile configuration.";
+  }
+  grouping vpn-svc-cfg {
+   leaf vpn-id {
+    type svc-id;
+    description
+    "VPN identifier.  Local administration meaning.";
+   }
+   leaf customer-name {
+    type string;
+    description
+    "Name of the customer that actually uses the VPN service.
+    In the case that any intermediary (e.g., Tier-2 provider
+    or partner) sells the VPN service to their end user
+    on behalf of the original service provider (e.g., Tier-1
+    provider), the original service provider may require the
+    customer name to provide smooth activation/commissioning
+    and operation for the service.";
+   }
+   leaf vpn-service-topology {
+    type identityref {
+     base vpn-topology;
+    }
+    default any-to-any;
+    description
+    "VPN service topology.";
+   }
+   uses vpn-service-cloud-access;
+
+   uses vpn-service-multicast;
+   uses vpn-service-mpls;
+   uses vpn-extranet;
+   description
+   "Grouping for VPN service configuration.";
+  }
+  grouping site-top-level-cfg {
+   uses operational-requirements;
+   uses customer-location-info;
+   uses site-devices;
+   uses site-diversity;
+   uses site-management;
+   uses site-vpn-policy;
+   uses site-vpn-flavor;
+   uses site-maximum-routes;
+   uses site-security;
+   uses site-service;
+   uses site-protection;
+   uses site-routing;
+   description
+   "Grouping for site top-level configuration.";
+  }
+  grouping site-network-access-top-level-cfg {
+   leaf site-network-access-type {
+    type identityref {
+     base site-network-access-type;
+    }
+    default point-to-point;
+    description
+    "Describes the type of connection, e.g.,
+    point-to-point or multipoint.";
+   }
+   choice location-flavor {
+    case location {
+     when "derived-from-or-self(../../management/type, "+
+      "'l3vpn-svc:customer-managed')" {
+      description
+      "Applicable only for customer-managed device.";
+     }
+     leaf location-reference {
+      type leafref {
+       path "../../../locations/location/location-id";
+      }
+      description
+      "Location of the site-network-access.";
+     }
+    }
+    case device {
+
+     when "derived-from-or-self(../../management/type, "+
+      "'l3vpn-svc:provider-managed') or "+
+      "derived-from-or-self(../../management/type, "+
+      "'l3vpn-svc:co-managed')" {
+      description
+      "Applicable only for provider-managed or co-managed device.";
+     }
+     leaf device-reference {
+      type leafref {
+       path "../../../devices/device/device-id";
+      }
+      description
+      "Identifier of CE to use.";
+     }
+    }
+    mandatory true;
+    description
+    "Choice of how to describe the site's location.";
+   }
+   uses access-diversity;
+   uses site-attachment-bearer;
+   uses site-attachment-ip-connection;
+   uses site-security;
+   uses site-network-access-service;
+   uses site-routing;
+   uses site-attachment-availability;
+   uses access-vpn-policy;
+   description
+   "Grouping for site network access top-level configuration.";
+  }
+  /* Main blocks */
+  container l3vpn-svc {
+   container vpn-profiles {
+    uses vpn-profile-cfg;
+     description
+     "Container for VPN Profiles.";
+   }
+   container vpn-services {
+    list vpn-service {
+     key vpn-id;
+     uses vpn-svc-cfg;
+     description
+     "List of VPN services.";
+    }
+    description
+    "Top-level container for the VPN services.";
+   }
+   container sites {
+    list site {
+     key site-id;
+     leaf site-id {
+      type svc-id;
+      description
+      "Identifier of the site.";
+     }
+     uses site-top-level-cfg;
+     uses operational-requirements-ops;
+     container site-network-accesses {
+      list site-network-access {
+       key site-network-access-id;
+       leaf site-network-access-id {
+        type svc-id;
+        description
+        "Identifier for the access.";
+       }
+       uses site-network-access-top-level-cfg;
+       description
+       "List of accesses for a site.";
+      }
+      description
+      "List of accesses for a site.";
+     }
+     description
+     "List of sites.";
+    }
+    description
+    "Container for sites.";
+   }
+   description
+   "Main container for L3VPN service configuration.";
+  }
+ }
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-netconf-acm@2018-02-14.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-netconf-acm@2018-02-14.yang
new file mode 100644
index 0000000000000000000000000000000000000000..dc0deb8ffd29791ad80b9e3ad8244502126f2d44
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-netconf-acm@2018-02-14.yang
@@ -0,0 +1,468 @@
+module ietf-netconf-acm {
+
+  namespace "urn:ietf:params:xml:ns:yang:ietf-netconf-acm";
+
+  prefix nacm;
+
+  import ietf-yang-types {
+    prefix yang;
+  }
+
+  organization
+    "IETF NETCONF (Network Configuration) Working Group";
+
+  contact
+    "WG Web:   <https://datatracker.ietf.org/wg/netconf/>
+     WG List:  <mailto:netconf@ietf.org>
+
+     Author:   Andy Bierman
+               <mailto:andy@yumaworks.com>
+
+     Author:   Martin Bjorklund
+               <mailto:mbj@tail-f.com>";
+
+  description
+    "Network Configuration Access Control Model.
+
+     Copyright (c) 2012 - 2018 IETF Trust and the persons
+     identified as authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or
+     without modification, is permitted pursuant to, and subject
+     to the license terms contained in, the Simplified BSD
+     License set forth in Section 4.c of the IETF Trust's
+     Legal Provisions Relating to IETF Documents
+     (https://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 8341; see
+     the RFC itself for full legal notices.";
+
+  revision "2018-02-14" {
+    description
+      "Added support for YANG 1.1 actions and notifications tied to
+       data nodes.  Clarified how NACM extensions can be used by
+       other data models.";
+    reference
+      "RFC 8341: Network Configuration Access Control Model";
+  }
+
+  revision "2012-02-22" {
+    description
+      "Initial version.";
+    reference
+      "RFC 6536: Network Configuration Protocol (NETCONF)
+                 Access Control Model";
+  }
+
+  /*
+   * Extension statements
+   */
+
+  extension default-deny-write {
+    description
+      "Used to indicate that the data model node
+       represents a sensitive security system parameter.
+
+       If present, the NETCONF server will only allow the designated
+       'recovery session' to have write access to the node.  An
+       explicit access control rule is required for all other users.
+
+       If the NACM module is used, then it must be enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), or this extension
+       is ignored.
+
+       The 'default-deny-write' extension MAY appear within a data
+       definition statement.  It is ignored otherwise.";
+  }
+
+  extension default-deny-all {
+    description
+      "Used to indicate that the data model node
+       controls a very sensitive security system parameter.
+
+       If present, the NETCONF server will only allow the designated
+       'recovery session' to have read, write, or execute access to
+       the node.  An explicit access control rule is required for all
+       other users.
+
+       If the NACM module is used, then it must be enabled (i.e.,
+       /nacm/enable-nacm object equals 'true'), or this extension
+       is ignored.
+
+       The 'default-deny-all' extension MAY appear within a data
+       definition statement, 'rpc' statement, or 'notification'
+       statement.  It is ignored otherwise.";
+  }
+
+  /*
+   * Derived types
+   */
+
+  typedef user-name-type {
+    type string {
+      length "1..max";
+    }
+    description
+      "General-purpose username string.";
+  }
+
+  typedef matchall-string-type {
+    type string {
+      pattern '\*';
+    }
+    description
+      "The string containing a single asterisk '*' is used
+       to conceptually represent all possible values
+       for the particular leaf using this data type.";
+  }
+
+  typedef access-operations-type {
+    type bits {
+      bit create {
+        description
+          "Any protocol operation that creates a
+           new data node.";
+        position 0;
+      }
+      bit read {
+        description
+          "Any protocol operation or notification that
+           returns the value of a data node.";
+        position 1;
+      }
+      bit update {
+        description
+          "Any protocol operation that alters an existing
+           data node.";
+        position 2;
+      }
+      bit delete {
+        description
+          "Any protocol operation that removes a data node.";
+        position 3;
+      }
+      bit exec {
+        description
+          "Execution access to the specified protocol operation.";
+        position 4;
+      }
+    }
+    description
+      "Access operation.";
+  }
+
+  typedef group-name-type {
+    type string {
+      length "1..max";
+      pattern '[^\*].*';
+    }
+    description
+      "Name of administrative group to which
+       users can be assigned.";
+  }
+
+  typedef action-type {
+    type enumeration {
+      enum permit {
+        description
+          "Requested action is permitted.";
+      }
+      enum deny {
+        description
+          "Requested action is denied.";
+      }
+    }
+    description
+      "Action taken by the server when a particular
+       rule matches.";
+  }
+
+  typedef node-instance-identifier {
+    type yang:xpath1.0;
+    description
+      "Path expression used to represent a special
+       data node, action, or notification instance-identifier
+       string.
+
+       A node-instance-identifier value is an
+       unrestricted YANG instance-identifier expression.
+       All the same rules as an instance-identifier apply,
+       except that predicates for keys are optional.  If a key
+       predicate is missing, then the node-instance-identifier
+       represents all possible server instances for that key.
+
+       This XML Path Language (XPath) expression is evaluated in the
+       following context:
+
+          o  The set of namespace declarations are those in scope on
+             the leaf element where this type is used.
+
+          o  The set of variable bindings contains one variable,
+             'USER', which contains the name of the user of the
+             current session.
+
+          o  The function library is the core function library, but
+             note that due to the syntax restrictions of an
+             instance-identifier, no functions are allowed.
+
+          o  The context node is the root node in the data tree.
+
+       The accessible tree includes actions and notifications tied
+       to data nodes.";
+  }
+
+  /*
+   * Data definition statements
+   */
+
+  container nacm {
+    nacm:default-deny-all;
+
+    description
+      "Parameters for NETCONF access control model.";
+
+    leaf enable-nacm {
+      type boolean;
+      default "true";
+      description
+        "Enables or disables all NETCONF access control
+         enforcement.  If 'true', then enforcement
+         is enabled.  If 'false', then enforcement
+         is disabled.";
+    }
+
+    leaf read-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether read access is granted if
+         no appropriate rule is found for a
+         particular read request.";
+    }
+
+    leaf write-default {
+      type action-type;
+      default "deny";
+      description
+        "Controls whether create, update, or delete access
+         is granted if no appropriate rule is found for a
+         particular write request.";
+    }
+
+    leaf exec-default {
+      type action-type;
+      default "permit";
+      description
+        "Controls whether exec access is granted if no appropriate
+         rule is found for a particular protocol operation request.";
+    }
+
+    leaf enable-external-groups {
+      type boolean;
+      default "true";
+      description
+        "Controls whether the server uses the groups reported by the
+         NETCONF transport layer when it assigns the user to a set of
+         NACM groups.  If this leaf has the value 'false', any group
+         names reported by the transport layer are ignored by the
+         server.";
+    }
+
+    leaf denied-operations {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request was denied.";
+    }
+
+    leaf denied-data-writes {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that a
+         protocol operation request to alter
+         a configuration datastore was denied.";
+    }
+
+    leaf denied-notifications {
+      type yang:zero-based-counter32;
+      config false;
+      mandatory true;
+      description
+        "Number of times since the server last restarted that
+         a notification was dropped for a subscription because
+         access to the event type was denied.";
+    }
+
+    container groups {
+      description
+        "NETCONF access control groups.";
+
+      list group {
+        key name;
+
+        description
+          "One NACM group entry.  This list will only contain
+           configured entries, not any entries learned from
+           any transport protocols.";
+
+        leaf name {
+          type group-name-type;
+          description
+            "Group name associated with this entry.";
+        }
+
+        leaf-list user-name {
+          type user-name-type;
+          description
+            "Each entry identifies the username of
+             a member of the group associated with
+             this entry.";
+        }
+      }
+    }
+
+    list rule-list {
+      key name;
+      ordered-by user;
+      description
+        "An ordered collection of access control rules.";
+
+      leaf name {
+        type string {
+          length "1..max";
+        }
+        description
+          "Arbitrary name assigned to the rule-list.";
+      }
+      leaf-list group {
+        type union {
+          type matchall-string-type;
+          type group-name-type;
+        }
+        description
+          "List of administrative groups that will be
+           assigned the associated access rights
+           defined by the 'rule' list.
+
+           The string '*' indicates that all groups apply to the
+           entry.";
+      }
+
+      list rule {
+        key name;
+        ordered-by user;
+        description
+          "One access control rule.
+
+           Rules are processed in user-defined order until a match is
+           found.  A rule matches if 'module-name', 'rule-type', and
+           'access-operations' match the request.  If a rule
+           matches, the 'action' leaf determines whether or not
+           access is granted.";
+
+        leaf name {
+          type string {
+            length "1..max";
+          }
+          description
+            "Arbitrary name assigned to the rule.";
+        }
+
+        leaf module-name {
+          type union {
+            type matchall-string-type;
+            type string;
+          }
+          default "*";
+          description
+            "Name of the module associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             object being accessed is defined in the module with the
+             specified module name.";
+        }
+        choice rule-type {
+          description
+            "This choice matches if all leafs present in the rule
+             match the request.  If no leafs are present, the
+             choice matches all requests.";
+          case protocol-operation {
+            leaf rpc-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if
+                 its value equals the requested protocol operation
+                 name.";
+            }
+          }
+          case notification {
+            leaf notification-name {
+              type union {
+                type matchall-string-type;
+                type string;
+              }
+              description
+                "This leaf matches if it has the value '*' or if its
+                 value equals the requested notification name.";
+            }
+          }
+          case data-node {
+            leaf path {
+              type node-instance-identifier;
+              mandatory true;
+              description
+                "Data node instance-identifier associated with the
+                 data node, action, or notification controlled by
+                 this rule.
+
+                 Configuration data or state data
+                 instance-identifiers start with a top-level
+                 data node.  A complete instance-identifier is
+                 required for this type of path value.
+
+                 The special value '/' refers to all possible
+                 datastore contents.";
+            }
+          }
+        }
+
+        leaf access-operations {
+          type union {
+            type matchall-string-type;
+            type access-operations-type;
+          }
+          default "*";
+          description
+            "Access operations associated with this rule.
+
+             This leaf matches if it has the value '*' or if the
+             bit corresponding to the requested operation is set.";
+        }
+
+        leaf action {
+          type action-type;
+          mandatory true;
+          description
+            "The access control action associated with the
+             rule.  If a rule has been determined to match a
+             particular request, then this object is used
+             to determine whether to permit or deny the
+             request.";
+        }
+
+        leaf comment {
+          type string;
+          description
+            "A textual description of the access rule.";
+        }
+      }
+    }
+  }
+}
diff --git a/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-yang-types@2013-07-15.yang b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-yang-types@2013-07-15.yang
new file mode 100644
index 0000000000000000000000000000000000000000..956562a7b342055127961732d8bde4be21c80d7d
--- /dev/null
+++ b/src/nbi/service/rest_server/nbi_plugins/ietf_l3vpn/yang/ietf-yang-types@2013-07-15.yang
@@ -0,0 +1,475 @@
+   module ietf-yang-types {
+
+     namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+     prefix "yang";
+
+     organization
+      "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+     contact
+      "WG Web:   <http://tools.ietf.org/wg/netmod/>
+       WG List:  <mailto:netmod@ietf.org>
+
+       WG Chair: David Kessens
+                 <mailto:david.kessens@nsn.com>
+
+       WG Chair: Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>
+
+       Editor:   Juergen Schoenwaelder
+                 <mailto:j.schoenwaelder@jacobs-university.de>";
+
+     description
+      "This module contains a collection of generally useful derived
+       YANG data types.
+
+       Copyright (c) 2013 IETF Trust and the persons identified as
+       authors of the code.  All rights reserved.
+
+       Redistribution and use in source and binary forms, with or
+       without modification, is permitted pursuant to, and subject
+       to the license terms contained in, the Simplified BSD License
+       set forth in Section 4.c of the IETF Trust's Legal Provisions
+       Relating to IETF Documents
+       (http://trustee.ietf.org/license-info).
+
+       This version of this YANG module is part of RFC 6991; see
+       the RFC itself for full legal notices.";
+
+     revision 2013-07-15 {
+       description
+        "This revision adds the following new data types:
+         - yang-identifier
+         - hex-string
+         - uuid
+         - dotted-quad";
+       reference
+        "RFC 6991: Common YANG Data Types";
+     }
+
+     revision 2010-09-24 {
+       description
+        "Initial revision.";
+       reference
+        "RFC 6021: Common YANG Data Types";
+     }
+
+     /*** collection of counter and gauge types ***/
+
+     typedef counter32 {
+       type uint32;
+       description
+        "The counter32 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter32 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter32 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter32.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter32 {
+       type yang:counter32;
+       default "0";
+       description
+        "The zero-based-counter32 type represents a counter32
+         that has the defined 'initial' value zero.
+
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^32-1 (4294967295 decimal), when it
+         wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+
+         In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter32 textual convention of the SMIv2.";
+       reference
+         "RFC 4502: Remote Network Monitoring Management Information
+                    Base Version 2";
+     }
+
+     typedef counter64 {
+       type uint64;
+       description
+        "The counter64 type represents a non-negative integer
+         that monotonically increases until it reaches a
+         maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Counters have no defined 'initial' value, and thus, a
+         single value of a counter has (in general) no information
+         content.  Discontinuities in the monotonically increasing
+         value normally occur at re-initialization of the
+         management system, and at other times as specified in the
+         description of a schema node using this type.  If such
+         other times can occur, for example, the creation of
+         a schema node of type counter64 at times other than
+         re-initialization, then a corresponding schema node
+         should be defined, with an appropriate type, to indicate
+         the last discontinuity.
+
+         The counter64 type should not be used for configuration
+         schema nodes.  A default statement SHOULD NOT be used in
+         combination with the type counter64.
+
+         In the value set and its semantics, this type is equivalent
+         to the Counter64 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef zero-based-counter64 {
+       type yang:counter64;
+       default "0";
+       description
+        "The zero-based-counter64 type represents a counter64 that
+         has the defined 'initial' value zero.
+
+         A schema node of this type will be set to zero (0) on creation
+         and will thereafter increase monotonically until it reaches
+         a maximum value of 2^64-1 (18446744073709551615 decimal),
+         when it wraps around and starts increasing again from zero.
+
+         Provided that an application discovers a new schema node
+         of this type within the minimum time to wrap, it can use the
+         'initial' value as a delta.  It is important for a management
+         station to be aware of this minimum time and the actual time
+         between polls, and to discard data if the actual time is too
+         long or there is no defined minimum time.
+
+         In the value set and its semantics, this type is equivalent
+         to the ZeroBasedCounter64 textual convention of the SMIv2.";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     typedef gauge32 {
+       type uint32;
+       description
+        "The gauge32 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^32-1 (4294967295 decimal), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge32 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge32 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the Gauge32 type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef gauge64 {
+       type uint64;
+       description
+        "The gauge64 type represents a non-negative integer, which
+         may increase or decrease, but shall never exceed a maximum
+         value, nor fall below a minimum value.  The maximum value
+         cannot be greater than 2^64-1 (18446744073709551615), and
+         the minimum value cannot be smaller than 0.  The value of
+         a gauge64 has its maximum value whenever the information
+         being modeled is greater than or equal to its maximum
+         value, and has its minimum value whenever the information
+         being modeled is smaller than or equal to its minimum value.
+         If the information being modeled subsequently decreases
+         below (increases above) the maximum (minimum) value, the
+         gauge64 also decreases (increases).
+
+         In the value set and its semantics, this type is equivalent
+         to the CounterBasedGauge64 SMIv2 textual convention defined
+         in RFC 2856";
+       reference
+        "RFC 2856: Textual Conventions for Additional High Capacity
+                   Data Types";
+     }
+
+     /*** collection of identifier-related types ***/
+
+     typedef object-identifier {
+       type string {
+         pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+               + '(\.(0|([1-9]\d*)))*';
+       }
+       description
+        "The object-identifier type represents administratively
+         assigned names in a registration-hierarchical-name tree.
+
+         Values of this type are denoted as a sequence of numerical
+         non-negative sub-identifier values.  Each sub-identifier
+         value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+         are separated by single dots and without any intermediate
+         whitespace.
+
+         The ASN.1 standard restricts the value space of the first
+         sub-identifier to 0, 1, or 2.  Furthermore, the value space
+         of the second sub-identifier is restricted to the range
+         0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+         the ASN.1 standard requires that an object identifier
+         has always at least two sub-identifiers.  The pattern
+         captures these restrictions.
+
+         Although the number of sub-identifiers is not limited,
+         module designers should realize that there may be
+         implementations that stick with the SMIv2 limit of 128
+         sub-identifiers.
+
+         This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+         since it is not restricted to 128 sub-identifiers.  Hence,
+         this type SHOULD NOT be used to represent the SMIv2 OBJECT
+         IDENTIFIER type; the object-identifier-128 type SHOULD be
+         used instead.";
+       reference
+        "ISO9834-1: Information technology -- Open Systems
+         Interconnection -- Procedures for the operation of OSI
+         Registration Authorities: General procedures and top
+         arcs of the ASN.1 Object Identifier tree";
+     }
+
+     typedef object-identifier-128 {
+       type object-identifier {
+         pattern '\d*(\.\d*){1,127}';
+       }
+       description
+        "This type represents object-identifiers restricted to 128
+         sub-identifiers.
+
+         In the value set and its semantics, this type is equivalent
+         to the OBJECT IDENTIFIER type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef yang-identifier {
+       type string {
+         length "1..max";
+         pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+         pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+       }
+       description
+         "A YANG identifier string as defined by the 'identifier'
+          rule in Section 12 of RFC 6020.  An identifier must
+          start with an alphabetic character or an underscore
+          followed by an arbitrary sequence of alphabetic or
+          numeric characters, underscores, hyphens, or dots.
+
+          A YANG identifier MUST NOT start with any possible
+          combination of the lowercase or uppercase character
+          sequence 'xml'.";
+       reference
+         "RFC 6020: YANG - A Data Modeling Language for the Network
+                    Configuration Protocol (NETCONF)";
+     }
+
+     /*** collection of types related to date and time***/
+
+     typedef date-and-time {
+       type string {
+         pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+               + '(Z|[\+\-]\d{2}:\d{2})';
+       }
+       description
+        "The date-and-time type is a profile of the ISO 8601
+         standard for representation of dates and times using the
+         Gregorian calendar.  The profile is defined by the
+         date-time production in Section 5.6 of RFC 3339.
+
+         The date-and-time type is compatible with the dateTime XML
+         schema type with the following notable exceptions:
+
+         (a) The date-and-time type does not allow negative years.
+
+         (b) The date-and-time time-offset -00:00 indicates an unknown
+             time zone (see RFC 3339) while -00:00 and +00:00 and Z
+             all represent the same time zone in dateTime.
+
+         (c) The canonical format (see below) of data-and-time values
+             differs from the canonical format used by the dateTime XML
+             schema type, which requires all times to be in UTC using
+             the time-offset 'Z'.
+
+         This type is not equivalent to the DateAndTime textual
+         convention of the SMIv2 since RFC 3339 uses a different
+         separator between full-date and full-time and provides
+         higher resolution of time-secfrac.
+
+         The canonical format for date-and-time values with a known time
+         zone uses a numeric time zone offset that is calculated using
+         the device's configured known offset to UTC time.  A change of
+         the device's offset to UTC time will cause date-and-time values
+         to change accordingly.  Such changes might happen periodically
+         in case a server follows automatically daylight saving time
+         (DST) time zone offset changes.  The canonical format for
+         date-and-time values with an unknown time zone (usually
+         referring to the notion of local time) uses the time-offset
+         -00:00.";
+       reference
+        "RFC 3339: Date and Time on the Internet: Timestamps
+         RFC 2579: Textual Conventions for SMIv2
+         XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+     }
+
+     typedef timeticks {
+       type uint32;
+       description
+        "The timeticks type represents a non-negative integer that
+         represents the time, modulo 2^32 (4294967296 decimal), in
+         hundredths of a second between two epochs.  When a schema
+         node is defined that uses this type, the description of
+         the schema node identifies both of the reference epochs.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeTicks type of the SMIv2.";
+       reference
+        "RFC 2578: Structure of Management Information Version 2
+                   (SMIv2)";
+     }
+
+     typedef timestamp {
+       type yang:timeticks;
+       description
+        "The timestamp type represents the value of an associated
+         timeticks schema node at which a specific occurrence
+         happened.  The specific occurrence must be defined in the
+         description of any schema node defined using this type.  When
+         the specific occurrence occurred prior to the last time the
+         associated timeticks attribute was zero, then the timestamp
+         value is zero.  Note that this requires all timestamp values
+         to be reset to zero when the value of the associated timeticks
+         attribute reaches 497+ days and wraps around to zero.
+
+         The associated timeticks schema node must be specified
+         in the description of any schema node using this type.
+
+         In the value set and its semantics, this type is equivalent
+         to the TimeStamp textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of generic address types ***/
+
+     typedef phys-address {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+
+       description
+        "Represents media- or physical-level addresses represented
+         as a sequence octets, each octet represented by two hexadecimal
+         numbers.  Octets are separated by colons.  The canonical
+         representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the PhysAddress textual convention of the SMIv2.";
+       reference
+        "RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     typedef mac-address {
+       type string {
+         pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+       }
+       description
+        "The mac-address type represents an IEEE 802 MAC address.
+         The canonical representation uses lowercase characters.
+
+         In the value set and its semantics, this type is equivalent
+         to the MacAddress textual convention of the SMIv2.";
+       reference
+        "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                   Networks: Overview and Architecture
+         RFC 2579: Textual Conventions for SMIv2";
+     }
+
+     /*** collection of XML-specific types ***/
+
+     typedef xpath1.0 {
+       type string;
+       description
+        "This type represents an XPATH 1.0 expression.
+
+         When a schema node is defined that uses this type, the
+         description of the schema node MUST specify the XPath
+         context in which the XPath expression is evaluated.";
+       reference
+        "XPATH: XML Path Language (XPath) Version 1.0";
+     }
+
+     /*** collection of string types ***/
+
+     typedef hex-string {
+       type string {
+         pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+       }
+
+       description
+        "A hexadecimal string with octets represented as hex digits
+         separated by colons.  The canonical representation uses
+         lowercase characters.";
+     }
+
+     typedef uuid {
+       type string {
+         pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+               + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+       }
+       description
+        "A Universally Unique IDentifier in the string representation
+         defined in RFC 4122.  The canonical representation uses
+         lowercase characters.
+
+         The following is an example of a UUID in string representation:
+         f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+         ";
+       reference
+        "RFC 4122: A Universally Unique IDentifier (UUID) URN
+                   Namespace";
+     }
+
+     typedef dotted-quad {
+       type string {
+         pattern
+           '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+         + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+       }
+       description
+         "An unsigned 32-bit number expressed in the dotted-quad
+          notation, i.e., four octets written as decimal numbers
+          and separated with the '.' (full stop) character.";
+     }
+   }
diff --git a/src/nbi/tests/PrepareTestScenario.py b/src/nbi/tests/PrepareTestScenario.py
index 88a77b6e099763c5c7c6dda291374bc2fc6e6f80..3c1fb2739cffe5f77815bb26beddad5fc705557a 100644
--- a/src/nbi/tests/PrepareTestScenario.py
+++ b/src/nbi/tests/PrepareTestScenario.py
@@ -23,6 +23,7 @@ from context.client.ContextClient import ContextClient
 from nbi.service.rest_server.RestServer import RestServer
 from nbi.service.rest_server.nbi_plugins.debug_api import register_debug_api
 from nbi.service.rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
+from nbi.service.rest_server.nbi_plugins.ietf_l3vpn import register_ietf_l3vpn
 from nbi.service.rest_server.nbi_plugins.ietf_network import register_ietf_network
 from nbi.tests.MockService_Dependencies import MockService_Dependencies
 from service.client.ServiceClient import ServiceClient
@@ -49,6 +50,7 @@ def nbi_service_rest(mock_service : MockService_Dependencies):  # pylint: disabl
     _rest_server = RestServer()
     register_debug_api(_rest_server)
     register_ietf_l2vpn(_rest_server)
+    register_ietf_l3vpn(_rest_server)
     register_ietf_network(_rest_server)
     _rest_server.start()
     time.sleep(1) # bring time for the server to start
diff --git a/src/nbi/tests/data/ietf_l3vpn_req_svc1.json b/src/nbi/tests/data/ietf_l3vpn_req_svc1.json
new file mode 100644
index 0000000000000000000000000000000000000000..66e253cb5b99d3b758bba04e1dfa8799e1b13c08
--- /dev/null
+++ b/src/nbi/tests/data/ietf_l3vpn_req_svc1.json
@@ -0,0 +1,231 @@
+{
+  "ietf-l3vpn-svc:l3vpn-svc": {
+    "vpn-services": {
+      "vpn-service": [
+        {
+          "vpn-id": "vpn1"
+        }
+      ]
+    },
+    "sites": {
+      "site": [
+        {
+          "site-id": "site_OLT",
+          "management": {
+            "type": "ietf-l3vpn-svc:provider-managed"
+          },
+          "locations": {
+            "location": [
+              {
+                "location-id": "OLT"
+              }
+            ]
+          },
+          "devices": {
+            "device": [
+              {
+                "device-id": "128.32.33.5",
+                "location": "OLT"
+              }
+            ]
+          },
+          "routing-protocols": {
+            "routing-protocol": [
+              {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                  "cascaded-lan-prefixes": {
+                    "ipv4-lan-prefixes": [
+                      {
+                        "lan": "128.32.10.1/24",
+                        "lan-tag": "vlan21",
+                        "next-hop": "128.32.33.5"
+                      },
+                      {
+                        "lan": "128.32.20.1/24",
+                        "lan-tag": "vlan21",
+                        "next-hop": "128.32.33.5"
+                      }
+                    ]
+                  }
+                }
+              }
+            ]
+          },
+          "site-network-accesses": {
+            "site-network-access": [
+              {
+                "site-network-access-id": "500",
+                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                "device-reference": "128.32.33.5",
+                "vpn-attachment": {
+                  "vpn-id": "vpn1",
+                  "site-role": "ietf-l3vpn-svc:spoke-role"
+                },
+                "ip-connection": {
+                  "ipv4": {
+                    "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                    "addresses": {
+                      "provider-address": "128.32.33.254",
+                      "customer-address": "128.32.33.2",
+                      "prefix-length": 24
+                    }
+                  }
+                },
+                "routing-protocols": {
+                  "routing-protocol": [
+                    {
+                      "type": "ietf-l3vpn-svc:static",
+                      "static": {
+                        "cascaded-lan-prefixes": {
+                          "ipv4-lan-prefixes": [
+                            {
+                              "lan": "172.1.101.1/24",
+                              "lan-tag": "vlan21",
+                              "next-hop": "10.0.10.1"
+                            }
+                          ]
+                        }
+                      }
+                    }
+                  ]
+                },
+                "service": {
+                  "svc-mtu": 1500,
+                  "svc-input-bandwidth": 1000000000,
+                  "svc-output-bandwidth": 1000000000,
+                  "qos": {
+                    "qos-profile": {
+                      "classes": {
+                        "class": [
+                          {
+                            "class-id": "qos-realtime",
+                            "direction": "ietf-l3vpn-svc:both",
+                            "latency": {
+                              "latency-boundary": 10
+                            },
+                            "bandwidth": {
+                              "guaranteed-bw-percent": 100
+                            }
+                          }
+                        ]
+                      }
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        },
+        {
+          "site-id": "site_POP",
+          "management": {
+            "type": "ietf-l3vpn-svc:provider-managed"
+          },
+          "locations": {
+            "location": [
+              {
+                "location-id": "POP"
+              }
+            ]
+          },
+          "devices": {
+            "device": [
+              {
+                "device-id": "172.10.33.5",
+                "location": "POP"
+              }
+            ]
+          },
+          "routing-protocols": {
+            "routing-protocol": [
+              {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                  "cascaded-lan-prefixes": {
+                    "ipv4-lan-prefixes": [
+                      {
+                        "lan": "172.1.101.1/24",
+                        "lan-tag": "vlan101",
+                        "next-hop": "172.10.33.5"
+                      }
+                    ]
+                  }
+                }
+              }
+            ]
+          },
+          "site-network-accesses": {
+            "site-network-access": [
+              {
+                "site-network-access-id": "500",
+                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                "device-reference": "172.10.33.5",
+                "vpn-attachment": {
+                  "vpn-id": "vpn1",
+                  "site-role": "ietf-l3vpn-svc:hub-role"
+                },
+                "ip-connection": {
+                  "ipv4": {
+                    "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                    "addresses": {
+                      "provider-address": "172.10.33.254",
+                      "customer-address": "172.10.33.2",
+                      "prefix-length": 24
+                    }
+                  }
+                },
+                "routing-protocols": {
+                  "routing-protocol": [
+                    {
+                      "type": "ietf-l3vpn-svc:static",
+                      "static": {
+                        "cascaded-lan-prefixes": {
+                          "ipv4-lan-prefixes": [
+                            {
+                              "lan": "128.32.10.1/24",
+                              "lan-tag": "vlan101",
+                              "next-hop": "10.0.30.1"
+                            },
+                            {
+                              "lan": "128.32.20.1/24",
+                              "lan-tag": "vlan101",
+                              "next-hop": "10.0.30.1"
+                            }
+                          ]
+                        }
+                      }
+                    }
+                  ]
+                },
+                "service": {
+                  "svc-mtu": 1500,
+                  "svc-input-bandwidth": 1000000000,
+                  "svc-output-bandwidth": 1000000000,
+                  "qos": {
+                    "qos-profile": {
+                      "classes": {
+                        "class": [
+                          {
+                            "class-id": "qos-realtime",
+                            "direction": "ietf-l3vpn-svc:both",
+                            "latency": {
+                              "latency-boundary": 10
+                            },
+                            "bandwidth": {
+                              "guaranteed-bw-percent": 100
+                            }
+                          }
+                        ]
+                      }
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/nbi/tests/data/ietf_l3vpn_req_svc2.json b/src/nbi/tests/data/ietf_l3vpn_req_svc2.json
new file mode 100644
index 0000000000000000000000000000000000000000..fa142f4fa318df8469d8bb057d34261a98664af1
--- /dev/null
+++ b/src/nbi/tests/data/ietf_l3vpn_req_svc2.json
@@ -0,0 +1,231 @@
+{
+  "ietf-l3vpn-svc:l3vpn-svc": {
+    "vpn-services": {
+      "vpn-service": [
+        {
+          "vpn-id": "vpn2"
+        }
+      ]
+    },
+    "sites": {
+      "site": [
+        {
+          "site-id": "site_OLT",
+          "management": {
+            "type": "ietf-l3vpn-svc:provider-managed"
+          },
+          "locations": {
+            "location": [
+              {
+                "location-id": "OLT"
+              }
+            ]
+          },
+          "devices": {
+            "device": [
+              {
+                "device-id": "128.32.33.5",
+                "location": "OLT"
+              }
+            ]
+          },
+          "routing-protocols": {
+            "routing-protocol": [
+              {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                  "cascaded-lan-prefixes": {
+                    "ipv4-lan-prefixes": [
+                      {
+                        "lan": "128.32.10.1/24",
+                        "lan-tag": "vlan31",
+                        "next-hop": "128.32.33.5"
+                      },
+                      {
+                        "lan": "128.32.20.1/24",
+                        "lan-tag": "vlan31",
+                        "next-hop": "128.32.33.5"
+                      }
+                    ]
+                  }
+                }
+              }
+            ]
+          },
+          "site-network-accesses": {
+            "site-network-access": [
+              {
+                "site-network-access-id": "service access 3",
+                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                "device-reference": "128.32.33.5",
+                "vpn-attachment": {
+                  "vpn-id": "vpn2",
+                  "site-role": "ietf-l3vpn-svc:spoke-role"
+                },
+                "ip-connection": {
+                  "ipv4": {
+                    "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                    "addresses": {
+                      "provider-address": "128.32.33.254",
+                      "customer-address": "128.32.33.2",
+                      "prefix-length": 24
+                    }
+                  }
+                },
+                "routing-protocols": {
+                  "routing-protocol": [
+                    {
+                      "type": "ietf-l3vpn-svc:static",
+                      "static": {
+                        "cascaded-lan-prefixes": {
+                          "ipv4-lan-prefixes": [
+                            {
+                              "lan": "172.1.101.1/24",
+                              "lan-tag": "vlan31",
+                              "next-hop": "10.0.10.1"
+                            }
+                          ]
+                        }
+                      }
+                    }
+                  ]
+                },
+                "service": {
+                  "svc-mtu": 1500,
+                  "svc-input-bandwidth": 1000000000,
+                  "svc-output-bandwidth": 1000000000,
+                  "qos": {
+                    "qos-profile": {
+                      "classes": {
+                        "class": [
+                          {
+                            "class-id": "qos-realtime",
+                            "direction": "ietf-l3vpn-svc:both",
+                            "latency": {
+                              "latency-boundary": 10
+                            },
+                            "bandwidth": {
+                              "guaranteed-bw-percent": 100
+                            }
+                          }
+                        ]
+                      }
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        },
+        {
+          "site-id": "site_POP",
+          "management": {
+            "type": "ietf-l3vpn-svc:provider-managed"
+          },
+          "locations": {
+            "location": [
+              {
+                "location-id": "POP"
+              }
+            ]
+          },
+          "devices": {
+            "device": [
+              {
+                "device-id": "172.10.33.5",
+                "location": "POP"
+              }
+            ]
+          },
+          "routing-protocols": {
+            "routing-protocol": [
+              {
+                "type": "ietf-l3vpn-svc:static",
+                "static": {
+                  "cascaded-lan-prefixes": {
+                    "ipv4-lan-prefixes": [
+                      {
+                        "lan": "172.1.101.1/24",
+                        "lan-tag": "vlan201",
+                        "next-hop": "172.10.33.1"
+                      }
+                    ]
+                  }
+                }
+              }
+            ]
+          },
+          "site-network-accesses": {
+            "site-network-access": [
+              {
+                "site-network-access-id": "service access 4",
+                "site-network-access-type": "ietf-l3vpn-svc:multipoint",
+                "device-reference": "172.10.33.5",
+                "vpn-attachment": {
+                  "vpn-id": "vpn2",
+                  "site-role": "ietf-l3vpn-svc:hub-role"
+                },
+                "ip-connection": {
+                  "ipv4": {
+                    "address-allocation-type": "ietf-l3vpn-svc:static-address",
+                    "addresses": {
+                      "provider-address": "172.10.33.254",
+                      "customer-address": "172.10.33.2",
+                      "prefix-length": 24
+                    }
+                  }
+                },
+                "routing-protocols": {
+                  "routing-protocol": [
+                    {
+                      "type": "ietf-l3vpn-svc:static",
+                      "static": {
+                        "cascaded-lan-prefixes": {
+                          "ipv4-lan-prefixes": [
+                            {
+                              "lan": "128.32.10.1/24",
+                              "lan-tag": "vlan201",
+                              "next-hop": "10.0.30.1"
+                            },
+                            {
+                              "lan": "128.32.20.1/24",
+                              "lan-tag": "vlan201",
+                              "next-hop": "10.0.30.1"
+                            }
+                          ]
+                        }
+                      }
+                    }
+                  ]
+                },
+                "service": {
+                  "svc-mtu": 1500,
+                  "svc-input-bandwidth": 1000000000,
+                  "svc-output-bandwidth": 1000000000,
+                  "qos": {
+                    "qos-profile": {
+                      "classes": {
+                        "class": [
+                          {
+                            "class-id": "qos-realtime",
+                            "direction": "ietf-l3vpn-svc:both",
+                            "latency": {
+                              "latency-boundary": 10
+                            },
+                            "bandwidth": {
+                              "guaranteed-bw-percent": 100
+                            }
+                          }
+                        ]
+                      }
+                    }
+                  }
+                }
+              }
+            ]
+          }
+        }
+      ]
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/nbi/tests/test_ietf_l3vpn.py b/src/nbi/tests/test_ietf_l3vpn.py
new file mode 100644
index 0000000000000000000000000000000000000000..17f3c3e93c627c41ddc344e55b3478d13077efb3
--- /dev/null
+++ b/src/nbi/tests/test_ietf_l3vpn.py
@@ -0,0 +1,113 @@
+# 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 json, logging, pytest
+from typing import Dict
+from common.Constants import DEFAULT_CONTEXT_NAME
+from common.proto.context_pb2 import ContextId
+from common.tools.descriptor.Loader import (
+    DescriptorLoader, check_descriptor_load_results, validate_empty_scenario
+)
+from common.tools.object_factory.Context import json_context_id
+from context.client.ContextClient import ContextClient
+from nbi.service.rest_server import RestServer
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    do_rest_delete_request, do_rest_get_request, do_rest_post_request,
+    mock_service, nbi_service_rest, osm_wim, context_client
+)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DESCRIPTOR_FILE = 'nbi/tests/data/topology-dummy.json'
+SVC1_DATA_FILE  = 'nbi/tests/data/ietf_l3vpn_req_svc1.json'
+SVC2_DATA_FILE  = 'nbi/tests/data/ietf_l3vpn_req_svc2.json'
+
+JSON_ADMIN_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_NAME)
+ADMIN_CONTEXT_ID = ContextId(**JSON_ADMIN_CONTEXT_ID)
+
+@pytest.fixture(scope='session')
+def storage() -> Dict:
+    yield dict()
+
+def test_prepare_environment(context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
+    validate_empty_scenario(context_client)
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    results = descriptor_loader.process()
+    check_descriptor_load_results(results, descriptor_loader)
+    descriptor_loader.validate()
+
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.topology_ids) == 1
+    assert len(response.service_ids ) == 0
+    assert len(response.slice_ids   ) == 0
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_create_svc1(nbi_service_rest : RestServer, storage : Dict):
+    with open(SVC1_DATA_FILE, 'r', encoding='UTF-8') as f:
+        svc1_data = json.load(f)
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services'
+    do_rest_post_request(URL, body=svc1_data, logger=LOGGER, expected_status_codes={201})
+    storage['svc1-uuid'] = svc1_data['ietf-l3vpn-svc:l3vpn-svc']['vpn-services']['vpn-service'][0]['vpn-id']
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_create_svc2(nbi_service_rest : RestServer, storage : Dict):
+    with open(SVC2_DATA_FILE, 'r', encoding='UTF-8') as f:
+        svc2_data = json.load(f)
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services'
+    do_rest_post_request(URL, body=svc2_data, logger=LOGGER, expected_status_codes={201})
+    storage['svc2-uuid'] = svc2_data['ietf-l3vpn-svc:l3vpn-svc']['vpn-services']['vpn-service'][0]['vpn-id']
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_get_state_svc1(nbi_service_rest : RestServer, storage : Dict):
+    assert 'svc1-uuid' in storage
+    service_uuid = storage['svc1-uuid']
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service={:s}/'.format(service_uuid)
+    do_rest_get_request(URL, logger=LOGGER, expected_status_codes={200})
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_get_state_svc2(nbi_service_rest : RestServer, storage : Dict):
+    assert 'svc2-uuid' in storage
+    service_uuid = storage['svc2-uuid']
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service={:s}/'.format(service_uuid)
+    do_rest_get_request(URL, logger=LOGGER, expected_status_codes={200})
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_delete_svc1(nbi_service_rest : RestServer, storage : Dict):
+    assert 'svc1-uuid' in storage
+    service_uuid = storage['svc1-uuid']
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service={:s}/'.format(service_uuid)
+    do_rest_delete_request(URL, logger=LOGGER, expected_status_codes={204})
+
+# pylint: disable=redefined-outer-name, unused-argument
+def test_delete_svc2(nbi_service_rest : RestServer, storage : Dict):
+    assert 'svc2-uuid' in storage
+    service_uuid = storage['svc2-uuid']
+    URL = '/restconf/data/ietf-l3vpn-svc:l3vpn-svc/vpn-services/vpn-service={:s}/'.format(service_uuid)
+    do_rest_delete_request(URL, logger=LOGGER, expected_status_codes={204})
+
+def test_cleanup_environment(context_client : ContextClient) -> None: # pylint: disable=redefined-outer-name
+    # Verify the scenario has no services/slices
+    response = context_client.GetContext(ADMIN_CONTEXT_ID)
+    assert len(response.topology_ids) == 1
+    assert len(response.service_ids ) == 0
+    assert len(response.slice_ids   ) == 0
+
+    # Load descriptors and validate the base scenario
+    descriptor_loader = DescriptorLoader(descriptors_file=DESCRIPTOR_FILE, context_client=context_client)
+    descriptor_loader.validate()
+    descriptor_loader.unload()
+    validate_empty_scenario(context_client)