BESS Working Group                                          H. Shah, Ed.
Internet-Draft                                         Ciena Corporation
Intended status: Standards Track                       P. Brissette, Ed.
Expires: September 14, 2017 January 1, 2018                             Cisco Systems, Inc.
                                                            I. Chen, Ed.
                                                                   Jabil
                                                         I. Hussain, Ed.
                                                    Infinera Corporation
                                                             B. Wen, Ed.
                                                                 Comcast
                                                    K. Tiruveedhula, Ed.
                                                        Juniper Networks
                                                          March 13,
                                                           June 30, 2017

                  YANG Data Model for MPLS-based L2VPN
                   draft-ietf-bess-l2vpn-yang-05.txt
                   draft-ietf-bess-l2vpn-yang-06.txt

Abstract

   This document describes a YANG data model for Layer 2 VPN (L2VPN)
   services over MPLS networks.  These services include point-to-point
   Virtual Private Wire Service (VPWS) and multipoint Virtual Private
   LAN service (VPLS) that uses LDP and BGP signaled Pseudowires.  It is
   expected that this model will be used by the management tools run by
   the network operators in order to manage and monitor the network
   resources that they use to deliver L2VPN services.

   This document also describes the YANG data model for the Pseudowires.
   The independent definition of the Pseudowires facilitates its use in
   Ethernet Segment and EVPN data models defined in separate document.

Status of This Memo

   This Internet-Draft is submitted in full conformance with the
   provisions of BCP 78 and BCP 79.

   Internet-Drafts are working documents of the Internet Engineering
   Task Force (IETF).  Note that other groups may also distribute
   working documents as Internet-Drafts.  The list of current Internet-
   Drafts is at http://datatracker.ietf.org/drafts/current/.

   Internet-Drafts are draft documents valid for a maximum of six months
   and may be updated, replaced, or obsoleted by other documents at any
   time.  It is inappropriate to use Internet-Drafts as reference
   material or to cite them other than as "work in progress."

   This Internet-Draft will expire on September 14, 2017. January 1, 2018.

Copyright Notice

   Copyright (c) 2017 IETF Trust and the persons identified as the
   document authors.  All rights reserved.

   This document is subject to BCP 78 and the IETF Trust's Legal
   Provisions Relating to IETF Documents
   (http://trustee.ietf.org/license-info) in effect on the date of
   publication of this document.  Please review these documents
   carefully, as they describe your rights and restrictions with respect
   to this document.  Code Components extracted from this document must
   include Simplified BSD License text as described in Section 4.e of
   the Trust Legal Provisions and are provided without warranty as
   described in the Simplified BSD License.

Table of Contents

   1.  Introduction  . . . . . . . . . . . . . . . . . . . . . . . .   2   3
   2.  Specification of Requirements . . . . . . . . . . . . . . . .   4
   3.  L2VPN YANG Model  . . . . . . . . . . . . . . . . . . . . . .   4
     3.1.  Overview  . . . . . . . . . . . . . . . . . . . . . . . .   4
     3.2.  Open issues and next steps  . . . . . . . . . . . . . . .   7
     3.3.  L2VPN  Pseudowire Common . . . . . . . . . . . . . . . . . . . .   8
       3.3.1.  Pseudowire  . . . . . . . . . . . . . . . . . . . . .   8
       3.3.1.
       3.3.2.  pw-templates  . . . . . . . . . . . . . . . . . . . .   8
       3.3.2.
     3.4.  L2VPN Common  . . . . . . . . . . . . . . . . . . . . . .   8
       3.4.1.  redundancy-group-templates  . . . . . . . . . . . . .   8
     3.4.
     3.5.  L2VPN instance  . . . . . . . . . . . . . . . . . . . . .   8
       3.4.1.
       3.5.1.  common attributes . . . . . . . . . . . . . . . . . .   8
       3.4.2.
       3.5.2.  PW list . . . . . . . . . . . . . . . . . . . . . . .   8
       3.4.3.
       3.5.3.  List of endpoints . . . . . . . . . . . . . . . . . .   8
       3.4.4.   9
       3.5.4.  point-to-point or multipoint service  . . . . . . . .  10
     3.5.
     3.6.  Operational State . . . . . . . . . . . . . . . . . . . .  10
     3.6.
     3.7.  Yang tree . . . . . . . . . . . . . . . . . . . . . . . .  10
   4.  YANG Module . . . . . . . . . . . . . . . . . . . . . . . . .  15  13
   5.  Security Considerations . . . . . . . . . . . . . . . . . . .  38  40
   6.  IANA Considerations . . . . . . . . . . . . . . . . . . . . .  39  41
   7.  Acknowledgments . . . . . . . . . . . . . . . . . . . . . . .  39  41
   8.  References  . . . . . . . . . . . . . . . . . . . . . . . . .  39  41
     8.1.  Normative References  . . . . . . . . . . . . . . . . . .  39  41
     8.2.  Informative References  . . . . . . . . . . . . . . . . .  39  41
   Appendix A.  Example Configuration  . . . . . . . . . . . . . . .  42  44
   Appendix B.  Contributors . . . . . . . . . . . . . . . . . . . .  42  44
   Authors' Addresses  . . . . . . . . . . . . . . . . . . . . . . .  43  45

1.  Introduction

   The Network Configuration Protocol (NETCONF) [RFC6241] is a network
   management protocol that defines mechanisms to manage network
   devices.  YANG [RFC6020] is a modular language that represents data
   structures in an XML or JSON tree format, and is used as a data
   modeling language for the NETCONF.

   This document defines a YANG data model for MPLS based Layer 2 VPN
   services (L2VPN) [RFC4664] and includes switching between the local
   attachment circuits.  The L2VPN model covers point-to-point VPWS and
   Multipoint VPLS services.  These services use signaling of
   Pseudowires across MPLS networks using LDP [RFC4447][RFC4762] or
   BGP[RFC4761].

   Initially, the data model covers Ethernet based Layer 2 services.
   The Ethernet Attachment Circuits are not defined.  Instead, they are
   leveraged from other standards organizations such as IEEE802.1 and
   Metro Ethernet Forum (MEF).

   Other Layer 2 services, such as ATM, Frame Relay, TDM, etc are
   included in the scope but will be covered as the future work items.

   The objective of the model is to define building blocks that can be
   easily assembled in different order to realize different services.

   The data model uses following constructs for configuration and
   management:

   o  Configuration

   o  Operational State

   o  Executables (Actions)

   o  Notifications

   The current document focuses on definition of configuration and configuration, state
   objects.  The future revisions are expected to cover the actions
   and
   notifications aspects of the model. notificationobjects.

   The L2VPN data object model uses the instance centric approach.
   Within an L2VPN instance; a set of common parameters, a list of PWs
   and a list of endpoints are defined.  A special constraint is added
   for the VPWS configuration such that only two endpoints are allowed
   in the list of endpoints.  This deviates from

   The Pseudowire data object model is defined independent of the previous versions
   where endpoint-a L2VPN
   data object model to allow its inclusion in the Ethernet Segment and endpoint-z were defined separately from
   EVPN data objects.

   The L2VPN data object model augments Psuedowire data object for its
   definition.

   The document also includes Notifications used by the
   endpoint list. L2VPN object
   model

2.  Specification of Requirements

   The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
   "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
   document are to be interpreted as described in [RFC2119].

3.  L2VPN YANG Model

3.1.  Overview

   In this version of the document, for configuration, one single
   container, l2vpn, is defined.  Within the l2vpn container, common
   parameters and a list of endpoints are defined.  For the point-to-
   point VPWS configuration, endpoint list is used with the constraint
   that limits the number of endpoints to be two.  For the multipoint
   service, endpoint list is used.  Each endpoint contains the common
   definition that is either an attachment circuit, a pseudowire or a
   redundancy group.  The YANG data model for l2vpn in this document is
   greatly simplified by by removing separate definition of endpoint-a
   and endpoint-z that was specific for VPWS service.  The same endpoint
   list is used by both the VPLS and VPWS service with the exception
   that VPWS uses only two entries.

   The l2vpn container also includes definition of common building
   blocks for redundancy-grp templates and pseudowire-templates.

   The operations state object holds read-only information of State objects
   that has either have been configured or dynamically created. consolidated with the configuration
   object as per the recommendations provided by the Guidelines for Yang
   Module Authors document.

   The IETF working group has defined the VPWS and VPLS services that
   leverages the pseudowire technologies defined by the PWE3 working
   group.  A large number of RFCs from these working groups cover this
   subject matter.  Hence, it is prudent that this document state the
   scope of the MPLS L2VPN object model definitions.

   The following documents are within the scope.  This is not an
   exhaustive list but a representation of documents that are covered
   for this work:

   o  Requirements for Pseudo-wire Emulation Edge-to-Edge (PWE3)
      [RFC3916]

   o  Pseudo-wire Emulation Edge-to-Edge (PWE3) Architecture [RFC3985]

   o  IANA Allocations for Pseudowire Edge to Edge Emulation (PWE3)
      [RFC4446]

   o  Pseudowire Setup and Maintenance Using the Label Distribution
      Protocol (LDP) [RFC4447]

   o  Encapsulation Methods for Transport of Ethernet over MPLS Networks
      [RFC4448]

   o  Pseudowire Emulation Edge-to-Edge (PWE3) Control Word for Use over
      an MPLS PSN [RFC4385]

   o  Requirements for Multi-Segment Pseudowire Emulation Edge-to-Edge
      (PWE3) [RFC5254]

   o  An Architecture for Multi-Segment Pseudowire Emulation Edge-to-
      Edge [RFC5659]

   o  Segmented Pseudowire [RFC6073]

   o  Framework for Layer 2 Virtual Private Networks [RFC4664]

   o  Service Requirements for Layer 2 Provider-Provisioned Virtual
      Private Networks [RFC4665]

   o  Virtual Private LAN Service (VPLS) Using BGP for Auto-Discovery
      and Signaling [RFC4761]

   o  Virtual Private LAN Service (VPLS) Using Label Distribution
      Protocol (LDP) Signaling [RFC4762]

   o  Attachment Individual Identifier (AII) Types for Aggregation
      [RFC5003]

   o  Provisioning, Auto-Discovery, and Signaling in Layer 2 Virtual
      Private Networks (L2VPNs) [RFC6074]

   o  Flow-Aware Transport of Pseudowires over an MPLS Packet Switched
      Network [RFC6391]

   o  Layer 2 Virtual Private Networks Using BGP for Auto-Discovery and
      Signaling [RFC6624]

   o  Extensions to the Virtual Private LAN Service (VPLS) Provider Edge
      (PE) Model for Provider Backbone Bridging [RFC7041]

   o  LDP Extensions for Optimized MAC Address Withdrawal in a
      Hierarchical Virtual Private LAN Service (H-VPLS) [RFC7361]

   o  Using the generic associated channel label for Pseudowire in the
      MPLS Transport Profile [RFC6423]

   o  Pseudowire status for static pseudowire [RFC6478]

   The specifics of pseudowire over MPLS-TP LSPs is in scope.  However,
   the initial effort addresses definitions of object models that are
   commonly deployed.

   The IETF work in L2VPN and PWE3 working group relating to L2TP, OAM,
   multicast (e.g. p2mp, etree, etc) and access specific protocols such
   as G.8032, MSTP, etc is out-of-scope for this document.

   The following is the high level view of the L2VPN data model.

 template-ref

 PW // Container
         PW
                    template specific attributes

         PW template definition

 template-ref Redundancy-Group // redundancy-group
                    template
                    attributes

 l2vpn-instances // containter

         common attributes

         BGP-parameters // container
                           common attributes
                           auto-discovery attributes
                           signaling attributes

         // list of PWs being used
         PW // container
                 template-ref PW
                 attribute-override

         PBB-parameters // container
                           pbb specific attributes

         VPWS-constraints // rule to limit number of endpoints to two

         // List of endpoints, where each member endpoint container is -
                 PW // reference
                 redundancy-grp // container
                         AC // eventual reference to standard AC
                         PW // reference

 l2vpn-state // read-only container

                                 Figure 1

3.2.  Open issues and next steps

   There are a number

   Most of additional defintitions that are the open issues have been resolved in
   considerations.  These this document.  There
   are VPLS IRB, some items for considerations, such as PW headend, how evpn instance is
   referenced within the scope of l2vpn instance and what parameters of
   evpn are defined VPLS IRB.
   These may or may not be convered in l2vpn data model.  Some of these are local and
   remote VPWS service Ids, FXC, Designated Forwarder priorities, etc.

   The contributors of this document intend to close on document.  If the working
   group intends these
   definitions during topics be addressed in a separate document,
   authors will proceed to finalize this document with comments received
   on the ongoing design team meeting as well as face-
   to-face meetings at definitions included in the IETF. current document.

3.3.  L2VPN  Pseudowire Common

3.3.1.  Pseudowire

   Pseudowire definitions is moved to a seperate container in order to
   allow Ethernet Segment and EVPN models can refer without having to
   pull down L2VPN container.

3.3.2.  pw-templates

   The pw-templates container contains a list of pw-template.  Each pw-
   template defines a list of common pseudowire attributes such as PW
   MTU, control word support etc.

3.3.2.

3.4.  L2VPN Common

3.4.1.  redundancy-group-templates

   The redundancy-group-template contains a list of templates.  Each
   template defines common attributes related to redundancy such as
   protection mode, reversion parameters, etc.

3.4.

3.5.  L2VPN instance

   A list of L2VPN instance is defined where each entry represent a
   point to point or multipoint service.  Within a service instance, a
   set of common attributes are defined, followed by a list of PWs and a
   list of endpoints.

3.4.1.

3.5.1.  common attributes

   The common attributes apply to entire L2VPN instance.  These
   attributes typically include attributes such as mac-aging-timer, BGP
   related parameters (if using BGP signaling), discovery-type, etc.

3.4.2.

3.5.2.  PW list

   The PW list is the number of PWs that are being used for a given
   L2VPN instance.  Each PW entry refers to PW template to inherit
   common attributes for the PW.  The one or more attributes from the
   template can be overriden.  It further extends definitions of more PW
   specific attributes such as use of control word, mac withdraw, what
   type of signaling (i.e.  LDP or BGP), setting of the TTL, etc.

3.4.3.

3.5.3.  List of endpoints

   The list of endpoints define the characteristics of the L2VPN
   service.  In the case of VPWS, the list is limited to two entries
   while for VPLS, there could be many.

   Each entry in the endpoint list, may hold AC, PW or redundancy-grp
   references.  The core aspect of endpoint container is its flexible
   personality based on what user decides to include in it.  It is
   future-proofed with possible extensions that can be included in the
   endpoint container such as Integrated Route Bridging (IRB), PW
   Headend, Virtual Switch Instance, etc.

   The endpoint entry also defines the split-horizon attribute which
   defines the frame forwarding restrictions between the endpoints
   belonging to same split-horizon group.  This construct permits
   multiple instances of split horizon groups with its own endpoint
   members.  The frame forwarding restrictions does not apply between
   endpoints that belong to two different split horizon groups.

3.4.3.1.

3.5.3.1.  ac

   Attachment Circuit (AC)resides within endpoint entry either as an
   independent entity or as a member of the redundancy group.  AC is not
   defined in this document but references the definitions being
   specified by other working groups and standard bodies.

3.4.3.2.

3.5.3.2.  pw

   The Pseudo-wire resides within endpoint entry either as an
   independent entity or as a member of the redundancy group.  The PW
   refers to one of the entry in the list of PWs defined with the L2VPN
   instance.

3.4.3.3.

3.5.3.3.  redundancy-grp choice

   The redundancy-grp is a generic redundancy construct which can hold
   primary and backup members of AC and PWs.  This flexibility permits
   combinations of -

   o  primary and backup AC

   o  primary and backup PW

   o  primary AC and backup PW

   o  primary PW and backup AC
   The redundancy group also defines attributes of the type of
   redundancy, such as protection mode, reroute mode, reversion related
   parameters, etc.

3.4.4.

3.5.4.  point-to-point or multipoint service

   The point-to-point service as defined for VPWS is represented by a
   list of endpoints and is limited to two entries by the VPWS constrain
   rules

   The multipoint service as defined for VPLS is represented by a list
   of endpoints.

   The augmentation of ietf-l2vpn module is TBD.  All IP addresses
   defined in this module are currently scoped under global VRF/table.

3.5.

3.6.  Operational State

   The operational state of L2VPN can be queried and obtained from attributes has been consolidated with
   the
   read-only container defined in this document configuration as "l2vpn-state".  This
   container holds per recommendations from the runtime information of guidelines for the bridge-table-instance
   and vpws-instance.

3.6.
   YANG author document.

3.7.  Yang tree

module: ietf-l2vpn
    +--rw l2vpn
    | ietf-pseudowires
    +--rw pw-templates
    |  | pseudowires
       +--rw pw-template* pseudowire* [name]
       |  |  +--rw name              string
       |  +--ro state?            pseudowire-status-type
       |  +--rw template?         pw-template-ref
       |  +--rw mtu?              uint16
       |  +--rw mac-withdraw?     boolean
       |  +--rw cw-negotiation?   cw-negotiation-type
       |  |  +--rw tunnel-policy?    string
       |  +--rw redundancy-group-templates (pw-type)?
       |     +--:(configured-pw)
       |        +--rw redundancy-group-template* [name] configured-pw
       |           +--rw peer-ip?          inet:ip-address
       |           +--rw pw-id?            uint32
       |           +--rw icb?              boolean
       |           +--rw transmit-label?   rt-types:mpls-label
       |           +--rw receive-label?    rt-types:mpls-label
       +--rw pw-templates
          +--rw pw-template* [name]
             +--rw name              string
             +--rw mtu?              uint16
             +--rw cw-negotiation?   cw-negotiation-type
             +--rw tunnel-policy?    string

module: ietf-l2vpn
    +--rw l2vpn
       +--rw redundancy-group-templates
       |  +--rw redundancy-group-template* [name]
       |     +--rw name               string
       |     +--rw protection-mode?   enumeration
       |  |     +--rw reroute-mode?      enumeration
       |  |     +--rw dual-receive?      boolean
       |  |     +--rw revert?            boolean
       |  |     +--rw reroute-delay?     uint16
       |  |     +--rw revert-delay?      uint16
    |
       +--rw l2vpn-instances
    | instances
          +--rw l2vpn-instance* instance* [name type]
    |
             +--rw name                  string
    |
             +--rw type                  identityref
    |
             +--rw mtu?                  uint16
    |
             +--rw mac-aging-timer?      uint32
    |
             +--rw service-type?         l2vpn-service-type
    |
             +--rw discovery-type?       l2vpn-discovery-type
    |
             +--rw signaling-type        l2vpn-signaling-type
    |
             +--rw bgp-auto-discovery
             |        |  +--rw route-distinguisher?   rt-types:route-distinguisher
             |        |  +--rw vpn-id?                string
             |        |  +--rw vpn-target* [route-target]
             |        |     +--rw route-target         rt-types:route-target
             |        |     +--rw route-target-type    rt-types:route-target-type
    |
             +--rw bgp-signaling
             |        |  +--rw site-id?      uint16
             |        |  +--rw site-range?   uint16
    |
             +--rw pw* endpoint* [name]
             |        |  +--rw name                   string
             |        |  +--rw template?         pw-template-ref
    | (ac-or-pw-or-redundancy-grp)?
             |  +--rw mtu?              uint16  |  +--:(ac)
             |  +--rw mac-withdraw?     boolean  |  |  +--rw cw-negotiation?   cw-negotiation-type ac* [name]
             |  |  |     +--rw tunnel-policy? name     string
             |  |  +--rw (pw-type)?
    |  |     +--ro state?   operational-state-type
             |  +--:(ldp-or-static-pw)  |  +--:(pw)
             |  |  |  +--rw peer-ip?          inet:ip-address
    | pw* [name]
             |  |  |     +--rw pw-id?            uint32
    | name     pw:pseudowire-ref
             |  |  |  +--rw icb?              boolean     +--ro state?   -> /pw:pseudowires/pseudowire[pw:name=current()/../name]/state
             |  |  +--:(redundancy-grp)
             |  |     +--rw transmit-label?   rt-types:mpls-label (primary)
             |  |     |  +--:(primary-ac)
             |  +--rw receive-label?    rt-types:mpls-label  |     |  |  +--:(bgp-pw)  +--rw primary-ac
             |  |     |  |     +--rw remote-pe-id?     inet:ip-address name?    string
             |  |     |  +--:(bgp-ad-pw)  |     +--ro state?   operational-state-type
             |  |     +--rw remote-ve-id?     uint16     |  +--:(primary-pw)
             |  +--rw vccv-ability?     boolean  |     |     +--rw request-vlanid?   uint16 primary-pw* [name]
             |  |     |        +--rw vlan-tpid?        string name     pw:pseudowire-ref
             |  |  +--rw ttl?              uint8
    |        +--rw endpoint* [name]
    |     |  +--rw name                   string        +--ro state?   -> /pw:pseudowires/pseudowire[pw:name=current()/../name]/state
             |  |     +--rw (ac-or-pw-or-redundancy-grp)? (backup)?
             |  |     |  +--:(ac)  +--:(backup-ac)
             |  |     |  |  +--rw ac* [name] backup-ac
             |  |     |  |     +--rw name name?    string
             |  |     |  +--:(pw)
    |        |  |  |  +--rw pw* [name]
    |        |  |  |     +--rw name    -> ../../../pw/name
    |        |  |  +--:(redundancy-grp)
    |        |  |     +--rw (primary)
    |        |  |     |  +--:(primary-ac)
    |        |  |     |  |  +--rw primary-ac?            string
    |  |     +--ro state?   operational-state-type
             |  |  +--:(primary-pw)     |  +--:(backup-pw)
             |  |     |     +--rw primary-pw* backup-pw* [name]
             |  |     |     |        +--rw name    -> ../../../pw/name
    |        |  |     +--rw (backup)?
    |        |  |     |  +--:(backup-ac)
    |        |  |     |  |  +--rw backup-ac?             string
    |        |  |     |  +--:(backup-pw)
    |        |  |     |     +--rw backup-pw* [name]          pw:pseudowire-ref
             |  |     |     |        +--rw name        +--ro state?        -> ../../../pw/name
    | /pw:pseudowires/pseudowire[pw:name=current()/../name]/state
             |  |     |        +--rw precedence?   uint32
             |  |  |     +--rw template?              -> /l2vpn/redundancy-group-templates/redundancy-group-template/name
             |  |  |     +--rw protection-mode?       enumeration
             |  |  |     +--rw reroute-mode?          enumeration
             |  |  |     +--rw dual-receive?          boolean
             |  |  |     +--rw revert?                boolean
             |  |  |     +--rw reroute-delay?         uint16
             |  |  |     +--rw revert-delay?          uint16
             |        |  +--rw split-horizon-group?   string
    |
             +--rw vpws-constraints
    |
             +--rw pbb-parameters
    |
                +--rw (component-type)?
    |
                   +--:(i-component)
                   |              |  +--rw i-sid?                   i-sid-type
                   |              |  +--rw backbone-src-mac?        yang:mac-address
    |
                   +--:(b-component)
    |
                      +--rw bind-b-component-name?   l2vpn-instance-name-ref
                      +--ro l2vpn-state
       +--ro l2vpn-instances-state
          +--ro l2vpn-instance*
             +--ro name?                 string
             +--ro type? bind-b-component-type?   identityref
             +--ro mtu?
  augment /pw:pseudowires/pw:pseudowire:
    +--rw vccv-ability?     boolean
    +--rw request-vlanid?   uint16
             +--ro mac-aging-timer?      uint32
             +--ro service-type?         l2vpn-service-type
             +--ro discovery-type?       l2vpn-discovery-type
             +--ro signaling-type        l2vpn-signaling-type
             +--ro bgp-auto-discovery
             |  +--ro route-distinguisher?   rt-types:route-distinguisher
             |  +--ro vpn-id?
    +--rw vlan-tpid?        string
    +--rw ttl?              uint8
  augment /pw:pseudowires/pw:pseudowire/pw:pw-type:
    +--:(bgp-pw)
    |  +--ro vpn-target* [route-target]
             |     +--ro route-target         rt-types:route-target
             |     +--ro route-target-type    rt-types:route-target-type
             +--ro bgp-signaling
             |  +--ro site-id?      uint16  +--rw bgp-pw
    |  +--ro site-range?     +--rw remote-pe-id?   inet:ip-address
    +--:(bgp-ad-pw)
       +--rw bgp-ad-pw
          +--rw remote-ve-id?   uint16

  notifications:
    +---n l2vpn-state-change-notification
       +--ro endpoint* [name]
             | l2vpn-instance-name?   l2vpn-instance-name-ref
       +--ro name                   string
             | l2vpn-instance-type?   -> /l2vpn/instances/instance[l2vpn:name=current()/../l2vpn-instance-name]/type
       +--ro (ac-or-pw-or-redundancy-grp)?
       |  |  +--:(ac)
       |  |  |  +--ro ac* ac?                    -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/pw/name
       |  +--:(pw)
       |  |  +--ro name?    string
             | pw?                    -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/pw/name
       |  +--:(redundancy-grp)
       |     +--ro state?   operational-state-type
             |  |  +--:(pw)
             | (primary)
       |     |  +--ro pw*  +--:(primary-ac)
       |     |  |  +--ro name?             string
             |  | primary-ac?            -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/primary-ac/name
       |     +--ro state?            operational-state-type     |  +--:(primary-pw)
       |     |     +--ro mtu?              uint16
             |  | primary-pw?            -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/primary-pw/name
       |     +--ro mac-withdraw?     boolean (backup)?
       |        +--:(backup-ac)
       |        |  +--ro cw-negotiation?   cw-negotiation-type
             | backup-ac?             -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/backup-ac/name
       |        +--:(backup-pw)
       |           +--ro tunnel-policy?    string
             |  |  |     +--ro (pw-type)?
             |  |  |     |  +--:(ldp-or-static-pw)
             |  |  |     |  |  +--ro peer-ip?          inet:ip-address
             |  |  |     |  |  +--ro pw-id?            uint32
             |  |  |     |  |  +--ro icb?              boolean
             |  |  |     |  |  +--ro transmit-label?   rt-types:mpls-label
             |  |  |     |  |  +--ro receive-label?    rt-types:mpls-label
             |  |  |     |  +--:(bgp-pw)
             |  |  |     |  |  +--ro remote-pe-id?     inet:ip-address
             |  |  |     |  +--:(bgp-ad-pw)
             |  |  |     |     +--ro remote-ve-id?     uint16
             |  |  |     +--ro vccv-ability?     boolean
             |  |  |     +--ro request-vlanid?   uint16
             |  |  |     +--ro vlan-tpid?        string
             |  |  |     +--ro ttl?              uint8
             |  |  +--:(redundancy-grp)
             |  |     +--ro (primary)
             |  |     |  +--:(primary-ac)
             |  |     |  |  +--ro primary-ac
             |  |     |  |     +--ro name?    string
             |  |     |  |     +--ro state?   operational-state-type
             |  |     |  +--:(primary-pw)
             |  |     |     +--ro primary-pw*
             |  |     |        +--ro name?             string
             |  |     | backup-pw?             -> /l2vpn/instances/instance[name=current()/../l2vpn-instance-name][type=current()/../l2vpn-instance-type]/endpoint/backup-pw/name
       +--ro state?            operational-state-type
             |  |     |        +--ro mtu?              uint16
             |  |     |        +--ro mac-withdraw?     boolean
             |  |     |        +--ro cw-negotiation?   cw-negotiation-type
             |  |     |        +--ro tunnel-policy?    string
             |  |     |        +--ro (pw-type)?
             |  |     |        |  +--:(ldp-or-static-pw)
             |  |     |        |  |  +--ro peer-ip?          inet:ip-address
             |  |     |        |  |  +--ro pw-id?            uint32
             |  |     |        |  |  +--ro icb?              boolean
             |  |     |        |  |  +--ro transmit-label?   rt-types:mpls-label
             |  |     |        |  |  +--ro receive-label?    rt-types:mpls-label
             |  |     |        |  +--:(bgp-pw)
             |  |     |        |  |  +--ro remote-pe-id?     inet:ip-address
             |  |     |        |  +--:(bgp-ad-pw)
             |  |     |        |     +--ro remote-ve-id?     uint16
             |  |     |        +--ro vccv-ability?     boolean
             |  |     |        +--ro request-vlanid?   uint16
             |  |     |        +--ro vlan-tpid?        string
             |  |     |        +--ro ttl?              uint8
             |  |     +--ro (backup)?
             |  |     |  +--:(backup-ac)
             |  |     |  |  +--ro backup-ac
             |  |     |  |     +--ro name?    string
             |  |     |  |     +--ro state?   operational-state-type
             |  |     |  +--:(backup-pw)
             |  |     |     +--ro backup-pw*
             |  |     |        +--ro name?             string
             |  |     |        +--ro state?            operational-state-type
             |  |     |        +--ro mtu?              uint16
             |  |     |        +--ro mac-withdraw?     boolean
             |  |     |        +--ro cw-negotiation?   cw-negotiation-type
             |  |     |        +--ro tunnel-policy?    string
             |  |     |        +--ro (pw-type)?
             |  |     |        |  +--:(ldp-or-static-pw)
             |  |     |        |  |  +--ro peer-ip?          inet:ip-address
             |  |     |        |  |  +--ro pw-id?            uint32
             |  |     |        |  |  +--ro icb?              boolean
             |  |     |        |  |  +--ro transmit-label?   rt-types:mpls-label
             |  |     |        |  |  +--ro receive-label?    rt-types:mpls-label
             |  |     |        |  +--:(bgp-pw)
             |  |     |        |  |  +--ro remote-pe-id?     inet:ip-address
             |  |     |        |  +--:(bgp-ad-pw)
             |  |     |        |     +--ro remote-ve-id?     uint16
             |  |     |        +--ro vccv-ability?     boolean
             |  |     |        +--ro request-vlanid?   uint16
             |  |     |        +--ro vlan-tpid?        string
             |  |     |        +--ro ttl?              uint8
             |  |     |        +--ro precedence?       uint32
             |  |     +--ro template?              -> /l2vpn/redundancy-group-templates/redundancy-group-template/name
             |  |     +--ro protection-mode?       enumeration
             |  |     +--ro reroute-mode?          enumeration
             |  |     +--ro dual-receive?          boolean
             |  |     +--ro revert?                boolean
             |  |     +--ro reroute-delay?         uint16
             |  |     +--ro revert-delay?          uint16
             |  +--ro split-horizon-group?   string
             +--ro pbb-parameters
                +--ro (component-type)?
                   +--:(i-component)
                   |  +--ro i-sid?                   i-sid-type
                   |  +--ro backbone-src-mac?        yang:mac-address
                   +--:(b-component)
                      +--ro bind-b-component-name?   string
                      +--ro bind-b-component-type?                 identityref

                                 Figure 2

4.  YANG Module

   The L2VPN configuration container is logically divided into following
   high level config areas: is logically divided into following
   high level config areas:

<CODE BEGINS> file "ietf-pseudowires@2017-06-26.yang"
module ietf-pseudowires {
  namespace "urn:ietf:params:xml:ns:yang:ietf-pseudowires";
  prefix "pw";

  import ietf-inet-types {
    prefix "inet";
  }

  import ietf-routing-types {
    prefix "rt-types";
  }

  organization  "ietf";
  contact       "ietf";
  description   "Pseudowire YANG model";

  revision "2017-06-26" {
    description "Initial revision " +
                "  - Created a new model for pseudowires, which used " +
                "    to be defined within the L2VPN model " +
                "";

    reference   "";
  }

  /* Typedefs */

  typedef pseudowire-ref {
    type leafref {
      path "/pw:pseudowires/pw:pseudowire/pw:name";
    }
    description "A type that is a reference to a pseudowire";
  }

  typedef pw-template-ref {
    type leafref {
      path "/pw:pseudowires/pw:pw-templates/pw:pw-template/pw:name";
    }
    description "A type that is a reference to a pw-template";
  }

  typedef cw-negotiation-type {
    type enumeration {
      enum "non-preferred" {
        description "No preference for control-word";
      }
      enum "preferred" {
        description "Prefer to have control-word negotiation";
      }
    }
    description "control-word negotiation preference type";
  }

  typedef pseudowire-status-type {
    type bits {
      bit pseudowire-forwarding {
        position 0;
        description "Pseudowire is forwarding";
      }
      bit pseudowire-not-forwarding {
        position 1;
        description "Pseudowire is not forwarding";
      }
      bit local-attachment-circuit-receive-fault {
        position 2;
        description "Local attachment circuit (ingress) receive " +
                    "fault";
      }
      bit local-attachment-circuit-transmit-fault {
        position 3;
        description "Local attachment circuit (egress) transmit " +
                    "fault";
      }
      bit local-PSN-facing-PW-receive-fault {
        position 4;
        description "Local PSN-facing PW (ingress) receive fault";
      }
      bit local-PSN-facing-PW-transmit-fault {
        position 5;
        description "Local PSN-facing PW (egress) transmit fault";
      }
      bit PW-preferential-forwarding-status {
        position 6;
        description "Pseudowire preferential forwarding status";
      }
      bit PW-request-switchover-status {
        position 7;
        description "Pseudowire request switchover status";
      }
    }
    description
      "Pseudowire status type, as registered in the IANA " +
      "Pseudowire Status Code Registry";
  }

  /* Groupings */

  grouping pw-type-grp {
    description "pseudowire type grouping";
    choice pw-type {
      description "A choice of pseudowire type";
      case ldp-or-static-pw {
        leaf peer-ip {
          type inet:ip-address;
          description "peer IP address";
        }
        leaf pw-id {
          type uint32;
          description "pseudowire id";
        }
        leaf icb {
          type boolean;
          description "inter-chassis backup";
        }
        leaf transmit-label {
          type rt-types:mpls-label;
          description "transmit lable";
        }
        leaf receive-label {
          type rt-types:mpls-label;
          description "receive label";
        }
      }
      case bgp-pw {
        leaf remote-pe-id {
          type inet:ip-address;
          description "remote pe id";
        }
      }
      case bgp-ad-pw {
        leaf remote-ve-id {
          type uint16;
          description "remote ve id";
        }
      }
    }
  }

  /* Data */

  container pseudowires {
    description "Configuration management of pseudowires";
    list pseudowire {
      key "name";
      description "A pseudowire";
      leaf name {
        type string;
        description "pseudowire name";
      }
      leaf state {
        type pseudowire-status-type;
        config false;
        description "pseudowire operation status";
        reference "RFC 4446 and IANA Pseudowire Status Codes " +
                  "Registery";
      }
      leaf template {
        type pw-template-ref;
        description "pseudowire template";
      }
      leaf mtu {
        type uint16;
        description "PW MTU";
      }
      leaf mac-withdraw {
        type boolean;
        default false;
        description "Enable (true) or disable (false) MAC withdraw";
      }
      leaf cw-negotiation {
        type cw-negotiation-type;
        description "cw-negotiation";
      }
      leaf tunnel-policy {
        type string;
        description "tunnel policy name";
      }
      choice pw-type {
        description "A choice of pseudowire type";
        case configured-pw {
          container configured-pw {
            description "LDP or static pseudowire that requires " +
                        "manual configuration";
            leaf peer-ip {
              type inet:ip-address;
              description "peer IP address";
            }
            leaf pw-id {
              type uint32;
              description "pseudowire id";
            }
            leaf icb {
              type boolean;
              description "inter-chassis backup";
            }
            leaf transmit-label {
              type rt-types:mpls-label;
              description "transmit lable";
            }
            leaf receive-label {
              type rt-types:mpls-label;
              description "receive label";
            }
          }
        }
      }
    }
    container pw-templates {
      description "pw-templates";
      list pw-template {
        key "name";
        description "pw-template";
        leaf name {
          type string;
          description "name";
        }
        leaf mtu {
          type uint16;
          description "pseudowire mtu";
        }
        leaf cw-negotiation {
          type cw-negotiation-type;
          default "preferred";
          description
            "control-word negotiation preference";
        }
        leaf tunnel-policy {
          type string;
          description "tunnel policy name";
        }
      }
    }
  }
}
<CODE ENDS>

<CODE BEGINS> file "ietf-l2vpn@2017-03-06.yang" "ietf-l2vpn@2017-06-26.yang"
module ietf-l2vpn {
  namespace "urn:ietf:params:xml:ns:yang:ietf-l2vpn";
  prefix "l2vpn";

  import ietf-inet-types {
    prefix "inet";
  }

  import ietf-yang-types {
    prefix "yang";
  }

  import ietf-mpls {
    prefix "mpls";
  }

  import ietf-routing-types {
    prefix "rt-types";
  }

  organization  "ietf";
  contact       "ietf";
  description   "l2vpn";

  revision "2017-03-06" {
    description "Sixth revision " +
                "  - Removed the 'common' container and move pw-templates " +
                "    and redundancy-group-templates up a level " +
                "  - Consolidated the endpoint configuration such that " +
                "    all L2VPN instances has a list of endpoint.  For " +
                "    certain types of L2VPN instances such as VPWS where " +
                "    each L2VPN instance is limited to at most two " +
                "    endpoint, additional augment statements were included " +
                "    to add necessary constraints " +
                "  - Removed discovery-type and signaling-type operational " +
                "    state from VPLS pseudowires, as these two parameters " +
                "    are configured as L2VPN parameters rather than " +
                "    pseudowire paramteres " +
                "  - Renamed l2vpn-instances to l2vpn-instances-state " +
                "    in the operational state branch " +
                "  - Removed BGP parameter groupings and reused " +
                "    ietf-routing-types.yang module instead " +
                "";
    reference "";
    prefix "inet";
  }

  import ietf-yang-types {
    prefix "yang";
  }

  import ietf-routing-types {
    prefix "rt-types";
  }

  import ietf-pseudowires {
    prefix "pw";
  }

  organization  "ietf";
  contact       "ietf";
  description   "l2vpn";

  revision "2016-10-24" "2017-06-26" {
    description "Fifth "Sixth revision " +
                "  - Edits based on Giles's comments Removed unused module mpls " +
                "    5) Remove relative leafrefs in groupings,  - Renamed l2vpn-instances-state to l2vpn-instances " +
                "  - Added pseudowire status as defined in RFC4446 and the resulting new groupings are: " +
                "       (a) bgp-auto-discovery-parameters-grp " +
                "       (b) bgp-signaling-parameters-grp    IANA Pseudowire Status Codes Register " +
                "       (c) endpoint-grp  - Added notifications " +
                "    11) Merge VPLS and VPWS into one single list  - Moved PW definition out of L2VPN " +
                "       and use augment statements  - Moved model to handle NMDA style specified in " +
                "       differences between VPLS and VPWS    draft-dsdt-nmda-guidelines-01.txt " +
                "  - Add a new grouping l2vpn-common-parameters-grp Renamed l2vpn-instances and l2vpn-instance to " +
                "    to make VPLS    instances and VPWS more consistent"; instance to shorten xpaths " +
                "";
    reference   "";
  }

  revision "2016-05-31" "2017-03-06" {
    description "Fourth "Sixth revision " +
                "  - Edits based on Giles's comments " +
                "    1) Change enumeration to identityref type for: " +
                "       (a) l2vpn-service-type " +
                "       (b) l2vpn-discovery-type " +
                "       (c) l2vpn-signaling-type " +
                "       bgp-rt-type, cw-negotiation, and " +
                "       pbb-component remain enumerations " +
                "    2) Define i-sid-type for leaf 'i-sid' " +
                "       (which is renamed from 'i-tag') " +
                "    3) Rename 'vpn-targets' to 'vpn-target' " +
                "    4) Import ietf-mpls.yang and reuse Removed the 'common' container and move pw-templates " +
                "       'mpls-label' type defined in ietf-mpls.yang " +
                "       transmit-label    and receive-label redundancy-group-templates up a level " +
                "    8) Change  - Consolidated the endpoint list's key to name configuration such that " +
                "    9) Changed MTU to type uint16 " +
                "";
    reference "";
  }

  revision "2016-03-07" {
    description "Third revision    all L2VPN instances has a list of endpoint.  For " +
                "  - Changed the module name to ietf-l2vpn    certain types of L2VPN instances such as VPWS where " +
                "  - Merged EVPN into    each L2VPN instance is limited to at most two " +
                "  - Eliminated the definitions of attachment    endpoint, additional augment statements were included " +
                "    circuit with the intention    to reuse other add necessary constraints " +
                "    layer-2 definitions  - Removed discovery-type and signaling-type operational " +
                "  - Added    state branch";
    reference "";
  }

  revision "2015-10-08" {
    description "Second revision from VPLS pseudowires, as these two parameters " +
                "  - Added container vpls-instances    are configured as L2VPN parameters rather than " +
                "  - Rearranged groupings and typedefs to be    pseudowire paramteres " +
                "    reused across vpls-instance and vpws-instances";
    reference "";
  }

  revision "2015-06-30" {
    description "Initial revision";
    reference   "";
  }

  /* identities */

  identity l2vpn-instance-type {
    description "Base identity from which identities of  - Renamed l2vpn-instances to l2vpn-instances-state " +
                "l2vpn service instance types are derived";
  }

  identity vpws-instance-type {
    base l2vpn-instance-type;
    description "This identity represents VPWS instance type";
  }

  identity vpls-instance-type {
    base l2vpn-instance-type;
    description "This identity represents VPLS instance type";
  }

  identity link-discovery-protocol {
    description "Base identiy from which identities describing
                " +
                "link discovery protocols are derived";
  }

  identity lacp {
    base "link-discovery-protocol";
    description "This identity represents LACP";

  }

  identity lldp {
    base "link-discovery-protocol";
    description "This identity represents LLDP";
  }

  identity bpdu {
    base "link-discovery-protocol";
    description "This identity represens BPDU";
  }

  identity cpd {
    base "link-discovery-protocol";
    description "This identity represents CPD";
  }

  identity udld {
    base "link-discovery-protocol";
    description "This identity represens UDLD";
  }

  identity l2vpn-service {
    description "Base identity from which identities describing    in the operational state branch " +
                "  - Removed BGP parameter groupings and reused " +
                "L2VPN services are derived";
  }

  identity Ethernet {
    base "l2vpn-service";
    description "This identity represents Ethernet service";
  }

  identity ATM {
    base "l2vpn-service";
    description "This identity represents Asynchronous Transfer
                "    ietf-routing-types.yang module instead " +
                "Mode service";
  }

  identity FR {
    base "l2vpn-service";
    description "This identity represent Frame-Relay service";
                "";
    reference "";
  }

  identity TDM

  revision "2016-10-24" {
    base "l2vpn-service";
    description "This identity represent Time Devision "Fifth revision " +
                "Multiplexing service";
  }
  identity l2vpn-discovery {
    description "Base identity from which identities describing
                "  - Edits based on Giles's comments " +
                "L2VPN discovery protocols are derived";
  }

  identity manual-discovery {
    base "l2vpn-discovery";
    description "Manual configuration of l2vpn service";
  }

  identity bgp-auto-discovery {
    base "l2vpn-discovery";
    description "Border Gateway Protocol (BGP) auto-discovery of
                "    5) Remove relative leafrefs in groupings, " +
                "l2vpn service";
  }

  identity ldp-discovery {
    base "l2vpn-discovery";
    description "Label Distribution Protocol (LDP) discovery of
                "       and the resulting new groupings are: " +
                "l2vpn service";
  }

  identity mixed-discovery {
    base "l2vpn-discovery";
    description "Mixed discovery methods of l2vpn service";
  }

  identity l2vpn-signaling {
    description "Base identity from which identities describing
                "       (a) bgp-auto-discovery-parameters-grp " +
                "L2VPN signaling protocols are derived";
  }

  identity static-configuration {
    base "l2vpn-signaling";
    description "Static configuration of labels (no signaling)";
  }

  identity ldp-signaling {
    base "l2vpn-signaling";
    description "Label Distribution Protocol (LDP) signaling";
  }

  identity bgp-signaling {
    base "l2vpn-signaling";
    description "Border Gateway Protocol (BGP) signaling";
                "       (b) bgp-signaling-parameters-grp " +
                "       (c) endpoint-grp " +
                "    11) Merge VPLS and VPWS into one single list " +
                "       and use augment statements to handle " +
                "       differences between VPLS and VPWS " +
                "  - Add a new grouping l2vpn-common-parameters-grp " +
                "    to make VPLS and VPWS more consistent";
    reference "";
  }

  identity mixed-signaling

  revision "2016-05-31" {
    base "l2vpn-signaling";
    description "Mixed signaling methods";
  }

  /* typedefs */

  typedef l2vpn-service-type {
    type "Fourth revision " +
                "  - Edits based on Giles's comments " +
                "    1) Change enumeration to identityref {
      base "l2vpn-service";
    }
    description "L2VPN service type";
  }

  typedef l2vpn-discovery-type { type identityref {
      base "l2vpn-discovery";
    }
    description "L2VPN discovery type";
  }

  typedef for: " +
                "       (a) l2vpn-service-type " +
                "       (b) l2vpn-discovery-type " +
                "       (c) l2vpn-signaling-type {
    type identityref {
      base "l2vpn-signaling";
    }
    description "L2VPN signaling type";
  }

  typedef cw-negotiation-type {
    type enumeration {
      enum "non-preferred" {
        description "No preference " +
                "       bgp-rt-type, cw-negotiation, and " +
                "       pbb-component remain enumerations " +
                "    2) Define i-sid-type for control-word";
      }
      enum "preferred" {
        description "Prefer leaf 'i-sid' " +
                "       (which is renamed from 'i-tag') " +
                "    3) Rename 'vpn-targets' to have control-word negotiation";
      }
    }
    description "control-word negotiation preference type";
  }

  typedef link-discovery-protocol-type {
    type identityref {
      base "link-discovery-protocol";
    }
    description "This 'vpn-target' " +
                "    4) Import ietf-mpls.yang and reuse the " +
                "       'mpls-label' type is used defined in ietf-mpls.yang " +
                "       transmit-label and receive-label " +
                "    8) Change endpoint list's key to identify name " +
                "link discovery protocol";
  }

  typedef pbb-component-type {
                "    9) Changed MTU to type enumeration {
      enum "b-component" {
        description "Identifies as a b-component";
      }
      enum "i-component" {
        description "Identifies as an i-component";
      } uint16 " +
                "";
    reference "";
  }

  revision "2016-03-07" {
    description "This type is used "Third revision " +
                "  - Changed the module name to identify ietf-l2vpn " +
                "the type
                "  - Merged EVPN into L2VPN " +
                "  - Eliminated the definitions of PBB component";
  }

  typedef pw-template-ref {
    type leafref {
      path "/l2vpn/pw-templates/pw-template/name";
    }
    description "pw-template-ref";
  }

  typedef redundancy-group-template-ref {
    type leafref {
      path "/l2vpn/redundancy-group-templates" attachment " +
           "/redundancy-group-template/name";
    }
    description "redundancy-group-template-ref";
  }

  typedef l2vpn-instance-name-ref {
    type leafref {
      path "/l2vpn/l2vpn-instances"
                "    circuit with the intention to reuse other " +
           "/l2vpn-instance/name";
    }
    description "l2vpn-instance-name-ref";
  }

  typedef l2vpn-instance-type-ref {
    type leafref {
      path "/l2vpn/l2vpn-instances"
                "    layer-2 definitions " +
           "/l2vpn-instance/type";
    }
    description "l2vpn-instance-type-ref";
  }

  typedef operational-state-type {
    type enumeration {
      enum 'up' {
        description "Operational state is up";
      }
      enum 'down' {
        description "Operational
                "  - Added state is down";
      }
    }
    description "operational-state-type"; branch";
    reference "";
  }

  typedef i-sid-type {
    type uint32

  revision "2015-10-08" {
      range "0..16777216";
    }
    description "I-SID type that is 24-bits. "Second revision " +
                "This should be moved to ieee-types.yang at
                "  - Added container vpls-instances " +
                "http://www.ieee802.org/1/files/public/docs2015"
                "  - Rearranged groupings and typedefs to be " +
                "/new-mholness-ieee-types-yang-v01.yang";
                "    reused across vpls-instance and vpws-instances";
    reference "";
  }

  /* groupings */

  grouping pbb-parameters-grp {
    description "PBB parameters grouping";
    container pbb-parameters {
      description "pbb-parameters";
      choice component-type {
        description "PBB component type";
        case i-component {
          leaf i-sid

  revision "2015-06-30" {
            type i-sid-type;
    description "I-SID"; "Initial revision";
    reference   "";
  }
          leaf backbone-src-mac
  /* identities */

  identity l2vpn-instance-type {
            type yang:mac-address;
    description "backbone-src-mac";
          } "Base identity from which identities of " +
                "l2vpn service instance types are derived";
  }
        case b-component {
          leaf bind-b-component-name

  identity vpws-instance-type {
            type l2vpn-instance-name-ref;
            must "/l2vpn" +
                 "/l2vpn-instances/l2vpn-instance[name=current()]" +
                 "/type = 'vpls-instance-type'"
    base l2vpn-instance-type;
    description "This identity represents VPWS instance type";
  }

  identity vpls-instance-type {
    base l2vpn-instance-type;
    description "A b-component must be an L2VPN "This identity represents VPLS instance type";
  }

  identity link-discovery-protocol {
    description "Base identiy from which identities describing " +
                          "of type vpls-instance-type";
                "link discovery protocols are derived";
  }

  identity lacp {
    base "link-discovery-protocol";
    description "Reference to the associated b-component";
          }
        }
      }

    } "This identity represents LACP";
  }

  grouping pbb-parameters-state-grp

  identity lldp {
    base "link-discovery-protocol";
    description "PBB parameters grouping";
    container pbb-parameters "This identity represents LLDP";
  }

  identity bpdu {
    base "link-discovery-protocol";
    description "pbb-parameters";
      choice component-type "This identity represens BPDU";
  }

  identity cpd {
    base "link-discovery-protocol";
    description "PBB component type";
        case i-component {
          leaf i-sid "This identity represents CPD";
  }

  identity udld {
            type i-sid-type;
    base "link-discovery-protocol";
    description "I-SID"; "This identity represens UDLD";
  }
          leaf backbone-src-mac

  identity l2vpn-service {
            type yang:mac-address;
    description "backbone-src-mac";
          } "Base identity from which identities describing " +
                "L2VPN services are derived";
  }
        case b-component {
          leaf bind-b-component-name

  identity Ethernet {
            type string;
    base "l2vpn-service";
    description "Name of the associated b-component"; "This identity represents Ethernet service";
  }
          leaf bind-b-component-type

  identity ATM {
            type identityref
    base "l2vpn-service";
    description "This identity represents Asynchronous Transfer " +
                "Mode service";
  }

  identity FR {
    base l2vpn-instance-type; "l2vpn-service";
    description "This identity represent Frame-Relay service";
  }
            must ". = 'vpls-instance-type'"

  identity TDM {
    base "l2vpn-service";
    description "The associated b-component must have "This identity represent Time Devision " +
                          "type vpls-instance-type";
                "Multiplexing service";
  }
  identity l2vpn-discovery {
    description "Type of the associated b-component";
          }
        }
      }
    } "Base identity from which identities describing " +
                "L2VPN discovery protocols are derived";
  }

  grouping l2vpn-common-parameters-grp

  identity manual-discovery {
    base "l2vpn-discovery";
    description "L2VPN common parameters";
    leaf name "Manual configuration of l2vpn service";
  }

  identity bgp-auto-discovery {
      type string;
    base "l2vpn-discovery";
    description "Name "Border Gateway Protocol (BGP) auto-discovery of L2VPN service instance"; " +
                "l2vpn service";
  }
    leaf type {
      type identityref

  identity ldp-discovery {
    base l2vpn-instance-type;

      } "l2vpn-discovery";
    description "Type "Label Distribution Protocol (LDP) discovery of L2VPN service instance"; " +
                "l2vpn service";
  }
    leaf mtu

  identity mixed-discovery {
      type uint16;
    base "l2vpn-discovery";
    description "MTU "Mixed discovery methods of L2VPN l2vpn service";
  }
    leaf mac-aging-timer

  identity l2vpn-signaling {
      type uint32;
    description "mac-aging-timer, the duration after which" "Base identity from which identities describing " +
                  "a MAC entry is considered aged out";
                "L2VPN signaling protocols are derived";
  }
    leaf service-type

  identity static-configuration {
      type l2vpn-service-type;
      default Ethernet;
    base "l2vpn-signaling";
    description "L2VPN service type"; "Static configuration of labels (no signaling)";
  }
    leaf discovery-type

  identity ldp-signaling {
      type l2vpn-discovery-type;
      default manual-discovery;
    base "l2vpn-signaling";
    description "L2VPN service discovery type"; "Label Distribution Protocol (LDP) signaling";
  }
    leaf signaling-type

  identity bgp-signaling {
      type l2vpn-signaling-type;
      mandatory true;
    base "l2vpn-signaling";
    description "L2VPN signaling type"; "Border Gateway Protocol (BGP) signaling";
  }

  identity mixed-signaling {
    base "l2vpn-signaling";
    description "Mixed signaling methods";
  }

  grouping bgp-signaling-parameters-grp

  identity l2vpn-notification-state {
    description "BGP parameters for signaling";
    leaf site-id "The base identity on which notification states " +
                "are based";
  }

  identity MAC-limit-reached {
      type uint16;
    base "l2vpn-notification-state";
    description "Site ID"; "MAC limit is reached";
  }
    leaf site-range

  identity MAC-limit-cleared {
      type uint16;
    base "l2vpn-notification-state";
    description "Site Range"; "MAC limit is cleared";
  }

  identity MTU-mismatched {
    base "l2vpn-notification-state";
    description "MAC is mismatched";
  }

  grouping pw-common-parameters-grp
  identity MTU-mismatched-cleared {
    base "l2vpn-notification-state";
    description "Pseudowire parameters common to both " +
                "VPWS and VPLS pseudowires";
    leaf name "MAC is mismatch is cleared";
  }

  identity state-changed-to-up {
      type string;
    base "l2vpn-notification-state";
    description "pseudowire name"; "State is changed to UP";
  }
    leaf template

  identity state-changed-to-down {
      type pw-template-ref;
    base "l2vpn-notification-state";
    description "pseudowire template"; "State is changed to down";
  }
    leaf mtu

  identity MAC-move-limit-exceeded {
      type uint16;
    base "l2vpn-notification-state";
    description "PW MTU"; "MAC move limit is exceeded";
  }
    leaf mac-withdraw

  identity MAC-move-limit-exceeded-cleared {
      type boolean;
      default false;
    base "l2vpn-notification-state";
    description "Enable (true) or disable (false) MAC withdraw"; "MAC move limit exceeded is cleared";
  }
    leaf cw-negotiation

  identity MAC-flap-detected {
      type cw-negotiation-type;
    base "l2vpn-notification-state";
    description "cw-negotiation"; "MAC flap detected";
  }
    leaf tunnel-policy

  identity port-disabled-due-to-MAC-flap {
      type string;
    base "l2vpn-notification-state";
    description "tunnel policy name";
    }
    uses pw-type-grp; "Port disabled due to MAC flap";
  }

  grouping pw-type-grp

  /* typedefs */

  typedef l2vpn-service-type {
    description "pseudowire
    type grouping";
    choice pw-type identityref {
      base "l2vpn-service";
    }
    description "A choice of pseudowire "L2VPN service type";
      case ldp-or-static-pw {
        leaf peer-ip
  }

  typedef l2vpn-discovery-type {
    type inet:ip-address; identityref {
      base "l2vpn-discovery";
    }
    description "peer IP address"; "L2VPN discovery type";
  }
        leaf pw-id

  typedef l2vpn-signaling-type {
    type uint32; identityref {
      base "l2vpn-signaling";
    }
    description "pseudowire id"; "L2VPN signaling type";
  }
        leaf icb

  typedef link-discovery-protocol-type {
    type boolean; identityref {
      base "link-discovery-protocol";
    }
    description "inter-chassis backup"; "This type is used to identify " +
                "link discovery protocol";
  }
        leaf transmit-label

  typedef pbb-component-type {
    type rt-types:mpls-label; enumeration {
      enum "b-component" {
        description "transmit lable"; "Identifies as a b-component";
      }
        leaf receive-label
      enum "i-component" {
          type rt-types:mpls-label;
        description "receive label"; "Identifies as an i-component";
      }
    }
      case bgp-pw {
        leaf remote-pe-id {
          type inet:ip-address;
    description "remote pe id";
        } "This type is used to identify " +
                "the type of PBB component";
  }
      case bgp-ad-pw {
        leaf remote-ve-id

  typedef redundancy-group-template-ref {
    type uint16;
          description "remote ve id"; leafref {
      path "/l2vpn:l2vpn/l2vpn:redundancy-group-templates" +
           "/l2vpn:redundancy-group-template/l2vpn:name";
    }
    description "redundancy-group-template-ref";
  }

  typedef l2vpn-instance-name-ref {
    type leafref {
      path "/l2vpn:l2vpn/l2vpn:instances" +
           "/l2vpn:instance/l2vpn:name";
    }
    description "l2vpn-instance-name-ref";
  }

  grouping redundancy-group-properties-grp

  typedef l2vpn-instance-type-ref {
    type leafref {
      path "/l2vpn:l2vpn/l2vpn:instances" +
           "/l2vpn:instance/l2vpn:type";
    }
    description "redundancy-group-properties-grp";
    leaf protection-mode "l2vpn-instance-type-ref";
  }

  typedef operational-state-type {
    type enumeration {
      enum "frr" 'up' {
          value 0;
        description "fast reroute"; "Operational state is up";
      }
      enum "master-slave" 'down' {
          value 1;
        description "master-slave"; "Operational state is down";
      }
        enum "independent"
    }
    description "operational-state-type";
  }

  typedef i-sid-type {
    type uint32 {
      range "0..16777216";
    }
    description "I-SID type that is 24-bits. " +
                "This should be moved to ieee-types.yang at " +
                "http://www.ieee802.org/1/files/public/docs2015" +
                "/new-mholness-ieee-types-yang-v01.yang";
  }

  /* groupings */

  grouping one-l2vpn-instance-grp {
          value 2;
    description "independent";
        }
      } "A grouping that identifies a single L2VPN instance";
    leaf l2vpn-instance-name {
      type l2vpn-instance-name-ref;
      description "protection-mode"; "The L2VPN instance name";
    }
    leaf reroute-mode l2vpn-instance-type {
      type enumeration {
        enum "immediate" leafref {
          value 0;
        path "/l2vpn:l2vpn/l2vpn:instances" +
             "/l2vpn:instance" +
                  "[l2vpn:name=current()/../l2vpn-instance-name]" +
             "/l2vpn:type";
      }
      description "immediate reroute"; "The L2VPN instance type";
    }
        enum "delayed"
  }
  grouping pbb-parameters-grp {
          value 1;
    description "delayed reroute";
        }
        enum "never" "PBB parameters grouping";
    container pbb-parameters {
          value 2;
      description "never reroute";
        }
      } "pbb-parameters";
      choice component-type {
        description "reroute-mode";
    } "PBB component type";
        case i-component {
          leaf dual-receive i-sid {
            type boolean; i-sid-type;
            description
      "allow extra traffic to be carried by backup"; "I-SID";
          }
          leaf revert backbone-src-mac {
            type boolean; yang:mac-address;
            description "allow forwarding to revert to primary " +
                  "after restoring primary"; "backbone-src-mac";
          }
        }
        case b-component {
          leaf reroute-delay bind-b-component-name {
      when "../reroute-mode
            type l2vpn-instance-name-ref;
            must "/l2vpn:l2vpn" +
                 "/l2vpn:instances" +
                 "/l2vpn:instance[l2vpn:name=current()]" +
                 "/type = 'delayed'" 'vpls-instance-type'" {
              description "Specify amount of time to " +
                    "delay reroute only when "A b-component must be an L2VPN instance " +
                    "delayed route is configured";
      }
                          "of type uint16; vpls-instance-type";
            }
            description "amount of time "Reference to delay reroute"; the associated b-component";
          }
          leaf revert-delay {
      when "../revert = 'true'" bind-b-component-type {
        description "Specify the amount of time to " +
                    "wait to revert to primary " +
                    "only if reversion is configured";
      }
            type uint16;
      description "amount ot time to wait to revert to primary";
    }
  }

  grouping endpoint-grp identityref {
    description "A grouping that defines the structure of " +
                "an endpoint";
    choice ac-or-pw-or-redundancy-grp
              base l2vpn-instance-type;
            }
            must ". = 'l2vpn:vpls-instance-type'" {
              description "A choice ofattachment circuit or "The associated b-component must have " +
                  "pseudowire or redundancy group";
      case ac {
                          "type vpls-instance-type";
            }
            config false;
            description "Attachment circuit(s) as an endpoint"; "Type of the associated b-component";
          }
      case pw
        }
      }
    }
  }

  grouping pbb-parameters-state-grp {
    description "Pseudowire(s) as an endpoint";
      }
      case redundancy-grp "PBB parameters grouping";
    container pbb-parameters {
      description "Redundancy group as an endpoint"; "pbb-parameters";
      choice primary component-type {
          mandatory true;
        description "primary options"; "PBB component type";
        case primary-ac i-component {
          leaf i-sid {
            type i-sid-type;
            description "primary-ac"; "I-SID";
          }
          case primary-pw
          leaf backbone-src-mac {
            type yang:mac-address;
            description "primary-pw"; "backbone-src-mac";
          }
        }
        choice backup {
          description "backup options";
        case backup-ac b-component {
            description "backup-ac";
          }
          case backup-pw
          leaf bind-b-component-name {
            type string;
            description "backup-pw";
          } "Name of the associated b-component";
          }
          leaf template bind-b-component-type {
            type leafref identityref {
            path "/l2vpn/redundancy-group-templates" +
                 "/redundancy-group-template/name";
              base l2vpn-instance-type;
            }
            must ". = 'l2vpn:vpls-instance-type'" {
              description "Reference a redundancy group "The associated b-component must have " +
                      "properties template";
                          "type vpls-instance-type";
            }
            description "Type of the associated b-component";
          }
        }
        uses redundancy-group-properties-grp;
      }
    }
  }

  grouping ac-state-grp l2vpn-common-parameters-grp {
    description "ac-state-grp"; "L2VPN common parameters";
    leaf name {
      type string;
      description "Name of attachment circuit.  " +
                  "This field is intended to " +
                  "reference standardized " +
                  "layer-2 definitions."; L2VPN service instance";
    }
    leaf state { type operational-state-type;
      description "attachment circuit up/down state";
    }
  }
  grouping common-pw-state-grp {
    description "common-pw-state-grp";
    leaf name {
      type string;
      description "pseudowire name";
    }
    leaf state identityref {
      type operational-state-type;
        base l2vpn-instance-type;
      }
      description "pseudowire operation state up/down"; "Type of L2VPN service instance";
    }
    leaf mtu {
      type uint16;
      description "PW MTU";
    }
    leaf mac-withdraw {
      type boolean;
      description "MAC withdraw is enabled (ture) or disabled (false)";
    }
    leaf cw-negotiation {
      type cw-negotiation-type;
      description "Override the control-word negotiation " +
                  "preference specified in the " +
                  "pseudowire template."; "MTU of L2VPN service";
    }
    leaf tunnel-policy mac-aging-timer {
      type string; uint32;
      description "Used to override "mac-aging-timer, the tunnel policy name " duration after which" +
                  "specified in the pseduowire template";
    }
    uses pw-type-grp;
  }

  grouping vpws-only-pw-state-grp {
    description "vpws-pw-state-grp";
    leaf vccv-ability {
      type boolean;
      description "vccv-ability";
                  "a MAC entry is considered aged out";
    }
    leaf request-vlanid service-type {
      type uint16;
      description "request vlanid"; l2vpn-service-type;
      default Ethernet;
      description "L2VPN service type";
    }
    leaf vlan-tpid discovery-type {
      type string; l2vpn-discovery-type;
      default manual-discovery;
      description "vlan tpid"; "L2VPN service discovery type";
    }
    leaf ttl signaling-type {
      type uint8; l2vpn-signaling-type;
      mandatory true;
      description "time-to-live"; "L2VPN signaling type";
    }
  }

  /* L2VPN YANG Model */

  container l2vpn {
    description "l2vpn";
    container pw-templates {
      description "pw-templates";
      list pw-template

  grouping bgp-signaling-parameters-grp {
        key "name";
    description "pw-template"; "BGP parameters for signaling";
    leaf name site-id {
      type string; uint16;
      description "name"; "Site ID";
    }
    leaf mtu site-range {
      type uint16;
      description "pseudowire mtu"; "Site Range";
    }
        leaf cw-negotiation
  }

  grouping redundancy-group-properties-grp {
          type cw-negotiation-type;
          default "preferred";
    description
            "control-word negotiation preference";
        } "redundancy-group-properties-grp";
    leaf tunnel-policy protection-mode {
      type string; enumeration {
        enum "frr" {
          value 0;
          description "tunnel policy name";
        }
      } "fast reroute";
        }
    container redundancy-group-templates
        enum "master-slave" {
          value 1;
          description "redundancy group templates";
      list redundancy-group-template "master-slave";
        }
        enum "independent" {
        key "name";
          value 2;
          description "redundancy-group-template"; "independent";
        }
      }
      description "protection-mode";
    }
    leaf name reroute-mode {
      type string; enumeration {
        enum "immediate" {
          value 0;
          description "name";
        }
        uses redundancy-group-properties-grp;
      } "immediate reroute";
        }
    container l2vpn-instances
        enum "delayed" {
          value 1;
          description "A list of L2VPN instances";
      list l2vpn-instance "delayed reroute";
        }
        enum "never" {
        key "name type";
          value 2;
          description "An L2VPN service instance";
        uses l2vpn-common-parameters-grp;
        container bgp-auto-discovery { "never reroute";
        }
      }
      description "BGP auto-discovery parameters"; "reroute-mode";
    }
    leaf route-distinguisher dual-receive {
      type rt-types:route-distinguisher; boolean;
      description "BGP route distinguisher";
      "allow extra traffic to be carried by backup";
    }
    leaf vpn-id revert {
      type string; boolean;
      description "VPN ID"; "allow forwarding to revert to primary " +
                  "after restoring primary";
    }
          uses rt-types:vpn-route-targets;
    leaf reroute-delay {
      when "../reroute-mode = 'delayed'" {
        description "Specify amount of time to " +
                    "delay reroute only when " +
                    "delayed route is configured";
      }
        container bgp-signaling
      type uint16;
      description "amount of time to delay reroute";
    }
    leaf revert-delay {
      when "../signaling-type "../revert = 'bgp-signaling'" 'true'" {
        description "Check signaling type: "Specify the amount of time to " +
                        "Can only configure BGP signaling if
                    "wait to revert to primary " +
                        "signaling type
                    "only if reversion is BGP";
          }
          description "BGP signaling parameters";
          uses bgp-signaling-parameters-grp;
        }
        list pw {
          key "name";
          description "A pseudowire";
          uses pw-common-parameters-grp; configured";
      }
        list endpoint {
          key "name";
          description "An endpoint";
          leaf name {
      type string; uint16;
      description "endpoint name"; "amount ot time to wait to revert to primary";
    }
          uses
  }

  grouping endpoint-grp {
            augment "ac-or-pw-or-redundancy-grp/ac" {
    description "Augment for attachment circuit(s) "A grouping that defines the structure of " +
                          "as an
                "an endpoint";
              list ac {
                key "name";
                leaf name
    choice ac-or-pw-or-redundancy-grp {
                  type string;
      description "Name of attachment circuit.  " +
                              "This field is intended to " +
                              "reference standardized "A choice ofattachment circuit or " +
                              "layer-2 definitions.";

                }
                  "pseudowire or redundancy group";
      case ac {
        description "An L2VPN instance's " +
                            "attachment circuit list";
              } "Attachment circuit(s) as an endpoint";
      }
            augment "ac-or-pw-or-redundancy-grp/pw"
      case pw {
        description "Augment for pseudowire(s) "Pseudowire(s) as an endpoint";
              list pw
      }
      case redundancy-grp {
                key "name";
                leaf name
        description "Redundancy group as an endpoint";
        choice primary {
                  type leafref
          mandatory true;
          description "primary options";
          case primary-ac {
                    path "../../../pw/name";
                  }
            description "name of pseudowire"; "primary-ac";
          }
          case primary-pw {
            description "An L2VPN instance's pseudowire list"; "primary-pw";
          }
        }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "primary/primary-ac"
        choice backup {
          description "Augment for primary-ac";
              leaf primary-ac "backup options";
          case backup-ac {
                type string;
            description "Name of primary attachment circuit.  " +
                            "This field is intended to reference " +
                            "standardized layer-2 definitions.";
              } "backup-ac";
          }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "primary/primary-pw"
          case backup-pw {
            description "Augment for primary-pw";
              list primary-pw {
                key "name";
                leaf name {
                  type leafref {
                    path "../../../pw/name"; "backup-pw";
          }
                  description "name of pseudowire";
        }
                description "An L2VPN instance's pseudowire list";
      }
    }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "backup/backup-ac"
  }

  grouping ac-params-grp {
    description "Augment for backup-ac"; "ac-state-grp";
    leaf backup-ac name {
      type string;
      description "Name of backup attachment circuit.  " +
                  "This field is intended to reference " +
                            "standardized layer-2
                  "reference standardized " +
                  "layer-2 definitions.";
    }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "backup/backup-pw"
    leaf state {
      type operational-state-type;
      config false;
      description "Augment for backup-pw";
              list backup-pw "attachment circuit up/down state";
    }
  }

  grouping pw-params-grp {
                key "name";
    description "PW state grouping";
    leaf name {
      type pw:pseudowire-ref;
      description "Pseudowire name";
    }
    leaf state {
      type leafref {
        path "../../../pw/name";
                  }
                  description "Reference an attachment circuit"; "/pw:pseudowires" +
             "/pw:pseudowire[pw:name=current()/../name]" +
             "/pw:state";
      }
      config false;
      description "A list of backup pseudowires";
              }
            }
          }
        }
      } "Pseudowire state";
    }
  }

  /* L2VPN YANG Model */

  container l2vpn-state l2vpn {
    config false;
    description "l2vpn state"; "l2vpn";

    container l2vpn-instances-state redundancy-group-templates {
      description "L2VPN "redundancy group templates";
      list redundancy-group-template {
        key "name";
        description "redundancy-group-template";
        leaf name {
          type string;
          description "name";
        }
        uses redundancy-group-properties-grp;
      }
    }
    container instances state"; {
      description "A list l2vpn-instance of L2VPN instances";
      list instance {
        key "name type";
        description "An L2VPN instance's state"; service instance";
        uses l2vpn-common-parameters-grp;
        container bgp-auto-discovery {
          description "BGP auto-discovery parameters";
          leaf route-distinguisher {
            type rt-types:route-distinguisher;
            description "BGP route distinguisher";
          }
          leaf vpn-id {
            type string;
            description "VPN ID";
          }
          uses rt-types:vpn-route-targets;
        }
        container bgp-signaling {
          when "../signaling-type = 'bgp-signaling'" {
            description "Check signaling type: " +
                        "Can only configure BGP signaling if " +
                        "signaling type is BGP";
          }
          description "BGP signaling parameters";
          uses bgp-signaling-parameters-grp;
        }
        list endpoint {
          key "name";
          description "An endpoint";
          leaf name {
            type string;
            description "endpoint name";
          }
          uses endpoint-grp {
            augment "ac-or-pw-or-redundancy-grp/ac" {
              description "Augment of for attachment circuit state"; circuit(s) " +
                          "as an endpoint";
              list ac {
                key "name";
                uses ac-state-grp; ac-params-grp;
                description "An attachment circuit's L2VPN instance's " +
                            "operational state";
                            "attachment circuit list";
              }
            }
            augment "ac-or-pw-or-redundancy-grp/pw" {
              description "Augment of pseudowire state"; for pseudowire(s) as an endpoint";
              list pw {
                key "name";
                uses common-pw-state-grp; pw-params-grp {
                  description "A pseudowire's operational state"; "Pseudowire parameters";
                  refine "name" {
                    must "(../../../type = " +
                         " 'l2vpn:vpws-instance-type') or " +
                         "(not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vccv-ability)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /request-vlanid)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vlan-tpid)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /ttl)))" {
                      description "Only a VPWS PW has parameters " +
                                  "vccv-ability, request-vlanid, " +
                                  "vlan-tpid, and ttl";
                    }
                  }
                }
                description "An L2VPN instance's pseudowire list";
              }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "primary/primary-ac" {
              description "Augment of primary attachment circuit state"; for primary-ac";
              container primary-ac {
                uses ac-state-grp;
                description "An attachment circuit's " +
                            "operational state"; "Primary AC";
                uses ac-params-grp;
              }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "primary/primary-pw" {
              description "Augment of primary pseudowire state"; for primary-pw";
              list primary-pw {
                key "name";
                uses common-pw-state-grp; pw-params-grp {
                  description "A pseudowire's operational state"; "Pseudowire parameters";
                  refine "name" {
                    must "(../../../type = " +
                         " 'l2vpn:vpws-instance-type') or " +
                         "(not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vccv-ability)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /request-vlanid)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vlan-tpid)) and " +
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /ttl)))" {
                      description "Only a VPWS PW has parameters " +
                                  "vccv-ability, request-vlanid, " +
                                  "vlan-tpid, and ttl";
                    }
                  }
                }
                description "An L2VPN instance's pseudowire list";
              }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "backup/backup-ac" {
              description "Augment of backup attachment circuit state"; for backup-ac";
              container backup-ac {
                uses ac-state-grp;
                description "An attachment circuit's " +
                            "operational state"; "Backup AC";
                uses ac-params-grp;
              }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                    "backup/backup-pw" {
              description "Augment of backup pseudowire state"; for backup-pw";
              list backup-pw {
                key "name";
                uses common-pw-state-grp;
                description "A pseudowire's operational state";
              }
            }
          }
        }
      }
    }
  }

  /* augments */

  augment "/l2vpn/l2vpn-instances/l2vpn-instance" {
    when "type = 'vpws-instance-type'" pw-params-grp {
                  description "Constraints only for VPWS pseudowires";
    }
    description "Augment for VPWS instance";
    container vpws-constraints "Pseudowire parameters";
                  refine "name" {
                    must "(count(../endpoint) <= 2) and "(../../../type = " +
           "(count(../endpoint/pw) <= 1)
                         " 'l2vpn:vpws-instance-type') or " +
                         "(not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vccv-ability)) and " +
           "(count(../endpoint/ac) <= 1)
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /request-vlanid)) and " +
           "(count(../endpoint/primary-pw) <= 1)
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /vlan-tpid)) and " +
           "(count(../endpoint/backup-pw) <= 1)
                         " not(boolean(/pw:pseudowires" +
                         "     /pw:pseudowire[pw:name = current()]" +
                         "     /ttl)))" {
                      description "A "Only a VPWS L2VPN instance PW has at most 2 endpoints parameters " +
                    "and each endpoint has at most 1 pseudowire or
                                  "vccv-ability, request-vlanid, " +
                    "1 attachment circuit";
                                  "vlan-tpid, and ttl";
                    }
                  }

                }
                description "A list of backup pseudowires";
              }
            }
            augment "ac-or-pw-or-redundancy-grp/redundancy-grp" {
              description "Augment for redundancy group properties";
              leaf template {
                type leafref {
                  path "/l2vpn/redundancy-group-templates" +
                       "/redundancy-group-template/name";
                }
                description "Reference a redundancy group " +
                            "properties template";
              }
              uses redundancy-group-properties-grp;
            }
          }
        }
      }
      description "VPWS constraints";
    }
  }

  /* augments */

  augment "/l2vpn/l2vpn-instances/l2vpn-instance/pw" {
    when "../type = 'vpws-instance-type'" "/pw:pseudowires/pw:pseudowire" {
    description "Pseudowire parameters only for VPWS pseudowires";
    }
    description "Augment for peudowire parameters for " +
                "VPWS pseudowires";
    leaf vccv-ability {
      type boolean;
      description "vccvability";
    }
    leaf request-vlanid {
      type uint16;
      description "request vlanid";
    }
    leaf vlan-tpid {
      type string;
      description "vlan tpid";
    }
    leaf ttl {
      type uint8;
      description "time-to-live";
    }
  }

  augment "/l2vpn/l2vpn-instances/l2vpn-instance" {
    when "type = 'vpls-instance-type'" "/pw:pseudowires/pw:pseudowire/pw:pw-type" {
    description "Parameters specifically for a VPLS instance";
    }
    description "Augment for parameters for a VPLS instance";
    uses pbb-parameters-grp;
  }

  augment "/l2vpn/l2vpn-instances/l2vpn-instance/endpoint" "Additional pseudowire types";
    case bgp-pw {
    when "../type = 'vpls-instance-type'"
      container bgp-pw {
        description "Endpoint parameter specifically for " +
                  "a VPLS instance";
    }
    description "Augment for endpoint parameters for a VPLS instance"; "BGP pseudowire";
        leaf split-horizon-group remote-pe-id {
          type string; inet:ip-address;
          description "Identify a split horizon group"; "remote pe id";
        }
      }

  augment "/l2vpn/l2vpn-instances/l2vpn-instance/endpoint" +
          "/ac-or-pw-or-redundancy-grp/redundancy-grp" +
          "/backup/backup-pw/backup-pw"
    }
    case bgp-ad-pw {
    when "../../type = 'vpls-instance-type'"
      container bgp-ad-pw {
        description "Backup pseudowire parameter specifically for " +
                  "a VPLS instance";
    }
    description "Augment for backup pseudowire paramters for " +
                "a VPLS instance"; "BGP auto-discovery pseudowire";
        leaf precedence remote-ve-id {
          type uint32; uint16;
          description "precedence of the pseudowire"; "remote ve id";
        }
      }
    }
  }

  augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance" +
          "/endpoint/ac-or-pw-or-redundancy-grp/pw/pw" "/l2vpn/instances/instance" {
    when "../../type "type = 'vpws-instance-type'" 'l2vpn:vpws-instance-type'" {
      description "Additional operational state specifically "Constraints only for " +
                  "a VPWS instance's pseudowire endpoint"; pseudowires";
    }
    description "Augment for a VPWS instance's pseudowire endpoint instance";
    container vpws-constraints {
      must "(count(../endpoint) < 2) and " +
                "operational state";
    uses vpws-only-pw-state-grp;
  }

  augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance"
           "(count(../endpoint/pw) < 1) and " +
          "/endpoint/ac-or-pw-or-redundancy-grp/redundancy-grp"
           "(count(../endpoint/ac) < 1) and " +
          "/primary/primary-pw/primary-pw" {
    when "../../type = 'vpws-instance-type'" {
      description "Additional operational state specifically for
           "(count(../endpoint/primary-pw) < 1) and " +
                  "a VPWS instance's primary pseudowire endpoint";
    }
           "(count(../endpoint/backup-pw) < 1) " {
        description "Augment for a "A VPWS instance's primary L2VPN instance has at most 2 endpoints " +
                    "and each endpoint has at most 1 pseudowire or " +
                "endpoint operational state";
    uses vpws-only-pw-state-grp;
                    "1 attachment circuit";
      }
      description "VPWS constraints";
    }
  }

  augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance" +
          "/endpoint/ac-or-pw-or-redundancy-grp/redundancy-grp" +
          "/backup/backup-pw/backup-pw" "/l2vpn/instances/instance" {
    when "../../type "type = 'vpws-instance-type'" 'l2vpn:vpls-instance-type'" {
      description "Additional operational state "Parameters specifically for " +
                  "a VPWS instance's backup pseudowire endpoint"; for a VPLS instance";
    }
    description "Augment for parameters for a VPWS instance's backup pseudowire " +
                "endpoint operational state"; VPLS instance";
    uses vpws-only-pw-state-grp; pbb-parameters-grp;
  }

  augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance" +
          "/endpoint" "/l2vpn/instances/instance/endpoint" {
    when "../type = 'vpls-instance-type'" 'l2vpn:vpls-instance-type'" {
      description "Endpoint parameter specifically for " +
                  "a VPLS instance operational state"; instance";
    }
    description "Augment for endpoint parameters for a VPLS " +
                "instance operational state"; instance";
    leaf split-horizon-group {
      type string;
      description "Identify a split horizon group";
    }
  }

  augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance" "/l2vpn/instances/instance/endpoint" +
          "/ac-or-pw-or-redundancy-grp/redundancy-grp" +
          "/backup/backup-pw/backup-pw" {
    when "type "../../type = 'vpls-instance-type'" 'l2vpn:vpls-instance-type'" {
      description "Additional operational state "Backup pseudowire parameter specifically for " +
                  "a VPLS instance";
    }
    description "Augment for a VPLS instance's backup pseudowire paramters for " +
                "operational state";
                "a VPLS instance";
    leaf precedence {
      type uint32;
      description "precedence of the pseudowire";
    }
  }

  /* Notifications */

  notification l2vpn-state-change-notification {
    description "L2VPN and constituents state change notification";
    uses one-l2vpn-instance-grp;
    uses pbb-parameters-state-grp; endpoint-grp {
      augment "ac-or-pw-or-redundancy-grp/ac" {
        description "Augment for attachment circuit(s) " +
                    "as an endpoint";
        leaf ac {
          type leafref {
            path "/l2vpn/instances/instance" +
                    "[name=current()/../l2vpn-instance-name]" +
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/pw/name";
          }
          description "Related attachment circuit";
        }
      }
      augment "/l2vpn-state/l2vpn-instances-state/l2vpn-instance" "ac-or-pw-or-redundancy-grp/pw" {
        description "Augment for pseudowire(s) as an endpoint";
        leaf pw {
          type leafref {
            path "/l2vpn/instances/instance" +
          "/endpoint/ac-or-pw-or-redundancy-grp/redundancy-grp"
                    "[name=current()/../l2vpn-instance-name]" +
          "/backup/backup-pw/backup-pw"
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/pw/name";
          }
          description "Related pseudowire";
        }
      }
      augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
              "primary/primary-ac" {
    when "../../type = 'vpls-instance-type'"
        description "Augment for primary-ac";
        leaf primary-ac {
          type leafref {
            path "/l2vpn/instances/instance" +
                    "[name=current()/../l2vpn-instance-name]" +
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/primary-ac/name";
          }
          description "Additional operational state specifically "Related primary attachment circuit";
        }
      }
      augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
              "primary/primary-pw" {
        description "Augment for " primary-pw";
        leaf primary-pw {
          type leafref {
            path "/l2vpn/instances/instance" +
                  "a VPLS instance's backup pseudowire endpoint";
                    "[name=current()/../l2vpn-instance-name]" +
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/primary-pw/name";
          }
          description "Related primary pseudowire";
        }
      }
      augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
              "backup/backup-ac" {
        description "Augment for a VPLS instance's backup-ac";
        leaf backup-ac {
          type leafref {
            path "/l2vpn/instances/instance" +
                    "[name=current()/../l2vpn-instance-name]" +
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/backup-ac/name";
          }
          description "Related backup pseudowire " attachment circuit";
        }
      }
      augment "ac-or-pw-or-redundancy-grp/redundancy-grp/" +
                "endpoint operational state";
              "backup/backup-pw" {
        description "Augment for backup-pw";
        leaf precedence backup-pw {
          type uint32; leafref {
            path "/l2vpn/instances/instance" +
                    "[name=current()/../l2vpn-instance-name]" +
                    "[type=current()/../l2vpn-instance-type]" +
                 "/endpoint/backup-pw/name";
          }
          description "precedence of the "Related backup pseudowire";
        }
      }
    }
    leaf state {
      type identityref {
        base l2vpn-notification-state;
      }
      description "State change notification";
    }
  }

}

<CODE ENDS>

                                 Figure 3

5.  Security Considerations

   The configuration, state, action and notification data defined in
   this document are designed to be accessed via the NETCONF protocol
   [RFC6241].  The lowest NETCONF layer is the secure transport layer
   and the mandatory-to-implement secure transport is SSH [RFC6242].
   The NETCONF access control model [RFC6536] provides means to restrict
   access for particular NETCONF users to a pre-configured subset of all
   available NETCONF protocol operations and content.

   The security concerns listed above are, however, no different than
   faced by other routing protocols.  Hence, this draft does not change
   any underlying security issues inherent in [I-D.ietf-netmod-routing-
   cfg]

6.  IANA Considerations

   None.

7.  Acknowledgments

   The authors would like to acknowledge Giles Heron and others for
   their useful comments.

8.  References

8.1.  Normative References

   [RFC2119]  Bradner, S., "Key words for use in RFCs to Indicate
              Requirement Levels", BCP 14, RFC 2119,
              DOI 10.17487/RFC2119, March 1997,
              <http://www.rfc-editor.org/info/rfc2119>.

8.2.  Informative References

   [RFC3916]  Xiao, X., Ed., McPherson, D., Ed., and P. Pate, Ed.,
              "Requirements for Pseudo-Wire Emulation Edge-to-Edge
              (PWE3)", RFC 3916, DOI 10.17487/RFC3916, September 2004,
              <http://www.rfc-editor.org/info/rfc3916>.

   [RFC3985]  Bryant, S., Ed. and P. Pate, Ed., "Pseudo Wire Emulation
              Edge-to-Edge (PWE3) Architecture", RFC 3985,
              DOI 10.17487/RFC3985, March 2005,
              <http://www.rfc-editor.org/info/rfc3985>.

   [RFC4385]  Bryant, S., Swallow, G., Martini, L., and D. McPherson,
              "Pseudowire Emulation Edge-to-Edge (PWE3) Control Word for
              Use over an MPLS PSN", RFC 4385, DOI 10.17487/RFC4385,
              February 2006, <http://www.rfc-editor.org/info/rfc4385>.

   [RFC4446]  Martini, L., "IANA Allocations for Pseudowire Edge to Edge
              Emulation (PWE3)", BCP 116, RFC 4446,
              DOI 10.17487/RFC4446, April 2006,
              <http://www.rfc-editor.org/info/rfc4446>.

   [RFC4447]  Martini, L., Ed., Rosen, E., El-Aawar, N., Smith, T., and
              G. Heron, "Pseudowire Setup and Maintenance Using the
              Label Distribution Protocol (LDP)", RFC 4447,
              DOI 10.17487/RFC4447, April 2006,
              <http://www.rfc-editor.org/info/rfc4447>.

   [RFC4448]  Martini, L., Ed., Rosen, E., El-Aawar, N., and G. Heron,
              "Encapsulation Methods for Transport of Ethernet over MPLS
              Networks", RFC 4448, DOI 10.17487/RFC4448, April 2006,
              <http://www.rfc-editor.org/info/rfc4448>.

   [RFC4664]  Andersson, L., Ed. and E. Rosen, Ed., "Framework for Layer
              2 Virtual Private Networks (L2VPNs)", RFC 4664,
              DOI 10.17487/RFC4664, September 2006,
              <http://www.rfc-editor.org/info/rfc4664>.

   [RFC4665]  Augustyn, W., Ed. and Y. Serbest, Ed., "Service
              Requirements for Layer 2 Provider-Provisioned Virtual
              Private Networks", RFC 4665, DOI 10.17487/RFC4665,
              September 2006, <http://www.rfc-editor.org/info/rfc4665>.

   [RFC4761]  Kompella, K., Ed. and Y. Rekhter, Ed., "Virtual Private
              LAN Service (VPLS) Using BGP for Auto-Discovery and
              Signaling", RFC 4761, DOI 10.17487/RFC4761, January 2007,
              <http://www.rfc-editor.org/info/rfc4761>.

   [RFC4762]  Lasserre, M., Ed. and V. Kompella, Ed., "Virtual Private
              LAN Service (VPLS) Using Label Distribution Protocol (LDP)
              Signaling", RFC 4762, DOI 10.17487/RFC4762, January 2007,
              <http://www.rfc-editor.org/info/rfc4762>.

   [RFC5003]  Metz, C., Martini, L., Balus, F., and J. Sugimoto,
              "Attachment Individual Identifier (AII) Types for
              Aggregation", RFC 5003, DOI 10.17487/RFC5003, September
              2007, <http://www.rfc-editor.org/info/rfc5003>.

   [RFC5254]  Bitar, N., Ed., Bocci, M., Ed., and L. Martini, Ed.,
              "Requirements for Multi-Segment Pseudowire Emulation Edge-
              to-Edge (PWE3)", RFC 5254, DOI 10.17487/RFC5254, October
              2008, <http://www.rfc-editor.org/info/rfc5254>.

   [RFC5659]  Bocci, M. and S. Bryant, "An Architecture for Multi-
              Segment Pseudowire Emulation Edge-to-Edge", RFC 5659,
              DOI 10.17487/RFC5659, October 2009,
              <http://www.rfc-editor.org/info/rfc5659>.

   [RFC6020]  Bjorklund, M., Ed., "YANG - A Data Modeling Language for
              the Network Configuration Protocol (NETCONF)", RFC 6020,
              DOI 10.17487/RFC6020, October 2010,
              <http://www.rfc-editor.org/info/rfc6020>.

   [RFC6073]  Martini, L., Metz, C., Nadeau, T., Bocci, M., and M.
              Aissaoui, "Segmented Pseudowire", RFC 6073,
              DOI 10.17487/RFC6073, January 2011,
              <http://www.rfc-editor.org/info/rfc6073>.

   [RFC6074]  Rosen, E., Davie, B., Radoaca, V., and W. Luo,
              "Provisioning, Auto-Discovery, and Signaling in Layer 2
              Virtual Private Networks (L2VPNs)", RFC 6074,
              DOI 10.17487/RFC6074, January 2011,
              <http://www.rfc-editor.org/info/rfc6074>.

   [RFC6241]  Enns, R., Ed., Bjorklund, M., Ed., Schoenwaelder, J., Ed.,
              and A. Bierman, Ed., "Network Configuration Protocol
              (NETCONF)", RFC 6241, DOI 10.17487/RFC6241, June 2011,
              <http://www.rfc-editor.org/info/rfc6241>.

   [RFC6242]  Wasserman, M., "Using the NETCONF Protocol over Secure
              Shell (SSH)", RFC 6242, DOI 10.17487/RFC6242, June 2011,
              <http://www.rfc-editor.org/info/rfc6242>.

   [RFC6391]  Bryant, S., Ed., Filsfils, C., Drafz, U., Kompella, V.,
              Regan, J., and S. Amante, "Flow-Aware Transport of
              Pseudowires over an MPLS Packet Switched Network",
              RFC 6391, DOI 10.17487/RFC6391, November 2011,
              <http://www.rfc-editor.org/info/rfc6391>.

   [RFC6423]  Li, H., Martini, L., He, J., and F. Huang, "Using the
              Generic Associated Channel Label for Pseudowire in the
              MPLS Transport Profile (MPLS-TP)", RFC 6423,
              DOI 10.17487/RFC6423, November 2011,
              <http://www.rfc-editor.org/info/rfc6423>.

   [RFC6478]  Martini, L., Swallow, G., Heron, G., and M. Bocci,
              "Pseudowire Status for Static Pseudowires", RFC 6478,
              DOI 10.17487/RFC6478, May 2012,
              <http://www.rfc-editor.org/info/rfc6478>.

   [RFC6536]  Bierman, A. and M. Bjorklund, "Network Configuration
              Protocol (NETCONF) Access Control Model", RFC 6536,
              DOI 10.17487/RFC6536, March 2012,
              <http://www.rfc-editor.org/info/rfc6536>.

   [RFC6624]  Kompella, K., Kothari, B., and R. Cherukuri, "Layer 2
              Virtual Private Networks Using BGP for Auto-Discovery and
              Signaling", RFC 6624, DOI 10.17487/RFC6624, May 2012,
              <http://www.rfc-editor.org/info/rfc6624>.

   [RFC7041]  Balus, F., Ed., Sajassi, A., Ed., and N. Bitar, Ed.,
              "Extensions to the Virtual Private LAN Service (VPLS)
              Provider Edge (PE) Model for Provider Backbone Bridging",
              RFC 7041, DOI 10.17487/RFC7041, November 2013,
              <http://www.rfc-editor.org/info/rfc7041>.

   [RFC7361]  Dutta, P., Balus, F., Stokes, O., Calvignac, G., and D.
              Fedyk, "LDP Extensions for Optimized MAC Address
              Withdrawal in a Hierarchical Virtual Private LAN Service
              (H-VPLS)", RFC 7361, DOI 10.17487/RFC7361, September 2014,
              <http://www.rfc-editor.org/info/rfc7361>.

Appendix A.  Example Configuration

   This section shows an example configuration using the YANG data model
   defined in the document.

Appendix B.  Contributors

   The editors gratefully acknowledge the following people for their
   contributions to this document.

                  Reshad Rahman
                  Cisco Systems, Inc.
                  Email: rrahman@cisco.com

                  Kamran Raza
                  Cisco Systems, Inc.
                  Email: skraza@cisco.com

                  Giles Heron
                  Cisco Systems, Inc.
                  Email: giheron@cisco.com

                 Tapraj Singh
                 Cisco Systems, Inc.
                 Email: tsingh@cisco.com

                 Zhenbin Li
                 Huawei Technologies
                 Email: lizhenbin@huawei.com

                 Zhuang Shunwan
                 Huawei Technologies
                 Email: Zhuangshunwan@huawei.com

                 Wang Haibo
                 Huawei Technologies
                 Email: rainsword.wang@huawei.com

                 Sajjad Ahmed
                 Ericsson
                 Email: sajjad.ahmed@ericsson.com

                 Matthew Bocci
                 Nokia
                 Email: matthew.bocci@nokia.com

                 Jorge Rabadan
                 Nokia
                 Email: jorge.rabadan@nokia.com

                 Jonathan Hardwick
                 Metaswitch
                 Email: jonathan.hardwick@metaswitch.com

                 Santosh Esale
                 Juniper Networks
                 Email: sesale@juniper.net

                 Nick Delregno
                 Verizon
                 Email: nick.deregno@verizon.com

                 Luay Jalil
                 Verizon
                 Email: luay.jalil@verizon.com

                 Maria Joecylyn
                 Verizon
                 Email: joecylyn.malit@verizon.com

                                 Figure 4

Authors' Addresses

   Himanshu Shah
   Ciena Corporation

   Email: hshah@ciena.com

   Patrice Brissette
   Cisco Systems, Inc.

   Email: pbrisset@cisco.com
   Ing-When Chen
   Jabil

   Email: ing-wher_chen@jabil.com

   Iftekar Hussain
   Infinera Corporation

   Email: ihussain@infinera.com

   Bin Wen
   Comcast

   Email: Bin_Wen@cable.comcast.com

   Kishore Tiruveedhula
   Juniper Networks

   Email: kishoret@juniper.net