From 0f28135623912d218ab1e001b0115d3588acea32 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Tue, 2 Jul 2019 12:13:44 -0300 Subject: [PATCH 1/4] yang: initial route-map YANG model import New model based on FRR's CLI and data structures. Signed-off-by: Rafael Zalamena --- yang/frr-route-map.yang | 405 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 yang/frr-route-map.yang diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang new file mode 100644 index 0000000000..349f427f5b --- /dev/null +++ b/yang/frr-route-map.yang @@ -0,0 +1,405 @@ +module frr-route-map { + yang-version 1.1; + namespace "http://frrouting.org/yang/route-map"; + prefix frr-route-map; + + import ietf-inet-types { + prefix inet; + } + + organization "Free Range Routing"; + contact + "FRR Users List: + FRR Development List: "; + description "This module defines route map settings"; + + revision 2019-07-01 { + description "Initial revision"; + } + + /* + * Types. + */ + typedef route-map-sequence { + description "Route map valid sequence numbers"; + type uint16 { + range "1..65535"; + } + } + + typedef route-map-name { + description "Route map name format"; + type string; + } + + /* + * Operational data. + */ + container route-map { + list instance { + description "Route map instance"; + + key "name sequence"; + + leaf name { + description "Route map instance name"; + type route-map-name; + } + + leaf sequence { + description + "Route map instance priority (low number means higher priority)"; + type route-map-sequence; + } + + leaf description { + description "Route map description"; + type string; + } + + leaf action { + description + "Route map actions: permit (executes action), deny (quits evaluation)"; + mandatory true; + type enumeration { + enum permit { + description + "Executes configured action and permits the prefix/route + if the conditions matched. An alternative exit action can + be configured to continue processing the route map list + or jump to process another route map."; + value 0; + } + enum deny { + description + "If all conditions are met the prefix/route is denied and + route map processing stops."; + value 1; + } + } + } + + list match-condition { + description "Route map match conditions"; + + key "condition"; + + leaf condition { + description "Match condition"; + type enumeration { + enum interface { + description "Match interface"; + value 0; + } + enum ipv4-address-list { + description "Match an IPv4 access-list"; + value 1; + } + enum ipv4-prefix-list { + description "Match an IPv4 prefix-list"; + value 2; + } + enum ipv4-prefix-length { + description "Match an IPv4 prefix length"; + value 3; + } + enum ipv4-next-hop-list { + description "Match an IPv4 next-hop"; + value 4; + } + enum ipv4-next-hop-prefix-list { + description "Match an IPv4 next-hop prefix list"; + value 5; + } + enum ipv4-next-hop-prefix-length { + description "Match an IPv4 next-hop prefix length"; + value 6; + } + enum ipv4-next-hop-type { + description "Match an IPv4 next-hop type"; + value 7; + } + enum ipv6-address-list { + description "Match an IPv6 access-list"; + value 8; + } + enum ipv6-prefix-list { + description "Match an IPv6 prefix-list"; + value 9; + } + enum ipv6-prefix-length { + description "Match an IPv6 prefix length"; + value 10; + } + enum ipv6-next-hop { + description "Match an IPv6 next-hop"; + value 11; + } + enum ipv6-next-hop-type { + description "Match an IPv6 next-hop type"; + value 12; + } + enum metric { + description "Match a route metric"; + value 13; + } + enum tag { + description "Match a route tag"; + value 14; + } + + /* + * Protocol YANG models should augment the parent node to + * contain the routing protocol specific value. The protocol + * must also augment `condition-value` to include its specific + * values or expand the `when` statement on the existing cases. + */ + enum routing-protocol-specific { + description "Match a routing protocol specific type"; + value 100; + } + } + } + + choice condition-value { + description + "Value to match (interpretation depends on condition type)"; + case access-list-num { + when "./condition = 'ipv4-address-list' or + ./condition = 'ipv4-next-hop-list'"; + leaf access-list-num { + type uint8 { + range "1..199"; + } + } + } + case access-list-num-extended { + when "./condition = 'ipv4-address-list' or + ./condition = 'ipv4-next-hop-list'"; + leaf access-list-num-extended { + type uint16 { + range "1300..2699"; + } + } + } + case list-name { + when "./condition = 'ipv4-address-list' or + ./condition = 'ipv4-prefix-list' or + ./condition = 'ipv4-next-hop-list' or + ./condition = 'ipv4-next-hop-prefix-list' or + ./condition = 'ipv6-address-list' or + ./condition = 'ipv6-prefix-list'"; + leaf list-name { + type string; + } + } + case ipv6-address { + when "./condition = 'ipv6-next-hop'"; + leaf ipv6-address { + type inet:ipv6-address; + } + } + case ipv4-prefix-length { + when "./condition = 'ipv4-prefix-length' or + ./condition = 'ipv4-next-hop-prefix-length'"; + leaf ipv4-prefix-length { + type uint8 { + range "0..32"; + } + } + } + case ipv6-prefix-length { + when "./condition = 'ipv6-prefix-length'"; + leaf ipv6-prefix-length { + type uint8 { + range "0..128"; + } + } + } + case ipv4-next-hop-type { + when "./condition = 'ipv4-next-hop-type'"; + leaf ipv4-next-hop-type { + type enumeration { + enum blackhole { + value 0; + } + } + } + } + case ipv6-next-hop-type { + when "./condition = 'ipv6-next-hop-type'"; + leaf ipv6-next-hop-type { + type enumeration { + enum blackhole { + value 0; + } + } + } + } + case metric { + when "./condition = 'metric'"; + leaf metric { + type uint32 { + range "1..4294967295"; + } + } + } + case tag { + when "./condition = 'tag'"; + leaf tag { + type uint32 { + range "1..4294967295"; + } + } + } + } + } + + list set-action { + description "Route map set actions"; + + key "action"; + + leaf action { + description "Action to do when the route map matches"; + type enumeration { + enum ipv4-next-hop { + description "Set IPv4 address of the next hop"; + value 0; + } + enum ipv6-next-hop { + description "Set IPv6 address of the next hop"; + value 1; + } + enum metric { + description "Set prefix/route metric"; + value 2; + } + enum tag { + description "Set tag"; + value 3; + } + + /* + * Protocol YANG models should augment the parent node to + * contain the routing protocol specific value. The protocol + * must also augment `action-value` to include its specific + * values or expand the `when` statement on the existing cases. + */ + enum routing-protocol-specific { + description "Set a routing protocol specific action"; + value 100; + } + } + } + + choice action-value { + description + "Value to set (interpretation depends on action-type)"; + case ipv4-address { + when "./action = 'ipv4-next-hop'"; + leaf ipv4-address { + description "IPv4 address"; + type inet:ipv4-address; + } + } + case ipv6-address { + when "./action = 'ipv6-next-hop'"; + leaf ipv6-address { + description "IPv6 address"; + type inet:ipv6-address; + } + } + case metric { + when "./action = 'metric'"; + choice metric-value { + description "Metric to set or use"; + case value { + leaf value { + description "Use the following metric value"; + type uint32 { + range "0..4294967295"; + } + } + } + case add-metric { + leaf add-metric { + description "Add unit to metric"; + type boolean; + } + } + case subtract-metric { + leaf subtract-metric { + description "Subtract unit from metric"; + type boolean; + } + } + case use-round-trip-time { + leaf use-round-trip-time { + description "Use the round trip time as metric"; + type boolean; + } + } + case add-round-trip-time { + leaf add-round-trip-time { + description "Add round trip time to metric"; + type boolean; + } + } + case subtract-round-trip-time { + leaf subtract-round-trip-time { + description "Subtract round trip time to metric"; + type boolean; + } + } + } + } + case tag { + leaf tag { + description "Tag value"; + type uint32 { + range "0..4294967295"; + } + } + } + } + } + + leaf call { + description + "Call another route map before calling `exit-policy`. If the + called route map returns deny then this route map will also + return deny"; + type string; + } + + leaf exit-policy { + description "What do to after route map successful match, set and call"; + type enumeration { + enum permit-or-deny { + description "End route map evaluation and return"; + value 0; + } + enum next { + description + "Proceed evaluating next route map entry per sequence"; + value 1; + } + enum goto { + description + "Go to route map entry with the provided sequence number"; + value 2; + } + } + default "permit-or-deny"; + } + + leaf goto-value { + when "../exit-policy = 'goto'"; + description + "Sequence number to jump (when using `goto` exit policy)"; + type route-map-sequence; + } + } + } +} From 2332428d3c80ac3d3b4e1c0bdba830b098ef440f Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 5 Jul 2019 11:07:30 -0300 Subject: [PATCH 2/4] yang: initial filter YANG model import This model contains the description of access-list, prefix-list and other lists used by route map and other filtering interfaces. Signed-off-by: Rafael Zalamena --- yang/frr-filter.yang | 365 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 365 insertions(+) create mode 100644 yang/frr-filter.yang diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang new file mode 100644 index 0000000000..92af6aebfd --- /dev/null +++ b/yang/frr-filter.yang @@ -0,0 +1,365 @@ +module frr-filter { + yang-version 1.1; + namespace "http://frrouting.org/yang/filter"; + prefix frr-filter; + + import ietf-inet-types { + prefix inet; + } + import ietf-yang-types { + prefix yang; + } + + organization "Free Range Routing"; + contact + "FRR Users List: + FRR Development List: "; + description "This module defines filter settings"; + + revision 2019-07-04 { + description "Initial revision"; + } + + /* + * Types. + */ + typedef access-list-standard { + description "Standard IPv4 access list (any, host or a prefix)"; + type uint16 { + range "1..99 | 1300..1999"; + } + } + + typedef access-list-extended { + description + "Extended IPv4 access list (source / destination any, hosts or prefixes)"; + type uint16 { + range "100..199 | 2000..2699"; + } + } + + typedef access-list-legacy { + description "Standard/Extended IPv4 access list"; + type uint16 { + range "1..199 | 1300..2699"; + } + } + + typedef access-list-name { + description "Access list name formatting"; + type string; + } + + typedef access-list-sequence { + description "Access list sequence number"; + type uint32 { + range "1..4294967295"; + } + } + + typedef access-list-action { + description "Access list return action on match"; + type enumeration { + enum deny { + description "Deny an entry"; + value 0; + } + enum permit { + description "Accept an entry"; + value 1; + } + } + } + + /* + * Configuration data. + */ + container filter-list { + list access-list-legacy { + description "Access list legacy instance"; + + key "number sequence"; + + leaf number { + description "Access list sequence value"; + type access-list-legacy; + } + + leaf sequence { + description "Access list sequence value"; + type access-list-sequence; + } + + leaf action { + description "Access list action on match"; + type access-list-action; + mandatory true; + } + + leaf remark { + description "Access list remark"; + type string; + } + + choice value { + description + "Standard access list: value to match. + Extended access list: source value to match."; + mandatory true; + + case host { + leaf host { + description "Host to match"; + type inet:ipv4-address; + } + } + case network { + leaf network { + description "Network to match"; + type inet:ipv4-prefix; + } + } + case any { + leaf any { + description "Match any"; + type empty; + } + } + } + + choice extended-value { + when "./sequence >= 100 and ./sequence <= 199 or + ./sequence >= 2000 and ./sequence <= 2699"; + description "Destination value to match"; + + case destination-host { + leaf destination-host { + description "Host to match"; + type inet:ipv4-address; + } + } + case destination-network { + leaf destination-network { + description "Network to match"; + type inet:ipv4-prefix; + } + } + case destination-any { + leaf destination-any { + description "Match any"; + type empty; + } + } + } + } + + list access-list { + description "Access list instance"; + + key "type identifier sequence"; + + leaf type { + description "Access list content type"; + type enumeration { + enum ipv4 { + description "Internet Protocol address version 4"; + value 0; + } + enum ipv6 { + description "Internet Protocol address version 6"; + value 1; + } + enum mac { + description "Media Access Control address"; + value 2; + } + + /* + * Protocol YANG models should augment the parent node to + * contain the routing protocol specific value. The protocol + * must also augment `value` leaf to include its specific + * values or expand the `when` statement on the existing cases. + */ + enum custom { + description "Custom data type"; + value 100; + } + } + } + + leaf identifier { + description "Access list identifier"; + type access-list-name; + } + + leaf sequence { + description "Access list sequence value"; + type access-list-sequence; + } + + leaf action { + description "Access list action on match"; + type access-list-action; + mandatory true; + } + + leaf remark { + description "Access list remark"; + type string; + } + + choice value { + description "Access list value to match"; + mandatory true; + + case ipv4-prefix { + when "./type = 'ipv4'"; + + leaf ipv4-prefix { + description "Configure IPv4 prefix to match"; + type inet:ipv4-prefix; + } + + leaf ipv4-exact-match { + description "Exact match of prefix"; + type boolean; + default false; + } + } + case ipv6-prefix { + when "./type = 'ipv6'"; + + leaf ipv6-prefix { + description "Configure IPv6 prefix to match"; + type inet:ipv6-prefix; + } + + leaf ipv6-exact-match { + description "Exact match of prefix"; + type boolean; + default false; + } + } + case mac { + when "./type = 'mac'"; + + leaf mac { + description "Configure MAC address to match"; + type yang:mac-address; + } + } + case any { + leaf any { + description "Match anything"; + type empty; + } + } + } + } + + list prefix-list { + description "Prefix list instance"; + + key "type name sequence"; + + leaf type { + description "Prefix list type"; + type enumeration { + enum ipv4 { + description "Internet Protocol address version 4"; + value 0; + } + enum ipv6 { + description "Internet Protocol address version 6"; + value 1; + } + } + } + + leaf name { + description "Prefix list name"; + type access-list-name; + } + + leaf sequence { + description "Access list sequence value"; + type access-list-sequence; + } + + leaf action { + description "Prefix list action on match"; + type access-list-action; + mandatory true; + } + + leaf description { + description "Prefix list user description"; + type string; + } + + choice value { + description "Prefix list value to match"; + mandatory true; + + case ipv4-prefix { + when "./type = 'ipv4'"; + + leaf ipv4-prefix { + description "Configure IPv4 prefix to match"; + type inet:ipv4-prefix; + } + + leaf ipv4-prefix-length-greater-or-equal { + description + "Specifies if matching prefixes with length greater than + or equal to value"; + type uint8 { + range "0..32"; + } + } + + leaf ipv4-prefix-length-lesser-or-equal { + description + "Specifies if matching prefixes with length lesser than + or equal to value"; + type uint8 { + range "0..32"; + } + } + } + case ipv6-prefix { + when "./type = 'ipv6'"; + + leaf ipv6-prefix { + description "Configure IPv6 prefix to match"; + type inet:ipv6-prefix; + } + + leaf ipv6-prefix-length-greater-or-equal { + description + "Specifies if matching prefixes with length greater than + or equal to value"; + type uint8 { + range "0..128"; + } + } + + leaf ipv6-prefix-length-lesser-or-equal { + description + "Specifies if matching prefixes with length lesser than + or equal to value"; + type uint8 { + range "0..128"; + } + } + } + case any { + leaf any { + description "Match anything"; + type empty; + } + } + } + } + } +} From 04ef6e75550cbdb212197294937659762f934a66 Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Thu, 25 Jul 2019 17:01:07 -0300 Subject: [PATCH 3/4] yang: use filter types in route-map Import the new YANG model filter and use its types. Signed-off-by: Rafael Zalamena --- yang/frr-route-map.yang | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/yang/frr-route-map.yang b/yang/frr-route-map.yang index 349f427f5b..0ce40b474b 100644 --- a/yang/frr-route-map.yang +++ b/yang/frr-route-map.yang @@ -6,6 +6,9 @@ module frr-route-map { import ietf-inet-types { prefix inet; } + import frr-filter { + prefix filter; + } organization "Free Range Routing"; contact @@ -168,18 +171,14 @@ module frr-route-map { when "./condition = 'ipv4-address-list' or ./condition = 'ipv4-next-hop-list'"; leaf access-list-num { - type uint8 { - range "1..199"; - } + type filter:access-list-standard; } } case access-list-num-extended { when "./condition = 'ipv4-address-list' or ./condition = 'ipv4-next-hop-list'"; leaf access-list-num-extended { - type uint16 { - range "1300..2699"; - } + type filter:access-list-extended; } } case list-name { @@ -190,7 +189,7 @@ module frr-route-map { ./condition = 'ipv6-address-list' or ./condition = 'ipv6-prefix-list'"; leaf list-name { - type string; + type filter:access-list-name; } } case ipv6-address { From bec0aa85b1f404ac9800c7524070fcf8582e82bc Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Thu, 1 Aug 2019 19:56:46 -0300 Subject: [PATCH 4/4] yang: simplify filter choice by removing cases Based on @rwestphal feedback, lets remove `case`s where we don't expect to add more items or items with more than one `leaf`. Signed-off-by: Rafael Zalamena --- yang/frr-filter.yang | 48 +++++++++++++++++--------------------------- 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/yang/frr-filter.yang b/yang/frr-filter.yang index 92af6aebfd..e79ede87b7 100644 --- a/yang/frr-filter.yang +++ b/yang/frr-filter.yang @@ -107,23 +107,17 @@ module frr-filter { Extended access list: source value to match."; mandatory true; - case host { - leaf host { - description "Host to match"; - type inet:ipv4-address; - } + leaf host { + description "Host to match"; + type inet:ipv4-address; } - case network { - leaf network { - description "Network to match"; - type inet:ipv4-prefix; - } + leaf network { + description "Network to match"; + type inet:ipv4-prefix; } - case any { - leaf any { - description "Match any"; - type empty; - } + leaf any { + description "Match any"; + type empty; } } @@ -132,23 +126,17 @@ module frr-filter { ./sequence >= 2000 and ./sequence <= 2699"; description "Destination value to match"; - case destination-host { - leaf destination-host { - description "Host to match"; - type inet:ipv4-address; - } + leaf destination-host { + description "Host to match"; + type inet:ipv4-address; } - case destination-network { - leaf destination-network { - description "Network to match"; - type inet:ipv4-prefix; - } + leaf destination-network { + description "Network to match"; + type inet:ipv4-prefix; } - case destination-any { - leaf destination-any { - description "Match any"; - type empty; - } + leaf destination-any { + description "Match any"; + type empty; } } }