module bgp-policy { yang-version "1"; // namespace // TODO: change to an ietf or other generic namespace namespace "http://google.com/yang/google-bgp-policy-cfg"; prefix "bgp-policy"; // import some basic types import ietf-inet-types { prefix inet; } // meta // TODO: add collaborating organizations organization "Google, AT&T, BT, Microsoft"; contact "Google, Inc. 1600 Amphitheatre Way Mountain View, CA 94043 AT&T Labs 200 S. Laurel Avenue Middletown, NJ 07748 BT pp. C3L, BT Centre 81, Newgate Street London EC1A 7AJ UK Microsoft 205 108th Ave. NE, Suite 400 Bellevue, WA 98004"; description "This module describes a YANG model for BGP policy configuration. It is a limited subset of all of the policy configuration parameters available in the variety of vendor implementations, but supports widely used constructs for managing how BGP routes are imported, exported, and modified. This module works with the base BGP protocol configuration model defined in google-bgp. Route policy expression: Policies are expressed as a set of top-level policy definitions, each of which consists of a sequence of policy statements. Policy statements are simple condition-action tuples. Conditions may include mutiple match or comparison operations, and similarly actions may be multitude of changes to route attributes and a final disposition of accepting or> rejecting the route. BGP | +->policy +-> policy definitions +-> policy statements +-> conditions +-> [ match conditions / comparison conditions ] +-> actions +-> [ set attribute actions / control-flow actions ] Route policy evaluation: Evaluation of a policy definition is expected to proceed by evaluating the individual policy statements in the specified order. When a condition statement in a policy statement is satisfied, the corresponding action statement is executed. If the action statement has either accept-route or reject-route actions, policy evaluation stops. If the condition is not satisfied, or if the action statement contains goto-next, then evaluation proceeds to the next policy statement. If none of the policy statement conditions are satisfied, then the default action is applied. Policy 'subroutines' are supported by allowing condition statements to reference another policy definition which first applies conditions from the referenced policy before proceeding."; revision "2014-09-30" { description "Initial revision"; reference "TBD"; } // extension statements // feature statements // identity statements identity bgp-attribute-comparison { description "base type for supported comparison operators on route attributes"; } identity attribute-eq { base bgp-attribute-comparison; description "== comparison"; } identity attribute-ge { base bgp-attribute-comparison; description ">= comparison"; } identity attribute-le { base bgp-attribute-comparison; description "<= comparison"; } // typedef statements typedef match-set-options-type { type enumeration { enum ANY { description "match is true if given value matches any member of the defined set"; } enum ALL { description "match is true if each given value matches a member of the defined set"; } enum INVERT { description "match is true if given value does not match any member of the defined set"; } } default ANY; description "Options that govern the behavior of a match statement. The default behavior is ANY, i.e., the given value matches any of the members of the defined set"; } typedef as-path-prepend-option-repeat { type uint32; description "Option for the as-prepend policy action. Prepends the local AS number repeated n times"; } typedef well-known-community-attr { type enumeration { enum INTERNET { description "entire Internet community (0x00000000)"; } enum NO_EXPORT { // value 0xFFFFFF01; description "no export"; } enum NO_ADVERTISE { description "no advertise (0xFFFFFF02)"; } enum NO_EXPORT_SUBCONFED { description "no export subconfed, equivalent to local AS (0xFFFFFF03)"; } } description "Type definition for well-known IETF community attribute values"; reference "RFC 1997 - BGP Communities Attribute"; } typedef std-community-attr-type { // TODO: further refine restrictions and allowed patterns // 4-octet value: // 2 octets // 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 ext-community-attr-type { // TODO: needs more work to make this more precise given the // variability of extended community attribute specifications // 8-octet value: // 2 octects // 6 octets type string { pattern '([0-9\.]+(:[0-9]+)?:[0-9]+)'; } description "Type definition for extended community attributes"; reference "RFC 4360 - BGP Extended Communities Attribute"; } typedef community-regexp-type { // TODO: needs more work to decide what format these regexps can // take. type string; description "Type definition for communities specified as regular expression patterns"; } typedef bgp-origin-attr-type { type enumeration { enum IGP { value 0; description "Origin of the NLRI is internal"; } enum EGP { value 1; description "Origin of the NLRI is EGP"; } enum INCOMPLETE { value 2; 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 set-community-option-type { type enumeration { enum ADD { description "add the specified communities to the existing community attribute"; } enum REMOVE { description "remove the specified communities from the existing community attribute"; } enum REPLACE { description "replace the existing community attribute with the specified communities"; } enum NULL { description "set the community attribute to empty / NULL"; } } description "Type definition for options when setting the community attribute in a policy action"; } typedef bgp-next-hop-type { type union { type inet:ip-address; type enumeration { enum SELF { description "special designation for local router's own address"; } } } description "type definition for specifying next-hop in policy actions"; } // grouping statements grouping defined-sets-definitions { description "Data definitions for pre-defined sets of attributes used in policy match conditions"; list prefix-set { key prefix-set-name; description "Definitions for prefix sets"; leaf prefix-set-name { type string; description "name / label of the prefix set -- this is used to reference the set in match conditions"; } list prefix { key "address masklength masklength-range"; description "list of prefix expressions that are part of the set"; leaf address { type inet:ip-address; mandatory true; description "address portion of the prefix"; } leaf masklength { type uint8 { // simple range covers both ipv4 and ipv6 -- // could separate this into different types // for IPv4 and IPv6 prefixes range 1..128; } mandatory true; description "masklength for the prefix specification"; } leaf masklength-range { type string { // pattern modeled after ietf-inet-types pattern '(([0-9])|([1-9][0-9])|(1[0-1][0-9])|' + '(12[0-8]))\.\.' + '(([0-9])|([1-9][0-9])|(1[0-1][0-9])|' + '(12[0-8]))'; } description "Defines an optional range for the masklength. Absence of the masklength-length implies that the prefix has an exact masklength given by the masklength parameter. Example: 10.3.192.0/21 through 10.3.192.0/24 would be expressed as address: 10.3.192.0, masklength: 21, masklength-range: 21..24"; } } } list community-set { key community-set-name; description "Definitions for community sets"; leaf community-set-name { type string; mandatory true; description "name / label of the community set -- this is used to reference the set in match conditions"; } leaf-list community-members { type union { type std-community-attr-type; type community-regexp-type; type well-known-community-attr; } description "members of the community set"; } } list ext-community-set { key ext-community-set-name; description "Definitions for extended community sets"; leaf ext-community-set-name { type string; description "name / label of the extended community set -- this is used to reference the set in match conditions"; } leaf-list ext-community-members { type union { type ext-community-attr-type; // TODO: is regexp support needed for extended communities? // TODO: is well-known needed for extended communities? type community-regexp-type; } description "members of the extended community set"; } } list as-path-set { key as-path-set-name; description "Definitions for AS path sets"; leaf as-path-set-name { type string; description "name of the AS path set -- this is used to reference the the set in match conditions"; } leaf-list as-path-set-members { // TODO: need to refine typedef for AS path expressions type string; description "AS path expression -- list of ASes in the set"; } } } grouping condition-set-matches { description "Condition statement definitions for checking membership in a defined set"; leaf match-community-set { type leafref { path "/bgp/policy/defined-sets/community-set/community-set-name"; require-instance true; } description "References a defined community set"; } leaf match-ext-community-set { type leafref { path "/bgp/policy/defined-sets/ext-community-set" + "/ext-community-set-name"; } description "References a defined extended community set"; } leaf match-as-path-set { type leafref { path "/bgp/policy/defined-sets/as-path-set/as-path-set-name"; } description "References a defined AS path set"; } leaf match-prefix-set { type leafref { path "/bgp/policy/defined-sets/prefix-set/prefix-set-name"; } description "References a defined prefix set"; } leaf match-set-options { type match-set-options-type; description "Optional parameter that governs the behavior of the match operation"; } } grouping condition-attribute-compare-operators { description "common definitions for comparison operations in condition statements"; leaf operator { type identityref { base bgp-attribute-comparison; } description "type of comparison to be performed"; } leaf value { type uint32; description "value to compare with the community count"; } } grouping condition-attribute-comparisons { description "Condition statement definitions for comparing a route attribute to a specified value"; leaf med-eq { type uint32; description "Condition to check if the received MED value is equal to the specified value"; } leaf origin-eq { type bgp-origin-attr-type; description "Condition to check if the route origin is equal to the specified value"; } leaf-list next-hop-in { type inet:ip-address; description "List of next hop addresses to check for in the route update"; } leaf local-pref-eq { type uint32; // TODO: add support for other comparisons description "Condition to check if the local pref attribute is equal to the specified value"; } container community-count { presence "node is present in the config data to indicate a community-count condition"; description "Value and comparison operations for conditions based on the number of communities in the route update"; uses condition-attribute-compare-operators; } container as-path-length { presence "node is present in the config data to indicate a as-path-length condition"; description "Value and comparison operations for conditions based on the length of the AS path in the route update"; uses condition-attribute-compare-operators; } leaf route-type { // TODO: verify extent of vendor support for this comparison type enumeration { enum INTERNAL { description "route type is internal"; } enum EXTERNAL { description "route type is external"; } } description "Condition to check the route type in the route update"; } } grouping set-attribute-actions { description "Definitions for base set of policy action statements that change various attributes of the route"; container set-as-path-prepend { presence "node is present in the config data to use the AS prepend action"; description "action to prepend local AS number to the AS-path a specified number of times"; leaf repeat-n { type uint8; description "number of times to prepend the local AS number"; } } container set-community { presence "node is present in the config data when set-community action is used"; description "action to set the community attributes of the route, along with options to modify how the community is modified"; leaf-list communities { type union { type std-community-attr-type; type well-known-community-attr; } description "community values for the update"; } leaf options { type set-community-option-type; description "options for modifying the community attribute with the specified values"; } } container set-ext-community { presence "node is present in the config data when set-community action is used"; description "action to set the extended community attributes of the route, along with options to modify how the community is modified"; leaf-list communities { type union { type ext-community-attr-type; type well-known-community-attr; } description "community values for the update"; } leaf options { type set-community-option-type; description "options for modifying the community attribute with the specified values"; } } leaf set-route-origin { type bgp-origin-attr-type; description "set the origin attribute to the specified value"; } leaf set-local-pref { type uint32; description "set the local pref attribute on the route update"; } leaf set-next-hop { type bgp-next-hop-type; description "set the next-hop attribute in the route update"; } leaf set-med { type uint32; description "set the med metric attribute in the route update"; } } grouping control-flow-actions { description "Definitions for base set of policy action statements that manage the disposition or control flow of the policy"; leaf accept-route { type empty; description "accepts the route into the routing table"; } leaf reject-route { type empty; description "rejects the route"; } leaf goto-next { type empty; description "proceed to evaluate the next policy statement in the policy definition"; } leaf goto-policy { type string; description "proceed to the named policy definition and continue evaluating the policy"; } } grouping conditions { description "Condition statement definitions for policy statements"; leaf call-policy { type string; description "Applies the conditions from the specified policy definition in the current policy statement."; } uses condition-set-matches; uses condition-attribute-comparisons; } grouping actions { description "Action statement definitions for policy statements"; uses set-attribute-actions; uses control-flow-actions; } grouping apply-policy-group { description "top level configuration for applying policies at various points in the configuration hierarchy"; container apply-policy { description "Anchor point for policies in the BGP configuration. Import and export policies are with respect to the local routing table, i.e., export (send) and import (receive)."; leaf-list import-policies { type leafref { path "/bgp/policy/policy-definitions/policy-definition" + "/name"; require-instance true; } description "list of policy names in sequence to be applied on receiving a routing update in the current context, e.g., for the current peer group, neighbor, address family, etc."; } leaf-list export-policies { type leafref { path "/bgp/policy/policy-definitions/policy-definition" + "/name"; require-instance true; } description "list of policy names in sequence to be applied on sending a routing update in the current context, e.g., for the current peer group, neighbor, address family, etc."; } } } grouping policy-definition-group { description "top level set of policy defined sets and policy definitions"; container policy { description "Top level container for BGP policy-related configuration items"; container defined-sets { presence "Container for sets defined for matching in policy statements"; description "Predefined sets of attributes used in policy match statements"; uses defined-sets-definitions; } container policy-definitions { presence "Container for the set of policy definitions"; description "Top level container for policy definitions"; list policy-definition { key name; ordered-by user; description "List of top-level policy definitions, keyed by a unique name"; leaf name { type string; description "Name of the top-level policy definition -- this name is used in references to the current policy"; } list statements { key name; // TODO: names of policy statements withing a policy defn // should be optional, however, YANG requires a unique id // for lists; not sure that a compound key works either; // need to investigate further. ordered-by user; description "Name of this policy statement"; leaf name { type string; description "name of the policy statement"; } container conditions { description "Condition statements for this policy statement"; uses conditions; } container actions { description "Action statements for this policy statement"; uses actions; } } } } } } // augment statements // rpc statements // notification statements }