<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-li-bess-l3vpn-yang-01" ipr="trust200902">
  <front>
    <title abbrev="Yang Data Model for L3VPN">Yang Data Model for BGP/MPLS IP
    VPN</title>

    <author fullname="Zhenbin Li" initials="Z. " surname="Li">
      <organization>Huawei Technologies</organization>

      <address>
        <postal>
          <street>Huawei Bld., No.156 Beiqing Rd.</street>

          <city>Beijing</city>

          <code>100095</code>

          <country>China</country>
        </postal>

        <email>lizhenbin@huawei.com</email>
      </address>
    </author>

    <author fullname="Shunwan Zhuang" initials="S. " surname="Zhuang">
      <organization>Huawei Technologies</organization>

      <address>
        <postal>
          <street>Huawei Bld., No.156 Beiqing Rd.</street>

          <city>Beijing</city>

          <code>100095</code>

          <country>China</country>
        </postal>

        <email>zhuangshunwan@huawei.com</email>
      </address>
    </author>

    <author fullname="Xufeng Liu" initials="X." surname="Liu">
      <organization>Ericsson</organization>

      <address>
        <postal>
          <street>1595 Spring Hill Road, Suite 500</street>

          <city>Vienna</city>

          <region>VA</region>

          <code>22182</code>

          <country>USA</country>
        </postal>

        <email>xufeng.liu@ericsson.com</email>
      </address>
    </author>

    <author fullname="Jeffrey Haas" initials="J." surname="Haas">
      <organization>Juniper Networks</organization>

      <address>
        <postal>
          <street/>
        </postal>

        <email>jhaas@juniper.net</email>
      </address>
    </author>

    <author fullname="Santosh Esale " initials="S." surname="Esale ">
      <organization>Juniper Networks</organization>

      <address>
        <postal>
          <street>1194 N. Mathilda Ave.</street>

          <city>Sunnyvale</city>

          <region>CA</region>

          <code>94089</code>

          <country>US</country>
        </postal>

        <email>sesale@juniper.net</email>
      </address>
    </author>

    <author fullname="Bin Wen" initials="B." surname="Wen">
      <organization>Comcast</organization>

      <address>
        <postal>
          <street/>
        </postal>

        <email>Bin_Wen@cable.comcast.com</email>
      </address>
    </author>

    <date day="21" month="December" year="2015"/>

    <abstract>
      <t>This document defines a YANG data model that can be used to configure
      and manage L3VPN (BGP/MPLS IP VPN).</t>
    </abstract>

    <note title="Requirements Language">
      <t>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 <xref
      target="RFC2119">RFC 2119</xref>.</t>
    </note>
  </front>

  <middle>
    <section title="Introduction">
      <t>YANG <xref target="RFC6020"/> is a data definition language that was
      introduced to define the contents of a conceptual data store that allows
      networked devices to be managed using NETCONF <xref target="RFC6241"/>.
      YANG is proving relevant beyond its initial confines, as bindings to
      other interfaces (e.g. ReST) and encodings other than XML (e.g. JSON)
      are being defined. Furthermore, YANG data models can be used as the
      basis of implementation for other interfaces, such as CLI and
      programmatic APIs.</t>

      <t>This document defines a YANG data model that can be used to configure
      and manage L3VPN (BGP/MPLS IP VPN) <xref target="RFC4364"/>.</t>
    </section>

    <section title="Definitions and Acronyms">
      <t>AF: Address Family</t>

      <t>BGP: Border Gateway Protocol</t>

      <t>JSON: JavaScript Object Notation</t>

      <t>L3VPN: Layer 3 VPN</t>

      <t>NETCONF: Network Configuration Protocol</t>

      <t>ReST: Representational State Transfer, a style of stateless interface
      and protocol that is generally carried over HTTP</t>

      <t>YANG: A data definition language for NETCONF</t>
    </section>

    <section title="Design of the L3VPN Model">
      <t/>

      <section title="Overview">
        <t>The L3VPN Yang module is to augment the routing instance Yang
        models proposed by the draft <xref
        target="I-D.ietf-netmod-routing-cfg"/>. It introduced the
        "l3vpn"container to define augmented parameters which can be applied
        for VRF Routing Instance and support both the IPv4 and IPv6 address
        families. The overview of the "l3vpn" container is shown in the
        following figure:</t>

        <figure>
          <artwork align="left"><![CDATA[module: ietf-l3vpn
augment /rt:routing/rt:routing-instance:
   +--rw l3vpn
      +--rw ipv4-family
      |  +--rw bgp-parameters
      |  |  +--rw common
      |  |     +--rw route-distinguisher?   string
      |  |     +--rw vpn-targets* [rt-value]
      |  |        +--rw rt-value    string
      |  |        +--rw rt-type     bgp-rt-type
      |  ......
      +--rw ipv6-family
         +--rw bgp-parameters
         |  +--rw common
         |     +--rw route-distinguisher?   string
         |     +--rw vpn-targets* [rt-value]
         |        +--rw rt-value    string
         |        +--rw rt-type     bgp-rt-type
         ......
]]></artwork>
        </figure>

        <t/>

        <t>L3VPN inteface parameters can reuse those parameters defined by
        <xref target="I-D.ietf-netmod-routing-cfg"/>.</t>

        <t>BGP Protocols parameters for L3VPN is defined by the draft <xref
        target="I-D.ietf-idr-bgp-model"/>. The augment may be defined in the
        future version if necessary.</t>
      </section>

      <section title="VPN Instance Configuration">
        <t>An instance is created to comprise the VPN forwarding information
        for each VPN in a BGP/MPLS IP VPN. This instance is called a VPN
        instance or a VPN routing and forwarding (VRF) table. It is also
        called a per-site forwarding table in <xref target="RFC4364"/>. VPN
        instances must be created in all BGP/MPLS IP VPN solutions. VPN
        instances support both the IPv4 and IPv6 address families.</t>

        <t>VPN instance configuration consists of the following components
        :</t>

        <t>o Per-Instance Configuration : that contains the common writable
        configuration objects for VPN instance IPv4 and IPv6 address
        family.</t>

        <t>o Address Family Configuration of L3VPN Instance: that contains the
        address family specific writable configuration objects.</t>

        <section title="Per-Instance Configuration">
          <t>Per-instance parameters is defined by <xref
          target="I-D.ietf-netmod-routing-cfg"/> including instance name,
          description, etc.</t>
        </section>

        <section title="Address Family Configuration of L3VPN Instance">
          <t>l3vpn container contains the address family specific writable
          configuration objects, such as route-distinguisher, vpn-targets,
          apply-label-mode, etc. The parameters should be consistent between
          IPv4 family and IPv6 family.</t>

          <t><figure>
              <artwork align="left"><![CDATA[   +--rw l3vpn
      +--rw ipv4-family
      |  +--rw bgp-parameters
      |  |  +--rw common
      |  |     +--rw route-distinguisher?   string
      |  |     +--rw vpn-targets* [rt-value]
      |  |        +--rw rt-value    string
      |  |        +--rw rt-type     bgp-rt-type
      |  +--rw apply-label-mode?      apply-label-mode-def
      |  +--rw import-route-policy?   string
      |  +--rw export-route-policy?   string
      |  +--rw tunnel-policy?         string
      |  +--rw prefix-limit
      |  |  +--rw prefix-limit-number?   uint32
      |  |  +--rw (prefix-limit-action)?
      |  |     +--:(enable-alert-percent)
      |  |     |  +--rw alert-percent-value?   uint8
      |  |     |  +--rw route-unchanged?       boolean
      |  |     +--:(enable-simple-alert)
      |  |        +--rw simple-alert?          boolean
      |  +--rw routing-table-limit
      |  |  +--rw routing-table-limit-number?   uint32
      |  |  +--rw (routing-table-limit-action)?
      |  |     +--:(enable-alert-percent)
      |  |     |  +--rw alert-percent-value?          uint8
      |  |     +--:(enable-simple-alert)
      |  |        +--rw simple-alert?                 boolean
      |  +--rw import-global-rib
      |     +--rw protocol?            enumeration
      |     +--rw processId?           uint32
      |     +--rw bgp-valid-route?     boolean
      |     +--rw route-policy-name?   string
      +--rw ipv6-family
         ......
]]></artwork>
            </figure></t>

          <t/>
        </section>
      </section>

      <section title="Yang Tree of L3VPN Yang Model">
        <t>The Yang tree of L3VPn Yang model is shown in the following
        figure:</t>

        <t><figure>
            <artwork align="left"><![CDATA[module: ietf-l3vpn
augment /rt:routing/rt:routing-instance:
   +--rw l3vpn
      +--rw ipv4-family
      |  +--rw bgp-parameters
      |  |  +--rw common
      |  |     +--rw route-distinguisher?   string
      |  |     +--rw vpn-targets* [rt-value]
      |  |        +--rw rt-value    string
      |  |        +--rw rt-type     bgp-rt-type
      |  +--rw apply-label-mode?      apply-label-mode-def
      |  +--rw import-route-policy?   string
      |  +--rw export-route-policy?   string
      |  +--rw tunnel-policy?         string
      |  +--rw prefix-limit
      |  |  +--rw prefix-limit-number?   uint32
      |  |  +--rw (prefix-limit-action)?
      |  |     +--:(enable-alert-percent)
      |  |     |  +--rw alert-percent-value?   uint8
      |  |     |  +--rw route-unchanged?       boolean
      |  |     +--:(enable-simple-alert)
      |  |        +--rw simple-alert?          boolean
      |  +--rw routing-table-limit
      |  |  +--rw routing-table-limit-number?   uint32
      |  |  +--rw (routing-table-limit-action)?
      |  |     +--:(enable-alert-percent)
      |  |     |  +--rw alert-percent-value?          uint8
      |  |     +--:(enable-simple-alert)
      |  |        +--rw simple-alert?                 boolean
      |  +--rw import-global-rib
      |     +--rw protocol?            enumeration
      |     +--rw processId?           uint32
      |     +--rw bgp-valid-route?     boolean
      |     +--rw route-policy-name?   string
      +--rw ipv6-family
         +--rw bgp-parameters
         |  +--rw common
         |     +--rw route-distinguisher?   string
         |     +--rw vpn-targets* [rt-value]
         |        +--rw rt-value    string
         |        +--rw rt-type     bgp-rt-type
         +--rw apply-label-mode?      apply-label-mode-def
         +--rw import-route-policy?   string
         +--rw export-route-policy?   string
         +--rw tunnel-policy?         string
         +--rw prefix-limit
         |  +--rw prefix-limit-number?   uint32
         |  +--rw (prefix-limit-action)?
         |     +--:(enable-alert-percent)
         |     |  +--rw alert-percent-value?   uint8
         |     |  +--rw route-unchanged?       boolean
         |     +--:(enable-simple-alert)
         |        +--rw simple-alert?          boolean
         +--rw routing-table-limit
         |  +--rw routing-table-limit-number?   uint32
         |  +--rw (routing-table-limit-action)?
         |     +--:(enable-alert-percent)
         |     |  +--rw alert-percent-value?          uint8
         |     +--:(enable-simple-alert)
         |        +--rw simple-alert?                 boolean
         +--rw import-global-rib
            +--rw protocol?            enumeration
            +--rw processId?           uint32
            +--rw bgp-valid-route?     boolean
            +--rw route-policy-name?   string
]]></artwork>
          </figure></t>

        <t/>
      </section>
    </section>

    <section title="L3VPN YANG Model">
      <t/>

      <t><figure>
          <artwork align="left"><![CDATA[//L3VPN YANG MODEL
<CODE BEGINS> file "ietf-l3vpn.yang"
module ietf-l3vpn {
  namespace "urn:ietf:params:xml:ns:yang:ietf-l3vpn";
  // replace with IANA namespace when assigned
  prefix "l3vpn";

  import ietf-routing {
    prefix "rt";
    //draft-ietf-netmod-routing-cfg-19
  }

  organization  "IETF BGP Enabled Services WG";
  contact       "draft-li-bess-l3vpn-yang@tools.ietf.org";
  description
    "This YANG module defines the generic configuration data
     for L3VPN service.

     Terms and Acronyms

     BGP (bgp): Border Gateway Protocol
     IPv4 (ipv4):Internet Protocol Version 4
     IPv6 (ipv6): Internet Protocol Version 6

    ";

  revision 2015-10-09 {
    description
      "Initial revision.";
      reference "RFC4271, RFC4364, RFC4365, RFC4760.";
  }

  /* typedefs */

  typedef bgp-rt-type {
    type enumeration {
      enum import {
        description "For import";
      }
      enum export {
        description "For export";
      }
      enum both {
        description "For both import and export";
      }
    }
    description "BGP route-target type. Import from BGP YANG.";
  }

  typedef apply-label-mode-def {
    type enumeration {
      enum "per-route" {
        value 0;
        description
          "By default, the VPN instance IPv4 address family
           assigns a unique label to each route to be sent
           to the peer PE.";
      }
      enum "per-instance" {
        value 1;
        description
          "The apply-label per-instance command enables the
           one-label-per-VPN-instance mode.";
      }
    }
    description "...";
  }

  typedef routing-instance-type-ref {
    type leafref {
      path "/rt:routing/rt:routing-instance/rt:type";
    }
    description
      "This type is used for leafs that reference a routing
       instance configuration.";
  }

  grouping bgp-parameters-grp {
    description
      "BGP parameters grouping.";
    container bgp-parameters {
      description
        "Parameters for BGP.";
      container common {
        description
          "Common BGP parameters.";
        leaf route-distinguisher {
          type string;
          description "BGP RD.";
        }
        list vpn-targets {
          key rt-value;
          description
            "Route Targets.";
          leaf rt-value {
            type string;
            description
              "Route-Target value.";
          }
          leaf rt-type {
            type bgp-rt-type;
            mandatory true;
            description
              "Type of RT.";
          }
        }
      }
    }
  }


  grouping vpn-af-config {
    description
      "A set of configuration parameters that is applicable to both
       IPv4 and IPv6 address family for a VPN instance .";

    leaf apply-label-mode {
      type apply-label-mode-def;
      default "per-route";
      description ".";
    }

    leaf import-route-policy {
      type string {
        length "1..40";
      }
      description
        "The import route-policy command associates a VPN instance
         enabled with the IPv4 or IPv6 address family with an
         import routing policy.
         Only one import routing policy can be associated with a
         VPN instance enabled with the IPv4 or IPv6 address family.
         If the import route-policy command is run more than once,
         the latest configuration overrides the previous ones.";
    }

    leaf export-route-policy {
      type string {
        length "1..40";
      }
      description
        "The export route-policy command associates a VPN instance
         enabled with the IPv4 or IPv6 address family with an
         export routing policy.
         Only one export routing policy can be associated with a
         VPN instance enabled with the IPv4 or IPv6 address family.
         If the export route-policy command is run more than once,
         the latest configuration overrides the previous ones.";
    }

    leaf tunnel-policy {
       type string;
       description
         "Tunnel policy name.";
    }

    container prefix-limit {
      description
        "The prefix limit command sets a limit on the maximum
         number of prefixes supported in the existing VPN
         instance, preventing the PE from importing excessive
         VPN route prefixes.";

      leaf prefix-limit-number {
        type uint32 {
          range "1..4294967295";
        }
        description
          "Specifies the maximum number of prefixes supported in the
           VPN instance IPv4 or IPv6 address family.";
      }

      choice prefix-limit-action {
        description ".";
        case enable-alert-percent {
          leaf alert-percent-value {
            type uint8 {
              range "1..100";
            }
            description
              "Specifies the proportion of the alarm threshold to the
               maximum number of prefixes.";
          }
          leaf route-unchanged {
            type boolean;
            default "false";
            description
              "Indicates that the routing table remains unchanged.
               By default, route-unchanged is not configured. When
               the number of prefixes in the routing table is
               greater than the value of the parameter number,
               routes are processed as follows:
               (1)If route-unchanged is configured, routes in the
                  routing table remain unchanged.
               (2)If route-unchanged is not configured, all routes
                  in the routing table are deleted and then
                  re-added.";
          }
        }
        case enable-simple-alert {
          leaf simple-alert {
            type boolean;
            default "false";
            description
              "Indicates that when the number of VPN route prefixes
               exceeds number, prefixes can still join the VPN
               routing table and alarms are displayed.";
          }
        }
      }
    }


    container routing-table-limit {
      description
        "The routing-table limit command sets a limit on the maximum
         number of routes that the IPv4 or IPv6 address family of a
         VPN instance can support.
         By default, there is no limit on the maximum number of
         routes that the IPv4 or IPv6 address family of a VPN
         instance can support, but the total number of private
         network and public network routes on a device cannot
         exceed the allowed maximum number of unicast routes.";

      leaf routing-table-limit-number {
        type uint32 {
          range "1..4294967295";
        }
        description
          "Specifies the maximum number of routes supported by a
           VPN instance. ";
      }

      choice routing-table-limit-action {
        description ".";
        case enable-alert-percent {
          leaf alert-percent-value {
            type uint8 {
              range "1..100";
            }
            description
              "Specifies the percentage of the maximum number of
               routes. When the maximum number of routes that join
               the VPN instance is up to the value
               (number*alert-percent)/100, the system prompts
               alarms. The VPN routes can be still added to the
               routing table, but after the number of routes
               reaches number, the subsequent routes are
               dropped.";
          }
        }
        case enable-simple-alert {
          leaf simple-alert {
            type boolean;
            description
              "Indicates that when VPN routes exceed number, routes
               can still be added into the routing table, but the
               system prompts alarms.
               However, after the total number of VPN routes and
               network public routes reaches the unicast route limit
               specified in the License, the subsequent VPN routes
               are dropped.";
          }
        }
      }
    }

    container import-global-rib {
      description
        "Route Leaking from a Global Routing Table into a VRF.";

      leaf protocol {
        type enumeration {
          enum ALL {
            value "0";
            description "ALL:";
          }
          enum Direct {
            value "1";
            description "Direct:";
          }
          enum OSPF {
            value "2";
            description "OSPF:";
          }
          enum ISIS {
            value "3";
            description "ISIS:";
          }
          enum Static {
            value "4";
            description "Static:";
          }
          enum RIP {
            value "5";
            description "RIP:";
          }
          enum BGP {
            value "6";
            description "BGP:";
          }
          enum OSPFV3 {
            value "7";
            description "OSPFV3:";
          }
          enum RIPNG {
            value "8";
            description "RIPNG:";
          }
          enum INVALID {
            value "9";
            description "INVALID:";
          }
        }
        description
          "Specifies the protocol from which routes are imported.
           At present, In the IPv4 unicast address family view,
           the protocol can be IS-IS,static, direct and BGP.";
      }

      leaf processId {
        type uint32 {
          range "0..4294967295";
        }
        default "0";
        description
          "Specifies the process ID if the protocol from routes
           are imported is IS-IS.";
      }

      leaf bgp-valid-route {
        type boolean;
        description ".";
      }

      leaf route-policy-name {
        type string;
        description
          "Policy Id for import routes";
      }

    }
  }

  augment "/rt:routing/rt:routing-instance" {
    description ".";
    container l3vpn {
      when "routing-instance-type-ref = 'vrf-routing-instance'" {
        description ".";
      }
      description ".";
      container ipv4-family {
        description
          "The IPv4 address family is enabled for the VPN
           instance.";

        uses bgp-parameters-grp;
        uses vpn-af-config;
      }

      container ipv6-family {
        description
          "The IPv6 address family is enabled for the VPN
           instance.";

        uses bgp-parameters-grp;
        uses vpn-af-config;
      }
    } //End of case type

  } //End of augment "/rt:routing/rt:routing-instance"

}
</CODE ENDS>

]]></artwork>
        </figure></t>

      <t/>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>This document makes no request of IANA.</t>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>This document does not introduce any new security risk.</t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119"?>

      <?rfc include="reference.RFC.4271"?>

      <?rfc include='reference.RFC.4364'?>

      <?rfc include='reference.RFC.4760'?>

      <?rfc include='reference.RFC.6020'?>

      <?rfc include='reference.RFC.6241'?>

      <?rfc include='reference.I-D.ietf-netmod-routing-cfg'?>

      <?rfc include='reference.I-D.ietf-idr-bgp-model'?>
    </references>
  </back>
</rfc>
