module openconfig-bgp-types {
  yang-version "1";

  namespace "http://openconfig.net/yang/bgp-types";

  prefix "bgp-types";

  import ietf-inet-types { prefix inet; revision-date 2013-07-15;}
  import openconfig-types { prefix oc-types; }
  import openconfig-extensions { prefix oc-ext; }

  // meta
  organization
    "OpenConfig working group";

  contact
    "OpenConfig working group
    netopenconfig@googlegroups.com";

  description
    "This module contains general data definitions for use in BGP
    policy. It can be imported by modules that make use of BGP
    attributes";

  oc-ext:openconfig-version "1.1.0";

  revision "2015-10-09" {
    description
      "Initial OpenConfig public release";
    reference "1.1.0";
  }

  revision "2015-05-15" {
    description "Initial revision";
    reference "Pre-release";
  }


  identity bgp-capability {
    description "Base identity for a BGP capability";
  }

  identity MPBGP {
    base "bgp-capability";
    description
      "Multi-protocol extensions to BGP";
    reference "RFC2858";
  }

  identity ROUTE-REFRESH {
    base "bgp-capability";
    description
      "The BGP route-refresh functionality";
    reference "RFC2918";
  }

  identity ASN32 {
    base "bgp-capability";
    description
      "4-byte (32-bit) AS number functionality";
    reference "RFC6793";
  }

  identity GRACEFUL-RESTART {
    base "bgp-capability";
    description
      "Graceful restart functionality";
    reference "RFC4724";
  }

  identity ADD-PATHS {
    base "bgp-capability";
    description
      "BGP add-paths";
    reference "draft-ietf-idr-add-paths";
  }

  identity afi-safi-type {
    description
      "Base identity type for AFI,SAFI tuples for BGP-4";
    reference "RFC4760 - multiprotocol extensions for BGP-4";
  }

  identity IPV4-UNICAST {
    base afi-safi-type;
    description
      "IPv4 unicast (AFI,SAFI = 1,1)";
    reference "RFC4760";
  }

  identity IPV6-UNICAST {
    base afi-safi-type;
    description
      "IPv6 unicast (AFI,SAFI = 2,1)";
    reference "RFC4760";
  }

  identity IPV4-LABELLED-UNICAST {
    base afi-safi-type;
    description
      "Labelled IPv4 unicast (AFI,SAFI = 1,4)";
    reference "RFC3107";
  }

  identity IPV6-LABELLED-UNICAST {
    base afi-safi-type;
    description
      "Labelled IPv6 unicast (AFI,SAFI = 2,4)";
    reference "RFC3107";
  }

  identity L3VPN-IPV4-UNICAST {
    base afi-safi-type;
    description
      "Unicast IPv4 MPLS L3VPN (AFI,SAFI = 1,128)";
    reference "RFC4364";
  }

  identity L3VPN-IPV6-UNICAST {
    base afi-safi-type;
    description
      "Unicast IPv6 MPLS L3VPN (AFI,SAFI = 2,128)";
    reference "RFC4659";
  }

  identity L3VPN-IPV4-MULTICAST {
    base afi-safi-type;
    description
      "Multicast IPv4 MPLS L3VPN (AFI,SAFI = 1,129)";
    reference "RFC6514";
  }

  identity L3VPN-IPV6-MULTICAST {
    base afi-safi-type;
    description
      "Multicast IPv6 MPLS L3VPN (AFI,SAFI = 2,129)";
    reference "RFC6514";
  }

  identity L2VPN-VPLS {
    base afi-safi-type;
    description
      "BGP-signalled VPLS (AFI,SAFI = 25,65)";
    reference "RFC4761";
  }

  identity L2VPN-EVPN {
    base afi-safi-type;
    description
      "BGP MPLS Based Ethernet VPN (AFI,SAFI = 25,70)";
  }

  identity bgp-well-known-std-community {
    description
      "Reserved communities within the standard community space
      defined by RFC1997. These communities must fall within the
      range 0x00000000 to 0xFFFFFFFF";
    reference "RFC1997";
  }

  identity NO_EXPORT {
    base bgp-well-known-std-community;
    description
      "Do not export NLRI received carrying this community outside
      the bounds of this autonomous system, or this confederation if
      the local autonomous system is a confederation member AS. This
      community has a value of 0xFFFFFF01.";
    reference "RFC1997";
  }

  identity NO_ADVERTISE {
    base bgp-well-known-std-community;
    description
      "All NLRI received carrying this community must not be
      advertised to other BGP peers. This community has a value of
      0xFFFFFF02.";
    reference "RFC1997";
  }

  identity NO_EXPORT_SUBCONFED {
    base bgp-well-known-std-community;
    description
      "All NLRI received carrying this community must not be
      advertised to external BGP peers - including over confederation
      sub-AS boundaries. This community has a value of 0xFFFFFF03.";
    reference "RFC1997";
  }

  identity NOPEER {
    base bgp-well-known-std-community;
    description
      "An autonomous system receiving NLRI tagged with this community
      is advised not to readvertise the NLRI to external bi-lateral
      peer autonomous systems. An AS may also filter received NLRI
      from bilateral peer sessions when they are tagged with this
      community value";
    reference "RFC3765";
  }

  typedef bgp-session-direction {
    type enumeration {
      enum INBOUND {
        description
          "Refers to all NLRI received from the BGP peer";
      }
      enum OUTBOUND {
        description
          "Refers to all NLRI advertised to the BGP peer";
      }
    }
    description
      "Type to describe the direction of NLRI transmission";
  }

  typedef bgp-well-known-community-type {
    type identityref {
      base bgp-well-known-std-community;
    }
    description
      "Type definition for well-known IETF community attribute
      values";
    reference
      "IANA Border Gateway Protocol (BGP) Well Known Communities";
  }


  typedef bgp-std-community-type {
    // TODO: further refine restrictions and allowed patterns
    // 4-octet value:
    //  <as number> 2 octets
    //  <community value> 2 octets
    type union {
      type uint32 {
      // per RFC 1997, 0x00000000 - 0x0000FFFF and 0xFFFF0000 -
      // 0xFFFFFFFF are reserved
        range "65536..4294901759"; // 0x00010000..0xFFFEFFFF
      }
      type string {
        pattern '([0-9]+:[0-9]+)';
      }
    }
    description
      "Type definition for standard commmunity attributes";
    reference "RFC 1997 - BGP Communities Attribute";
  }

  typedef bgp-ext-community-type {
    // TODO: needs more work to make this more precise given the
    // variability of extended community attribute specifications
    // 8-octet value:
    //  <type> 2 octects
    //  <value> 6 octets

    type union {
      type string {
        // Type 1: 2-octet global and 4-octet local
        //         (AS number)        (Integer)
        pattern '(6[0-5][0-5][0-3][0-5]|[1-5][0-9]{4}|'            +
                '[1-9][0-9]{1,4}|[0-9]):'                          +
                '(4[0-2][0-9][0-4][0-9][0-6][0-7][0-2][0-9][0-6]|' +
                '[1-3][0-9]{9}|[1-9]([0-9]{1,7})?[0-9]|[1-9])';
      }
      type string {
        // Type 2: 4-octet global and 2-octet local
        //         (ipv4-address)     (integer)
        pattern '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'      +
                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'     +
                '2[0-4][0-9]|25[0-5]):'                            +
                '(6[0-5][0-5][0-3][0-5]|[1-5][0-9]{4}|'            +
                '[1-9][0-9]{1,4}|[0-9])';
      }
      type string {
        // route-target with Type 1
        // route-target:(ASN):(local-part)
        pattern 'route\-target:(6[0-5][0-5][0-3][0-5]|'            +
                '[1-5][0-9]{4}|[1-9][0-9]{1,4}|[0-9]):'            +
                '(4[0-2][0-9][0-4][0-9][0-6][0-7][0-2][0-9][0-6]|' +
                '[1-3][0-9]{9}|[1-9]([0-9]{1,7})?[0-9]|[1-9])';
      }
      type string {
        // route-target with Type 2
        // route-target:(IPv4):(local-part)
        pattern 'route\-target:' +
                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'      +
                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'     +
                '2[0-4][0-9]|25[0-5]):'                            +
                '(6[0-5][0-5][0-3][0-5]|[1-5][0-9]{4}|'            +
                '[1-9][0-9]{1,4}|[0-9])';
      }
      type string {
        // route-origin with Type 1
        pattern 'route\-origin:(6[0-5][0-5][0-3][0-5]|'            +
                '[1-5][0-9]{4}|[1-9][0-9]{1,4}|[0-9]):'            +
                '(4[0-2][0-9][0-4][0-9][0-6][0-7][0-2][0-9][0-6]|' +
                '[1-3][0-9]{9}|[1-9]([0-9]{1,7})?[0-9]|[1-9])';
      }
      type string {
        // route-origin with Type 2
        pattern 'route\-origin:' +
                '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|'      +
                '25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|'     +
                '2[0-4][0-9]|25[0-5]):'                            +
                '(6[0-5][0-5][0-3][0-5]|[1-5][0-9]{4}|'            +
                '[1-9][0-9]{1,4}|[0-9])';
      }
    }
    description
      "Type definition for extended community attributes";
    reference "RFC 4360 - BGP Extended Communities Attribute";
  }

  typedef bgp-community-regexp-type {
    // TODO: needs more work to decide what format these regexps can
    // take.
    type oc-types:std-regexp;
    description
      "Type definition for communities specified as regular
      expression patterns";
  }

  typedef bgp-origin-attr-type {
    type enumeration {
      enum IGP {
        description "Origin of the NLRI is internal";
      }
      enum EGP {
        description "Origin of the NLRI is EGP";
      }
      enum INCOMPLETE {
        description "Origin of the NLRI is neither IGP or EGP";
      }
    }
    description
      "Type definition for standard BGP origin attribute";
    reference "RFC 4271 - A Border Gateway Protocol 4 (BGP-4),
      Sec 4.3";
  }

  typedef peer-type {
    type enumeration {
      enum INTERNAL {
        description "internal (iBGP) peer";
      }
      enum EXTERNAL {
        description "external (eBGP) peer";
      }
    }
    description
      "labels a peer or peer group as explicitly internal or
      external";
  }


  typedef remove-private-as-option {
    type enumeration {
      enum ALL {
        description "remove all private ASes in the path";
      }
      enum REPLACE {
        description "replace private ASes with local AS";
      }
    }
    description
      "set of options for configuring how private AS path numbers
      are removed from advertisements";
  }

  typedef percentage {
    type uint8 {
      range "0..100";
    }
    description
      "Integer indicating a percentage value";
  }

  typedef rr-cluster-id-type {
    type union {
      type uint32;
      type inet:ipv4-address;
    }
    description
      "union type for route reflector cluster ids:
      option 1: 4-byte number
      option 2: IP address";
  }

  typedef community-type {
    type enumeration {
      enum STANDARD {
        description "send only standard communities";
      }
      enum EXTENDED {
        description "send only extended communities";
      }
      enum BOTH {
        description "send both standard and extended communities";
      }
      enum NONE {
        description "do not send any community attribute";
      }
    }
    description
      "type describing variations of community attributes:
      STANDARD: standard BGP community [rfc1997]
      EXTENDED: extended BGP community [rfc4360]
      BOTH: both standard and extended community";
  }


}