module frr-bgp-filter {
  yang-version 1.1;
  namespace "http://frrouting.org/yang/bgp-filter";
  prefix frr-bgp-filter;

  import frr-filter {
    prefix frr-filter;
  }

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

  organization
    "Free Range Routing";
  contact
    "FRR Users List:       <mailto:frog@lists.frrouting.org>
     FRR Development List: <mailto:dev@lists.frrouting.org>";
  description
    "This module defines filter settings";

  revision 2020-01-15 {
    description
      "Initial revision";
  }

  typedef list-sequence {
    type uint32 {
      range "1..4294967295";
    }
    description
      "List instance priority (low number means higher priority)";
  }

  typedef list-action {
    type enumeration {
      enum "deny" {
        value 0;
        description
          "Deny an entry";
      }
      enum "permit" {
        value 1;
        description
          "Accept an entry";
      }
    }
    description
      "Return action on match";
  }

  typedef bgp-list-name {
    type string;
    description
      "List name";
  }

  typedef community-string {
    type string {
      pattern "(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0)|((6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0):(6553[0-5]|655[0-2][0-9]|65[0-4][0-9]{2}|6[0-4][0-9]{3}|[1-5][0-9]{4}|[1-9][0-9]{0,3}|0))|(local-AS)|(no-advertise)|(no-export)|(internet)";
    }
    description
      "The BGP community string";
  }

  typedef large-community-string {
    type string {
      pattern "(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0)|(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0)|(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0):(429496729[0-5]|42949672[0-8][0-9]|4294967[01][0-9]{2}|429496[0-6][0-9]{3}|42949[0-5][0-9]{4}|4294[0-8][0-9]{5}|429[0-3][0-9]{6}|42[0-8][0-9]{7}|4[01][0-9]{8}|[1-3][0-9]{9}|[1-9][0-9]{0,8}|0)";
    }
    description
      "The BGP large-community string";
  }

  augment "/frr-filter:lib" {
    list community-list {
      key "name";
      description
        "Community-list instance";
      leaf name {
        type string;
      }

      list entry {
        key "sequence";
        description
          "Community-list entry";
        leaf sequence {
          type list-sequence;
        }

        leaf action {
          type list-action;
        }

        leaf type {
          type enumeration {
            enum "community-list-standard" {
              value 0;
              description
                "Standard community-list name/identifier";
            }
            enum "community-list-extended" {
              value 1;
              description
                "Expanded community-list name/identifier";
            }
          }
          mandatory true;
          description
            "Community-list instance name/identifier";
        }

        choice community-string {
          description
            "Community string";
          case standard {
            when "./type = 'community-list-standard'";
            leaf-list standard-community-string {
              type community-string;
              description
                "Community string";
            }
          }

          case expanded {
            when "./type = 'community-list-extended'";
            leaf expanded-community-string {
              type string;
              description
                "Community string reg-ex";
            }
          }
        }
      }
    }

    list large-community-list {
      key "name";
      description
        "Large community-list instance";
      leaf name {
        type string;
      }

      list entry {
        key "sequence";
        description
          "Large community-list entry";
        leaf sequence {
          type list-sequence;
        }

        leaf action {
          type list-action;
        }

        leaf type {
          type enumeration {
            enum "large-community-list-standard-id" {
              value 0;
              description
                "Standard large-community-list identifier";
            }
            enum "large-community-list-extended-id" {
              value 1;
              description
                "Expanded large-community-list identifier";
            }
            enum "large-community-list-standard-name" {
              value 2;
              description
                "Standard large-community-list name";
            }
            enum "large-community-list-extended-name" {
              value 3;
              description
                "Expanded large-community-list name";
            }
          }
          mandatory true;
          description
            "Large community-list instance name/identifier";
        }

        choice large-community-string {
          description
            "Large community string";
          case standard {
            when "./type = 'large-community-list-standard-id' or "
               + "./type = 'large-community-list-standard-name'";
            leaf-list standard-large-community-string {
              type large-community-string;
              description
                "Large community string";
            }
          }

          case expanded {
            when "./type = 'large-community-list-extended-id' or "
               + "./type = 'large-community-list-extended-name'";
            leaf expanded-large-community-string {
              type string;
              description
                "Large community string reg-ex";
            }
          }
        }
      }
    }

    list extcommunity-list {
      key "name";
      description
        "Extcommunity-list instance";
      leaf name {
        type string;
      }

      list entry {
        key "sequence";
        description
          "Extcommunity-list entry";
        leaf sequence {
          type list-sequence;
        }

        leaf action {
          type list-action;
        }

        leaf type {
          type enumeration {
            enum "extcommunity-list-standard-id" {
              value 0;
              description
                "Standard extcommunity-list identifier";
            }
            enum "extcommunity-list-extended-id" {
              value 1;
              description
                "Expanded extcommunity-list identifier";
            }
            enum "extcommunity-list-standard-name" {
              value 2;
              description
                "Standard extcommunity-list name";
            }
            enum "extcommunity-list-extended-name" {
              value 3;
              description
                "Expanded extcommunity-list name";
            }
          }
          mandatory true;
          description
            "Extcommunity-list instance name/identifier";
        }

        choice extcommunity-string {
          description
            "Extcommunity string";
          case standard {
            when "./type = 'extcommunity-list-standard-id' or "
               + "./type = 'extcommunity-list-standard-name'";
            choice standard-extcommunity-string {
              description
                "Value of the ext-community";
              case extcommunity-rt {
                description
                  "Set BGP ext-community route-target attribute";
                leaf-list extcommunity-rt {
                  type rt-types:route-target;
                }
              }

              case extcommunity-soo {
                description
                  "Set BGP ext-community site-of-origin attribute";
                leaf-list extcommunity-soo {
                  type rt-types:route-target;
                }
              }
            }
          }

          case expanded {
            when "./type = 'extcommunity-list-extended-id' or "
               + "./type = 'extcommunity-list-extended-name'";
            leaf expanded-extcommunity-string {
              type string;
              description
                "Extcommunity string reg-ex";
            }
          }
        }
      }
    }

    list as-path-list {
      key "name";
      description
        "AS-path access-list instance";
      leaf name {
        type string;
        description
          "AS-path access-list instance name/identifier";
      }

      list entry {
        key "sequence";
        description
          "AS-path access-list entry";
        leaf sequence {
          type list-sequence;
        }

        leaf action {
          type list-action;
        }

        leaf as-path {
          type string;
          description
            "AS-path access-list string reg-ex";
        }
      }
    }
  }
}
