frr: makefile cleanup and misc fixeslilik-openwrt-22.03
@ -0,0 +1,7 @@ | |||
! | |||
! Sample configuration file for vtysh. | |||
! | |||
!service integrated-vtysh-config | |||
!hostname quagga-router | |||
!username root nopassword | |||
! |
@ -0,0 +1,385 @@ | |||
From 2332428d3c80ac3d3b4e1c0bdba830b098ef440f Mon Sep 17 00:00:00 2001 | |||
From: Rafael Zalamena <rzalamena@opensourcerouting.org> | |||
Date: Fri, 5 Jul 2019 11:07:30 -0300 | |||
Subject: [PATCH] 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 <rzalamena@opensourcerouting.org> | |||
--- | |||
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: <mailto:frog@lists.frrouting.org> | |||
+ FRR Development List: <mailto:dev@lists.frrouting.org>"; | |||
+ 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; | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+} |
@ -0,0 +1,390 @@ | |||
--- a/dev/null 2020-04-10 18:48:03.582667900 +0300 | |||
+++ b/yang/frr-route-map.yang 2020-05-02 11:43:04.182956847 +0300 | |||
@@ -0,0 +1,387 @@ | |||
+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; | |||
+ } | |||
+ import frr-filter { | |||
+ prefix filter; | |||
+ } | |||
+ import frr-interface { | |||
+ prefix frr-interface; | |||
+ } | |||
+ | |||
+ organization "FRRouting"; | |||
+ contact | |||
+ "FRR Users List: <mailto:frog@lists.frrouting.org> | |||
+ FRR Development List: <mailto:dev@lists.frrouting.org>"; | |||
+ 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 lib { | |||
+ list route-map { | |||
+ description "Route map instance"; | |||
+ | |||
+ key "name"; | |||
+ | |||
+ leaf name { | |||
+ description "Route map instance name"; | |||
+ type route-map-name; | |||
+ } | |||
+ | |||
+ list entry { | |||
+ description "Route map entry"; | |||
+ | |||
+ key "sequence"; | |||
+ | |||
+ 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; | |||
+ } | |||
+ } | |||
+ } | |||
+ | |||
+ 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 route-map-name; | |||
+ } | |||
+ | |||
+ 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)"; | |||
+ mandatory true; | |||
+ type route-map-sequence; | |||
+ } | |||
+ | |||
+ 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-next-hop-list { | |||
+ description "Match an IPv4 next-hop"; | |||
+ value 3; | |||
+ } | |||
+ enum ipv4-next-hop-prefix-list { | |||
+ description "Match an IPv4 next-hop prefix list"; | |||
+ value 4; | |||
+ } | |||
+ enum ipv4-next-hop-type { | |||
+ description "Match an IPv4 next-hop type"; | |||
+ value 5; | |||
+ } | |||
+ enum ipv6-address-list { | |||
+ description "Match an IPv6 access-list"; | |||
+ value 6; | |||
+ } | |||
+ enum ipv6-prefix-list { | |||
+ description "Match an IPv6 prefix-list"; | |||
+ value 7; | |||
+ } | |||
+ enum ipv6-next-hop-type { | |||
+ description "Match an IPv6 next-hop type"; | |||
+ value 8; | |||
+ } | |||
+ enum metric { | |||
+ description "Match a route metric"; | |||
+ value 9; | |||
+ } | |||
+ enum tag { | |||
+ description "Match a route tag"; | |||
+ value 10; | |||
+ } | |||
+ /* zebra specific conditions. */ | |||
+ enum ipv4-prefix-length { | |||
+ description "Match IPv4 prefix length"; | |||
+ value 100; | |||
+ } | |||
+ enum ipv6-prefix-length { | |||
+ description "Match IPv6 prefix length"; | |||
+ value 101; | |||
+ } | |||
+ enum ipv4-next-hop-prefix-length { | |||
+ description "Match next-hop prefix length"; | |||
+ value 102; | |||
+ } | |||
+ enum source-protocol { | |||
+ description "Match source protocol"; | |||
+ value 103; | |||
+ } | |||
+ enum source-instance { | |||
+ description "Match source protocol instance"; | |||
+ value 104; | |||
+ } | |||
+ } | |||
+ } | |||
+ | |||
+ choice condition-value { | |||
+ description | |||
+ "Value to match (interpretation depends on condition type)"; | |||
+ mandatory true; | |||
+ case interface { | |||
+ when "./condition = 'interface'"; | |||
+ leaf interface { | |||
+ type string; | |||
+ } | |||
+ } | |||
+ case access-list-num { | |||
+ when "./condition = 'ipv4-address-list' or | |||
+ ./condition = 'ipv4-next-hop-list'"; | |||
+ leaf access-list-num { | |||
+ 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 filter:access-list-extended; | |||
+ } | |||
+ } | |||
+ 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 filter:access-list-name; | |||
+ } | |||
+ } | |||
+ 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; | |||
+ } | |||
+ /* zebra specific conditions. */ | |||
+ enum source { | |||
+ description "Set source address for route"; | |||
+ 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 { | |||
+ when "./action = 'tag'"; | |||
+ leaf tag { | |||
+ description "Tag value"; | |||
+ type uint32 { | |||
+ range "0..4294967295"; | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+ } | |||
+} |
@ -0,0 +1,83 @@ | |||
From bec0aa85b1f404ac9800c7524070fcf8582e82bc Mon Sep 17 00:00:00 2001 | |||
From: Rafael Zalamena <rzalamena@opensourcerouting.org> | |||
Date: Thu, 1 Aug 2019 19:56:46 -0300 | |||
Subject: [PATCH] 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 <rzalamena@opensourcerouting.org> | |||
--- | |||
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; | |||
} | |||
} | |||
} |
@ -0,0 +1,147 @@ | |||
From dc397e4c0adc13982fc5d83a1afc42178708f4a5 Mon Sep 17 00:00:00 2001 | |||
From: Renato Westphal <renato@opensourcerouting.org> | |||
Date: Fri, 3 Apr 2020 20:10:04 -0300 | |||
Subject: [PATCH] lib: consolidate flexible array hack in a single place | |||
Old gcc versions (< 5.x) have a bug that prevents C99 flexible | |||
arrays from working properly on shared libraries. | |||
We already have a hack in place to work around this problem, but it | |||
needs to be replicated in every declaration of a frr_yang_module_info | |||
variable within libfrr. This clearly isn't a good solution if we | |||
consider that many more libfrr YANG modules are about to come in | |||
the future. | |||
This commit introduces a different workaround that operates within | |||
the northbound layer itself, such that implementers of libfrr YANG | |||
modules won't need to worry about this problem anymore. | |||
Signed-off-by: Renato Westphal <renato@opensourcerouting.org> | |||
--- | |||
lib/if.c | 24 ------------------------ | |||
lib/northbound.c | 7 +++++++ | |||
lib/northbound.h | 11 +++++++++++ | |||
lib/routemap_northbound.c | 25 ------------------------- | |||
4 files changed, 18 insertions(+), 49 deletions(-) | |||
diff --git a/lib/if.c b/lib/if.c | |||
index dabf66799d..24b103b3ff 100644 | |||
--- a/lib/if.c | |||
+++ b/lib/if.c | |||
@@ -1657,31 +1657,7 @@ static int lib_interface_description_destroy(enum nb_event event, | |||
/* clang-format off */ | |||
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) | |||
-/* gcc versions before 5.x miscalculate the size for structs with variable | |||
- * length arrays (they just count it as size 0) | |||
- */ | |||
-struct frr_yang_module_info_size3 { | |||
- /* YANG module name. */ | |||
- const char *name; | |||
- | |||
- /* Northbound callbacks. */ | |||
- const struct { | |||
- /* Data path of this YANG node. */ | |||
- const char *xpath; | |||
- | |||
- /* Callbacks implemented for this node. */ | |||
- struct nb_callbacks cbs; | |||
- | |||
- /* Priority - lower priorities are processed first. */ | |||
- uint32_t priority; | |||
- } nodes[3]; | |||
-}; | |||
- | |||
-const struct frr_yang_module_info_size3 frr_interface_info_size3 asm("frr_interface_info") = { | |||
-#else | |||
const struct frr_yang_module_info frr_interface_info = { | |||
-#endif | |||
.name = "frr-interface", | |||
.nodes = { | |||
{ | |||
diff --git a/lib/northbound.c b/lib/northbound.c | |||
index cebedcff09..85e723d7cf 100644 | |||
--- a/lib/northbound.c | |||
+++ b/lib/northbound.c | |||
@@ -1866,6 +1866,13 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module) | |||
struct nb_node *nb_node; | |||
uint32_t priority; | |||
+ if (i > YANG_MODULE_MAX_NODES) { | |||
+ zlog_err( | |||
+ "%s: %s.yang has more than %u nodes. Please increase YANG_MODULE_MAX_NODES to fix this problem.", | |||
+ __func__, module->name, YANG_MODULE_MAX_NODES); | |||
+ exit(1); | |||
+ } | |||
+ | |||
nb_node = nb_node_find(module->nodes[i].xpath); | |||
if (!nb_node) { | |||
flog_warn(EC_LIB_YANG_UNKNOWN_DATA_PATH, | |||
diff --git a/lib/northbound.h b/lib/northbound.h | |||
index 76a11e518c..19a2ba0865 100644 | |||
--- a/lib/northbound.h | |||
+++ b/lib/northbound.h | |||
@@ -403,6 +403,13 @@ struct nb_node { | |||
/* The YANG list doesn't contain key leafs. */ | |||
#define F_NB_NODE_KEYLESS_LIST 0x02 | |||
+/* | |||
+ * HACK: old gcc versions (< 5.x) have a bug that prevents C99 flexible arrays | |||
+ * from working properly on shared libraries. For those compilers, use a fixed | |||
+ * size array to work around the problem. | |||
+ */ | |||
+#define YANG_MODULE_MAX_NODES 1024 | |||
+ | |||
struct frr_yang_module_info { | |||
/* YANG module name. */ | |||
const char *name; | |||
@@ -417,7 +424,11 @@ struct frr_yang_module_info { | |||
/* Priority - lower priorities are processed first. */ | |||
uint32_t priority; | |||
+#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) | |||
+ } nodes[YANG_MODULE_MAX_NODES + 1]; | |||
+#else | |||
} nodes[]; | |||
+#endif | |||
}; | |||
/* Northbound error codes. */ | |||
diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c | |||
index 69cebbd2a1..dd4cbd7d99 100644 | |||
--- a/lib/routemap_northbound.c | |||
+++ b/lib/routemap_northbound.c | |||
@@ -1221,32 +1221,7 @@ lib_route_map_entry_set_action_tag_destroy(enum nb_event event, | |||
} | |||
/* clang-format off */ | |||
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) | |||
-/* | |||
- * gcc versions before 5.x miscalculate the size for structs with variable | |||
- * length arrays (they just count it as size 0) | |||
- */ | |||
-struct frr_yang_module_info_sizen { | |||
- /* YANG module name. */ | |||
- const char *name; | |||
- | |||
- /* Northbound callbacks. */ | |||
- const struct { | |||
- /* Data path of this YANG node. */ | |||
- const char *xpath; | |||
- | |||
- /* Callbacks implemented for this node. */ | |||
- struct nb_callbacks cbs; | |||
- | |||
- /* Priority - lower priorities are processed first. */ | |||
- uint32_t priority; | |||
- } nodes[28]; | |||
-}; | |||
- | |||
-const struct frr_yang_module_info_sizen frr_route_map_info_sizen asm("frr_route_map_info") = { | |||
-#else | |||
const struct frr_yang_module_info frr_route_map_info = { | |||
-#endif | |||
.name = "frr-route-map", | |||
.nodes = { | |||
{ |
@ -0,0 +1,330 @@ | |||
From 97cd849362b45ecbcb20194b5771c5ce777de6bc Mon Sep 17 00:00:00 2001 | |||
From: Renato Westphal <renato@opensourcerouting.org> | |||
Date: Tue, 21 Apr 2020 21:27:47 -0300 | |||
Subject: [PATCH] lib: create a wrapper function for all northbound callbacks | |||
The intention here is to keep the code more organized. These wrappers | |||
should be used by the northbound clients only, and never directly | |||
by any YANG backend code. | |||
Signed-off-by: Renato Westphal <renato@opensourcerouting.org> | |||
--- | |||
lib/northbound.c | 222 +++++++++++++++++++++++----------------- | |||
lib/northbound_grpc.cpp | 3 +- | |||
2 files changed, 131 insertions(+), 94 deletions(-) | |||
diff --git a/lib/northbound.c b/lib/northbound.c | |||
index 85e723d7cf..d10e4713f5 100644 | |||
--- a/lib/northbound.c | |||
+++ b/lib/northbound.c | |||
@@ -62,11 +62,10 @@ static struct { | |||
*/ | |||
static bool transaction_in_progress; | |||
+static int nb_callback_pre_validate(const struct nb_node *nb_node, | |||
+ const struct lyd_node *dnode); | |||
static int nb_callback_configuration(const enum nb_event event, | |||
struct nb_config_change *change); | |||
-static void nb_log_callback(const enum nb_event event, | |||
- enum nb_operation operation, const char *xpath, | |||
- const char *value); | |||
static struct nb_transaction *nb_transaction_new(struct nb_config *config, | |||
struct nb_config_cbs *changes, | |||
enum nb_client client, | |||
@@ -609,18 +608,7 @@ static int nb_candidate_validate_code(struct nb_config *candidate, | |||
if (!nb_node->cbs.pre_validate) | |||
goto next; | |||
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, | |||
- DEBUG_MODE_ALL)) { | |||
- char xpath[XPATH_MAXLEN]; | |||
- | |||
- yang_dnode_get_path(child, xpath, | |||
- sizeof(xpath)); | |||
- nb_log_callback(NB_EV_VALIDATE, | |||
- NB_OP_PRE_VALIDATE, xpath, | |||
- NULL); | |||
- } | |||
- | |||
- ret = (*nb_node->cbs.pre_validate)(child); | |||
+ ret = nb_callback_pre_validate(nb_node, child); | |||
if (ret != NB_OK) | |||
return NB_ERR_VALIDATION; | |||
@@ -791,14 +779,128 @@ int nb_running_lock_check(enum nb_client client, const void *user) | |||
return ret; | |||
} | |||
-static void nb_log_callback(const enum nb_event event, | |||
- enum nb_operation operation, const char *xpath, | |||
- const char *value) | |||
+static void nb_log_config_callback(const enum nb_event event, | |||
+ enum nb_operation operation, | |||
+ const struct lyd_node *dnode) | |||
{ | |||
+ const char *value; | |||
+ char xpath[XPATH_MAXLEN]; | |||
+ | |||
+ if (!DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) | |||
+ return; | |||
+ | |||
+ yang_dnode_get_path(dnode, xpath, sizeof(xpath)); | |||
+ if (yang_snode_is_typeless_data(dnode->schema)) | |||
+ value = "(none)"; | |||
+ else | |||
+ value = yang_dnode_get_string(dnode, NULL); | |||
+ | |||
zlog_debug( | |||
"northbound callback: event [%s] op [%s] xpath [%s] value [%s]", | |||
nb_event_name(event), nb_operation_name(operation), xpath, | |||
- value ? value : "(NULL)"); | |||
+ value); | |||
+} | |||
+ | |||
+static int nb_callback_create(const struct nb_node *nb_node, | |||
+ enum nb_event event, const struct lyd_node *dnode, | |||
+ union nb_resource *resource) | |||
+{ | |||
+ nb_log_config_callback(event, NB_OP_CREATE, dnode); | |||
+ | |||
+ return nb_node->cbs.create(event, dnode, resource); | |||
+} | |||
+ | |||
+static int nb_callback_modify(const struct nb_node *nb_node, | |||
+ enum nb_event event, const struct lyd_node *dnode, | |||
+ union nb_resource *resource) | |||
+{ | |||
+ nb_log_config_callback(event, NB_OP_MODIFY, dnode); | |||
+ | |||
+ return nb_node->cbs.modify(event, dnode, resource); | |||
+} | |||
+ | |||
+static int nb_callback_destroy(const struct nb_node *nb_node, | |||
+ enum nb_event event, | |||
+ const struct lyd_node *dnode) | |||
+{ | |||
+ nb_log_config_callback(event, NB_OP_DESTROY, dnode); | |||
+ | |||
+ return nb_node->cbs.destroy(event, dnode); | |||
+} | |||
+ | |||
+static int nb_callback_move(const struct nb_node *nb_node, enum nb_event event, | |||
+ const struct lyd_node *dnode) | |||
+{ | |||
+ nb_log_config_callback(event, NB_OP_MOVE, dnode); | |||
+ | |||
+ return nb_node->cbs.move(event, dnode); | |||
+} | |||
+ | |||
+static int nb_callback_pre_validate(const struct nb_node *nb_node, | |||
+ const struct lyd_node *dnode) | |||
+{ | |||
+ nb_log_config_callback(NB_EV_VALIDATE, NB_OP_PRE_VALIDATE, dnode); | |||
+ | |||
+ return nb_node->cbs.pre_validate(dnode); | |||
+} | |||
+ | |||
+static void nb_callback_apply_finish(const struct nb_node *nb_node, | |||
+ const struct lyd_node *dnode) | |||
+{ | |||
+ nb_log_config_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, dnode); | |||
+ | |||
+ nb_node->cbs.apply_finish(dnode); | |||
+} | |||
+ | |||
+struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node, | |||
+ const char *xpath, | |||
+ const void *list_entry) | |||
+{ | |||
+ DEBUGD(&nb_dbg_cbs_state, | |||
+ "northbound callback (get_elem): xpath [%s] list_entry [%p]", | |||
+ xpath, list_entry); | |||
+ | |||
+ return nb_node->cbs.get_elem(xpath, list_entry); | |||
+} | |||
+ | |||
+const void *nb_callback_get_next(const struct nb_node *nb_node, | |||
+ const void *parent_list_entry, | |||
+ const void *list_entry) | |||
+{ | |||
+ DEBUGD(&nb_dbg_cbs_state, | |||
+ "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]", | |||
+ nb_node->xpath, parent_list_entry, list_entry); | |||
+ | |||
+ return nb_node->cbs.get_next(parent_list_entry, list_entry); | |||
+} | |||
+ | |||
+int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry, | |||
+ struct yang_list_keys *keys) | |||
+{ | |||
+ DEBUGD(&nb_dbg_cbs_state, | |||
+ "northbound callback (get_keys): node [%s] list_entry [%p]", | |||
+ nb_node->xpath, list_entry); | |||
+ | |||
+ return nb_node->cbs.get_keys(list_entry, keys); | |||
+} | |||
+ | |||
+const void *nb_callback_lookup_entry(const struct nb_node *nb_node, | |||
+ const void *parent_list_entry, | |||
+ const struct yang_list_keys *keys) | |||
+{ | |||
+ DEBUGD(&nb_dbg_cbs_state, | |||
+ "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]", | |||
+ nb_node->xpath, parent_list_entry); | |||
+ | |||
+ return nb_node->cbs.lookup_entry(parent_list_entry, keys); | |||
+} | |||
+ | |||
+int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, | |||
+ const struct list *input, struct list *output) | |||
+{ | |||
+ DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath); | |||
+ | |||
+ return nb_node->cbs.rpc(xpath, input, output); | |||
} | |||
/* | |||
@@ -815,15 +917,6 @@ static int nb_callback_configuration(const enum nb_event event, | |||
union nb_resource *resource; | |||
int ret = NB_ERR; | |||
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) { | |||
- const char *value = "(none)"; | |||
- | |||
- if (dnode && !yang_snode_is_typeless_data(dnode->schema)) | |||
- value = yang_dnode_get_string(dnode, NULL); | |||
- | |||
- yang_dnode_get_path(dnode, xpath, sizeof(xpath)); | |||
- nb_log_callback(event, operation, xpath, value); | |||
- } | |||
if (event == NB_EV_VALIDATE) | |||
resource = NULL; | |||
@@ -832,16 +925,16 @@ static int nb_callback_configuration(const enum nb_event event, | |||
switch (operation) { | |||
case NB_OP_CREATE: | |||
- ret = (*nb_node->cbs.create)(event, dnode, resource); | |||
+ ret = nb_callback_create(nb_node, event, dnode, resource); | |||
break; | |||
case NB_OP_MODIFY: | |||
- ret = (*nb_node->cbs.modify)(event, dnode, resource); | |||
+ ret = nb_callback_modify(nb_node, event, dnode, resource); | |||
break; | |||
case NB_OP_DESTROY: | |||
- ret = (*nb_node->cbs.destroy)(event, dnode); | |||
+ ret = nb_callback_destroy(nb_node, event, dnode); | |||
break; | |||
case NB_OP_MOVE: | |||
- ret = (*nb_node->cbs.move)(event, dnode); | |||
+ ret = nb_callback_move(nb_node, event, dnode); | |||
break; | |||
default: | |||
yang_dnode_get_path(dnode, xpath, sizeof(xpath)); | |||
@@ -890,57 +983,6 @@ static int nb_callback_configuration(const enum nb_event event, | |||
return ret; | |||
} | |||
-struct yang_data *nb_callback_get_elem(const struct nb_node *nb_node, | |||
- const char *xpath, | |||
- const void *list_entry) | |||
-{ | |||
- DEBUGD(&nb_dbg_cbs_state, | |||
- "northbound callback (get_elem): xpath [%s] list_entry [%p]", | |||
- xpath, list_entry); | |||
- | |||
- return nb_node->cbs.get_elem(xpath, list_entry); | |||
-} | |||
- | |||
-const void *nb_callback_get_next(const struct nb_node *nb_node, | |||
- const void *parent_list_entry, | |||
- const void *list_entry) | |||
-{ | |||
- DEBUGD(&nb_dbg_cbs_state, | |||
- "northbound callback (get_next): node [%s] parent_list_entry [%p] list_entry [%p]", | |||
- nb_node->xpath, parent_list_entry, list_entry); | |||
- | |||
- return nb_node->cbs.get_next(parent_list_entry, list_entry); | |||
-} | |||
- | |||
-int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry, | |||
- struct yang_list_keys *keys) | |||
-{ | |||
- DEBUGD(&nb_dbg_cbs_state, | |||
- "northbound callback (get_keys): node [%s] list_entry [%p]", | |||
- nb_node->xpath, list_entry); | |||
- | |||
- return nb_node->cbs.get_keys(list_entry, keys); | |||
-} | |||
- | |||
-const void *nb_callback_lookup_entry(const struct nb_node *nb_node, | |||
- const void *parent_list_entry, | |||
- const struct yang_list_keys *keys) | |||
-{ | |||
- DEBUGD(&nb_dbg_cbs_state, | |||
- "northbound callback (lookup_entry): node [%s] parent_list_entry [%p]", | |||
- nb_node->xpath, parent_list_entry); | |||
- | |||
- return nb_node->cbs.lookup_entry(parent_list_entry, keys); | |||
-} | |||
- | |||
-int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath, | |||
- const struct list *input, struct list *output) | |||
-{ | |||
- DEBUGD(&nb_dbg_cbs_rpc, "northbound RPC: %s", xpath); | |||
- | |||
- return nb_node->cbs.rpc(xpath, input, output); | |||
-} | |||
- | |||
static struct nb_transaction * | |||
nb_transaction_new(struct nb_config *config, struct nb_config_cbs *changes, | |||
enum nb_client client, const void *user, const char *comment) | |||
@@ -1058,7 +1100,6 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) | |||
{ | |||
struct nb_config_cbs cbs; | |||
struct nb_config_cb *cb; | |||
- char xpath[XPATH_MAXLEN]; | |||
/* Initialize tree of 'apply_finish' callbacks. */ | |||
RB_INIT(nb_config_cbs, &cbs); | |||
@@ -1075,6 +1116,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) | |||
* be called though). | |||
*/ | |||
if (change->cb.operation == NB_OP_DESTROY) { | |||
+ char xpath[XPATH_MAXLEN]; | |||
+ | |||
dnode = dnode->parent; | |||
if (!dnode) | |||
break; | |||
@@ -1111,15 +1154,8 @@ static void nb_transaction_apply_finish(struct nb_transaction *transaction) | |||
} | |||
/* Call the 'apply_finish' callbacks, sorted by their priorities. */ | |||
- RB_FOREACH (cb, nb_config_cbs, &cbs) { | |||
- if (DEBUG_MODE_CHECK(&nb_dbg_cbs_config, DEBUG_MODE_ALL)) { | |||
- yang_dnode_get_path(cb->dnode, xpath, sizeof(xpath)); | |||
- nb_log_callback(NB_EV_APPLY, NB_OP_APPLY_FINISH, xpath, | |||
- NULL); | |||
- } | |||
- | |||
- (*cb->nb_node->cbs.apply_finish)(cb->dnode); | |||
- } | |||
+ RB_FOREACH (cb, nb_config_cbs, &cbs) | |||
+ nb_callback_apply_finish(cb->nb_node, cb->dnode); | |||
/* Release memory. */ | |||
while (!RB_EMPTY(nb_config_cbs, &cbs)) { | |||
diff --git a/lib/northbound_grpc.cpp b/lib/northbound_grpc.cpp | |||
index b195f1aeca..66bf05c1ab 100644 | |||
--- a/lib/northbound_grpc.cpp | |||
+++ b/lib/northbound_grpc.cpp | |||
@@ -545,7 +545,8 @@ class NorthboundImpl final : public frr::Northbound::Service | |||
} | |||
// Execute callback registered for this XPath. | |||
- if (nb_node->cbs.rpc(xpath, input_list, output_list) != NB_OK) { | |||
+ if (nb_callback_rpc(nb_node, xpath, input_list, output_list) | |||
+ != NB_OK) { | |||
flog_warn(EC_LIB_NB_CB_RPC, | |||
"%s: rpc callback failed: %s", __func__, | |||
xpath); |
@ -0,0 +1,33 @@ | |||
From 0b7086494e9fe056f35560bcab53ff9eb0e68df4 Mon Sep 17 00:00:00 2001 | |||
From: Mark Stapp <mjs@voltanet.io> | |||
Date: Wed, 19 Feb 2020 08:44:05 -0500 | |||
Subject: [PATCH] zebra: fix missing route-advert stubs | |||
Stubs are used when frr is built without route-advert | |||
support; a couple of apis were missing, causing builds to fail. | |||
Signed-off-by: Mark Stapp <mjs@voltanet.io> | |||
--- | |||
zebra/rtadv.c | 11 +++++++++++ | |||
1 file changed, 11 insertions(+) | |||
diff --git a/zebra/rtadv.c b/zebra/rtadv.c | |||
index e9a97d4b15..c710978d78 100644 | |||
--- a/zebra/rtadv.c | |||
+++ b/zebra/rtadv.c | |||
@@ -2399,4 +2399,15 @@ void rtadv_cmd_init(void) | |||
{ | |||
/* Empty.*/; | |||
} | |||
+ | |||
+void rtadv_stop_ra(struct interface *ifp) | |||
+{ | |||
+ /* Empty.*/; | |||
+} | |||
+ | |||
+void rtadv_stop_ra_all(void) | |||
+{ | |||
+ /* Empty.*/; | |||
+} | |||
+ | |||
#endif /* HAVE_RTADV */ |
@ -0,0 +1,218 @@ | |||
From 2b5eda4c0539dcd30a06c975be36f879cc454e9f Mon Sep 17 00:00:00 2001 | |||
From: Donald Sharp <sharpd@cumulusnetworks.com> | |||
Date: Mon, 10 Feb 2020 19:25:52 -0500 | |||
Subject: [PATCH 1/3] bgpd: Update failed reason to distinguish some NHT | |||
scenarios | |||
Current failed reasons for bgp when you have a peer that | |||
is not online yet is `Waiting for NHT`, even if NHT has | |||
succeeded. Add some code to differentiate this. | |||
eva# show bgp ipv4 uni summ failed | |||
BGP router identifier 192.168.201.135, local AS number 3923 vrf-id 0 | |||
BGP table version 0 | |||
RIB entries 0, using 0 bytes of memory | |||
Peers 2, using 43 KiB of memory | |||
Neighbor EstdCnt DropCnt ResetTime Reason | |||
192.168.44.1 0 0 never Waiting for NHT | |||
192.168.201.139 0 0 never Waiting for Open to Succeed | |||
Total number of neighbors 2 | |||
eva# | |||
eva# show bgp nexthop | |||
Current BGP nexthop cache: | |||
192.168.44.1 invalid, peer 192.168.44.1 | |||
Must be Connected | |||
Last update: Mon Feb 10 19:05:19 2020 | |||
192.168.201.139 valid [IGP metric 0], #paths 0, peer 192.168.201.139 | |||
So 192.168.201.139 is a peer for a connected route that has not been | |||
created on .139, while 44.1 nexthop tracking has not succeeded yet. | |||
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> | |||
--- | |||
bgpd/bgp_fsm.c | 4 +++- | |||
bgpd/bgp_nht.c | 23 ++++++++++++++++------- | |||
bgpd/bgpd.h | 12 +++++++++--- | |||
3 files changed, 28 insertions(+), 11 deletions(-) | |||
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c | |||
index 3667dae83d..107e9fc892 100644 | |||
--- a/bgpd/bgp_fsm.c | |||
+++ b/bgpd/bgp_fsm.c | |||
@@ -560,7 +560,9 @@ const char *const peer_down_str[] = {"", | |||
"Waiting for NHT", | |||
"Waiting for Peer IPv6 LLA", | |||
"Waiting for VRF to be initialized", | |||
- "No AFI/SAFI activated for peer"}; | |||
+ "No AFI/SAFI activated for peer", | |||
+ "AS Set config change", | |||
+ "Waiting for peer OPEN"}; | |||
static int bgp_graceful_restart_timer_expire(struct thread *thread) | |||
{ | |||
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c | |||
index a50fc7d697..e9496e47a9 100644 | |||
--- a/bgpd/bgp_nht.c | |||
+++ b/bgpd/bgp_nht.c | |||
@@ -788,13 +788,22 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc) | |||
bgp_process(bgp_path, rn, afi, safi); | |||
} | |||
- if (peer && !CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED)) { | |||
- if (BGP_DEBUG(nht, NHT)) | |||
- zlog_debug("%s: Updating peer (%s(%s)) status with NHT", | |||
- __FUNCTION__, peer->host, | |||
- peer->bgp->name_pretty); | |||
- bgp_fsm_event_update(peer, bgp_isvalid_nexthop(bnc)); | |||
- SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED); | |||
+ if (peer) { | |||
+ int valid_nexthops = bgp_isvalid_nexthop(bnc); | |||
+ | |||
+ if (valid_nexthops) | |||
+ peer->last_reset = PEER_DOWN_WAITING_OPEN; | |||
+ else | |||
+ peer->last_reset = PEER_DOWN_WAITING_NHT; | |||
+ | |||
+ if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED)) { | |||
+ if (BGP_DEBUG(nht, NHT)) | |||
+ zlog_debug("%s: Updating peer (%s(%s)) status with NHT", | |||
+ __FUNCTION__, peer->host, | |||
+ peer->bgp->name_pretty); | |||
+ bgp_fsm_event_update(peer, valid_nexthops); | |||
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED); | |||
+ } | |||
} | |||
RESET_FLAG(bnc->change_flags); | |||
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h | |||
index 7d81579009..66d7633553 100644 | |||
--- a/bgpd/bgpd.h | |||
+++ b/bgpd/bgpd.h | |||
@@ -1185,10 +1185,10 @@ struct peer { | |||
#define PEER_DOWN_REMOTE_AS_CHANGE 2 /* neighbor remote-as command */ | |||
#define PEER_DOWN_LOCAL_AS_CHANGE 3 /* neighbor local-as command */ | |||
#define PEER_DOWN_CLID_CHANGE 4 /* bgp cluster-id command */ | |||
-#define PEER_DOWN_CONFED_ID_CHANGE 5 /* bgp confederation identifier command */ | |||
+#define PEER_DOWN_CONFED_ID_CHANGE 5 /* bgp confederation id command */ | |||
#define PEER_DOWN_CONFED_PEER_CHANGE 6 /* bgp confederation peer command */ | |||
-#define PEER_DOWN_RR_CLIENT_CHANGE 7 /* neighbor route-reflector-client command */ | |||
-#define PEER_DOWN_RS_CLIENT_CHANGE 8 /* neighbor route-server-client command */ | |||
+#define PEER_DOWN_RR_CLIENT_CHANGE 7 /* neighbor rr-client command */ | |||
+#define PEER_DOWN_RS_CLIENT_CHANGE 8 /* neighbor rs-client command */ | |||
#define PEER_DOWN_UPDATE_SOURCE_CHANGE 9 /* neighbor update-source command */ | |||
#define PEER_DOWN_AF_ACTIVATE 10 /* neighbor activate command */ | |||
#define PEER_DOWN_USER_SHUTDOWN 11 /* neighbor shutdown command */ | |||
@@ -1212,6 +1212,12 @@ struct peer { | |||
#define PEER_DOWN_VRF_UNINIT 29 /* Associated VRF is not init yet */ | |||
#define PEER_DOWN_NOAFI_ACTIVATED 30 /* No AFI/SAFI activated for peer */ | |||
#define PEER_DOWN_AS_SETS_REJECT 31 /* Reject routes with AS_SET */ | |||
+#define PEER_DOWN_WAITING_OPEN 32 /* Waiting for open to succeed */ | |||
+ /* | |||
+ * Remember to update peer_down_str in bgp_fsm.c when you add | |||
+ * a new value to the last_reset reason | |||
+ */ | |||
+ | |||
size_t last_reset_cause_size; | |||
uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE]; | |||
From 4098f79949dd0e1e4ed7b89df8dc9b2be81fa9d6 Mon Sep 17 00:00:00 2001 | |||
From: Donatas Abraitis <donatas.abraitis@gmail.com> | |||
Date: Fri, 14 Feb 2020 23:21:55 +0200 | |||
Subject: [PATCH 2/3] bgpd: Show the real reason why the peer is failed | |||
If the peer was shutdown locally, it doesn't show up as admin. shutdown. | |||
Instead it's treated as "Waiting for peer OPEN". | |||
The same applies to when the peer reaches maximum-prefix count. | |||
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com> | |||
--- | |||
bgpd/bgp_fsm.c | 7 ++++++- | |||
bgpd/bgpd.h | 1 + | |||
2 files changed, 7 insertions(+), 1 deletion(-) | |||
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c | |||
index 107e9fc892..c920c4e501 100644 | |||
--- a/bgpd/bgp_fsm.c | |||
+++ b/bgpd/bgp_fsm.c | |||
@@ -562,7 +562,8 @@ const char *const peer_down_str[] = {"", | |||
"Waiting for VRF to be initialized", | |||
"No AFI/SAFI activated for peer", | |||
"AS Set config change", | |||
- "Waiting for peer OPEN"}; | |||
+ "Waiting for peer OPEN", | |||
+ "Reached received prefix count"}; | |||
static int bgp_graceful_restart_timer_expire(struct thread *thread) | |||
{ | |||
@@ -1431,6 +1432,10 @@ int bgp_start(struct peer *peer) | |||
"%s [FSM] Trying to start suppressed peer" | |||
" - this is never supposed to happen!", | |||
peer->host); | |||
+ if (CHECK_FLAG(peer->flags, PEER_FLAG_SHUTDOWN)) | |||
+ peer->last_reset = PEER_DOWN_USER_SHUTDOWN; | |||
+ else if (CHECK_FLAG(peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) | |||
+ peer->last_reset = PEER_DOWN_PFX_COUNT; | |||
return -1; | |||
} | |||
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h | |||
index 66d7633553..49e2a537fd 100644 | |||
--- a/bgpd/bgpd.h | |||
+++ b/bgpd/bgpd.h | |||
@@ -1213,6 +1213,7 @@ struct peer { | |||
#define PEER_DOWN_NOAFI_ACTIVATED 30 /* No AFI/SAFI activated for peer */ | |||
#define PEER_DOWN_AS_SETS_REJECT 31 /* Reject routes with AS_SET */ | |||
#define PEER_DOWN_WAITING_OPEN 32 /* Waiting for open to succeed */ | |||
+#define PEER_DOWN_PFX_COUNT 33 /* Reached received prefix count */ | |||
/* | |||
* Remember to update peer_down_str in bgp_fsm.c when you add | |||
* a new value to the last_reset reason | |||
From 540528864d85a3b00e0794da769497ecfb8e0c27 Mon Sep 17 00:00:00 2001 | |||
From: Donatas Abraitis <donatas.abraitis@gmail.com> | |||
Date: Tue, 11 Feb 2020 18:02:19 +0200 | |||
Subject: [PATCH 3/3] bgpd: Format properly `show bgp summary failed` | |||
Before: | |||
``` | |||
Neighbor EstdCnt DropCnt ResetTime Reason | |||
192.168.0.1 0 0 never Waiting for peer OPEN | |||
``` | |||
After: | |||
``` | |||
Neighbor EstdCnt DropCnt ResetTime Reason | |||
192.168.0.1 0 0 never Waiting for peer OPEN | |||
``` | |||
Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com> | |||
--- | |||
bgpd/bgp_vty.c | 4 ++-- | |||
1 file changed, 2 insertions(+), 2 deletions(-) | |||
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c | |||
index 53d9732956..243822206c 100644 | |||
--- a/bgpd/bgp_vty.c | |||
+++ b/bgpd/bgp_vty.c | |||
@@ -8063,7 +8063,7 @@ static void bgp_show_peer_reset(struct vty * vty, struct peer *peer, | |||
: "received", | |||
code_str, subcode_str); | |||
} else { | |||
- vty_out(vty, " %s\n", | |||
+ vty_out(vty, " %s\n", | |||
peer_down_str[(int)peer->last_reset]); | |||
} | |||
} | |||
@@ -8119,7 +8119,7 @@ static void bgp_show_failed_summary(struct vty *vty, struct bgp *bgp, | |||
if (len < max_neighbor_width) | |||
vty_out(vty, "%*s", max_neighbor_width - len, | |||
" "); | |||
- vty_out(vty, "%7d %7d %8s", peer->established, | |||
+ vty_out(vty, "%7d %7d %9s", peer->established, | |||
peer->dropped, | |||
peer_uptime(peer->uptime, timebuf, | |||
BGP_UPTIME_LEN, 0, NULL)); |
@ -0,0 +1,177 @@ | |||
From 33a9ff0045adfa605832187e570dbe1374ceb22e Mon Sep 17 00:00:00 2001 | |||
From: Mark Stapp <mjs@voltanet.io> | |||
Date: Tue, 28 Jan 2020 11:00:42 -0500 | |||
Subject: [PATCH] zebra: add config to disable use of kernel nexthops | |||
Add a config that disables use of kernel-level nexthop ids. | |||
Currently, zebra always uses nexthop ids if the kernel supports | |||
them. | |||
Signed-off-by: Mark Stapp <mjs@voltanet.io> | |||
--- | |||
zebra/rt_netlink.c | 20 ++++++++++++++++---- | |||
zebra/zebra_nhg.c | 18 ++++++++++++++++++ | |||
zebra/zebra_nhg.h | 10 +++++++++- | |||
zebra/zebra_vty.c | 18 ++++++++++++++++++ | |||
4 files changed, 61 insertions(+), 5 deletions(-) | |||
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c | |||
index 2abcd6ef2a..705536595b 100644 | |||
--- a/zebra/rt_netlink.c | |||
+++ b/zebra/rt_netlink.c | |||
@@ -75,6 +75,10 @@ | |||
static vlanid_t filter_vlan = 0; | |||
+/* We capture whether the current kernel supports nexthop ids; by | |||
+ * default, we'll use them if possible. There's also a configuration | |||
+ * available to _disable_ use of kernel nexthops. | |||
+ */ | |||
static bool supports_nh; | |||
struct gw_family_t { | |||
@@ -86,6 +90,12 @@ struct gw_family_t { | |||
static const char ipv4_ll_buf[16] = "169.254.0.1"; | |||
static struct in_addr ipv4_ll; | |||
+/* Helper to control use of kernel-level nexthop ids */ | |||
+static bool kernel_nexthops_supported(void) | |||
+{ | |||
+ return (supports_nh && zebra_nhg_kernel_nexthops_enabled()); | |||
+} | |||
+ | |||
/* | |||
* The ipv4_ll data structure is used for all 5549 | |||
* additions to the kernel. Let's figure out the | |||
@@ -1628,7 +1638,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) | |||
RTA_PAYLOAD(rta)); | |||
} | |||
- if (supports_nh) { | |||
+ if (kernel_nexthops_supported()) { | |||
/* Kernel supports nexthop objects */ | |||
addattr32(&req.n, sizeof(req), RTA_NH_ID, | |||
dplane_ctx_get_nhe_id(ctx)); | |||
@@ -1943,7 +1953,7 @@ static int netlink_nexthop(int cmd, struct zebra_dplane_ctx *ctx) | |||
size_t req_size = sizeof(req); | |||
/* Nothing to do if the kernel doesn't support nexthop objects */ | |||
- if (!supports_nh) | |||
+ if (!kernel_nexthops_supported()) | |||
return 0; | |||
label_buf[0] = '\0'; | |||
@@ -2504,8 +2514,10 @@ int netlink_nexthop_read(struct zebra_ns *zns) | |||
* this kernel must support them. | |||
*/ | |||
supports_nh = true; | |||
- else if (IS_ZEBRA_DEBUG_KERNEL) | |||
- zlog_debug("Nexthop objects not supported on this kernel"); | |||
+ | |||
+ if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_NHG) | |||
+ zlog_debug("Nexthop objects %ssupported on this kernel", | |||
+ supports_nh ? "" : "not "); | |||
return ret; | |||
} | |||
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c | |||
index cbeb73aed4..62c478cf85 100644 | |||
--- a/zebra/zebra_nhg.c | |||
+++ b/zebra/zebra_nhg.c | |||
@@ -49,6 +49,9 @@ DEFINE_MTYPE_STATIC(ZEBRA, NHG_CTX, "Nexthop Group Context"); | |||
/* id counter to keep in sync with kernel */ | |||
uint32_t id_counter; | |||
+/* */ | |||
+static bool g_nexthops_enabled = true; | |||
+ | |||
static struct nhg_hash_entry *depends_find(const struct nexthop *nh, | |||
afi_t afi); | |||
static void depends_add(struct nhg_connected_tree_head *head, | |||
@@ -2004,3 +2007,18 @@ void zebra_nhg_sweep_table(struct hash *hash) | |||
{ | |||
hash_iterate(hash, zebra_nhg_sweep_entry, NULL); | |||
} | |||
+ | |||
+/* Global control to disable use of kernel nexthops, if available. We can't | |||
+ * force the kernel to support nexthop ids, of course, but we can disable | |||
+ * zebra's use of them, for testing e.g. By default, if the kernel supports | |||
+ * nexthop ids, zebra uses them. | |||
+ */ | |||
+void zebra_nhg_enable_kernel_nexthops(bool set) | |||
+{ | |||
+ g_nexthops_enabled = set; | |||
+} | |||
+ | |||
+bool zebra_nhg_kernel_nexthops_enabled(void) | |||
+{ | |||
+ return g_nexthops_enabled; | |||
+} | |||
diff --git a/zebra/zebra_nhg.h b/zebra/zebra_nhg.h | |||
index c2e173e094..4d001944b7 100644 | |||
--- a/zebra/zebra_nhg.h | |||
+++ b/zebra/zebra_nhg.h | |||
@@ -153,6 +153,13 @@ struct nhg_ctx { | |||
enum nhg_ctx_status status; | |||
}; | |||
+/* Global control to disable use of kernel nexthops, if available. We can't | |||
+ * force the kernel to support nexthop ids, of course, but we can disable | |||
+ * zebra's use of them, for testing e.g. By default, if the kernel supports | |||
+ * nexthop ids, zebra uses them. | |||
+ */ | |||
+void zebra_nhg_enable_kernel_nexthops(bool set); | |||
+bool zebra_nhg_kernel_nexthops_enabled(void); | |||
/** | |||
* NHE abstracted tree functions. | |||
@@ -227,4 +234,5 @@ extern void zebra_nhg_sweep_table(struct hash *hash); | |||
/* Nexthop resolution processing */ | |||
struct route_entry; /* Forward ref to avoid circular includes */ | |||
extern int nexthop_active_update(struct route_node *rn, struct route_entry *re); | |||
-#endif | |||
+ | |||
+#endif /* __ZEBRA_NHG_H__ */ | |||
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c | |||
index 78001da170..866b38b47e 100644 | |||
--- a/zebra/zebra_vty.c | |||
+++ b/zebra/zebra_vty.c | |||
@@ -1410,6 +1410,19 @@ DEFPY (show_nexthop_group, | |||
return CMD_SUCCESS; | |||
} | |||
+DEFPY_HIDDEN(nexthop_group_use_enable, | |||
+ nexthop_group_use_enable_cmd, | |||
+ "[no] zebra nexthop kernel enable", | |||
+ NO_STR | |||
+ ZEBRA_STR | |||
+ "Nexthop configuration \n" | |||
+ "Configure use of kernel nexthops\n" | |||
+ "Enable kernel nexthops\n") | |||
+{ | |||
+ zebra_nhg_enable_kernel_nexthops(!no); | |||
+ return CMD_SUCCESS; | |||
+} | |||
+ | |||
DEFUN (no_ip_nht_default_route, | |||
no_ip_nht_default_route_cmd, | |||
"no ip nht resolve-via-default", | |||
@@ -3121,6 +3134,10 @@ static int config_write_protocol(struct vty *vty) | |||
/* Include dataplane info */ | |||
dplane_config_write_helper(vty); | |||
+ /* Include nexthop-group config */ | |||
+ if (!zebra_nhg_kernel_nexthops_enabled()) | |||
+ vty_out(vty, "no zebra nexthop kernel enable\n"); | |||
+ | |||
return 1; | |||
} | |||
@@ -3492,6 +3509,7 @@ void zebra_vty_init(void) | |||
install_element(CONFIG_NODE, &no_zebra_workqueue_timer_cmd); | |||
install_element(CONFIG_NODE, &zebra_packet_process_cmd); | |||
install_element(CONFIG_NODE, &no_zebra_packet_process_cmd); | |||
+ install_element(CONFIG_NODE, &nexthop_group_use_enable_cmd); | |||
install_element(VIEW_NODE, &show_nexthop_group_cmd); | |||
install_element(VIEW_NODE, &show_interface_nexthop_group_cmd); |
@ -0,0 +1,166 @@ | |||
From b49789f5d32429722542a1a7de4b371b43958a31 Mon Sep 17 00:00:00 2001 | |||
From: Donald Sharp <sharpd@cumulusnetworks.com> | |||
Date: Wed, 18 Mar 2020 22:30:28 -0400 | |||
Subject: [PATCH] yang: Partially revert code to restore functionality | |||
Partially revert code from commit: | |||
f22b9250853229c93617ffdad139a4762f5f7348 | |||
since this broke passive-interface, network and offset-list | |||
commands in rip and ripng | |||
Fixes: #6001 | |||
Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com> | |||
--- | |||
yang/frr-eigrpd.yang | 9 +++------ | |||
yang/frr-ripd.yang | 27 ++++++++++----------------- | |||
yang/frr-ripngd.yang | 23 +++++++---------------- | |||
3 files changed, 20 insertions(+), 39 deletions(-) | |||
diff --git a/yang/frr-eigrpd.yang b/yang/frr-eigrpd.yang | |||
index 0c62954570..853d823880 100644 | |||
--- a/yang/frr-eigrpd.yang | |||
+++ b/yang/frr-eigrpd.yang | |||
@@ -23,11 +23,6 @@ module frr-eigrpd { | |||
description | |||
"This module defines a model for managing FRR eigrpd daemon."; | |||
- revision 2019-09-09 { | |||
- description | |||
- "Changed interface references to use | |||
- frr-interface:interface-ref typedef"; | |||
- } | |||
revision 2019-06-19 { | |||
description "Initial revision."; | |||
reference | |||
@@ -99,7 +94,9 @@ module frr-eigrpd { | |||
leaf-list passive-interface { | |||
description "List of suppressed interfaces"; | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
} | |||
leaf active-time { | |||
diff --git a/yang/frr-ripd.yang b/yang/frr-ripd.yang | |||
index 94a9ebf3e1..07690793f0 100644 | |||
--- a/yang/frr-ripd.yang | |||
+++ b/yang/frr-ripd.yang | |||
@@ -24,11 +24,6 @@ module frr-ripd { | |||
description | |||
"This module defines a model for managing FRR ripd daemon."; | |||
- revision 2019-09-09 { | |||
- description | |||
- "Changed interface references to use | |||
- frr-interface:interface-ref typedef"; | |||
- } | |||
revision 2017-12-06 { | |||
description | |||
"Initial revision."; | |||
@@ -118,7 +113,9 @@ module frr-ripd { | |||
"Enable RIP on the specified IP network."; | |||
} | |||
leaf-list interface { | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
description | |||
"Enable RIP on the specified interface."; | |||
} | |||
@@ -127,15 +124,7 @@ module frr-ripd { | |||
description | |||
"Offset-list to modify route metric."; | |||
leaf interface { | |||
- type union { | |||
- type frr-interface:interface-ref; | |||
- type enumeration { | |||
- enum '*' { | |||
- description | |||
- "Match all interfaces."; | |||
- } | |||
- } | |||
- } | |||
+ type string; | |||
description | |||
"Interface to match. Use '*' to match all interfaces."; | |||
} | |||
@@ -179,14 +168,18 @@ module frr-ripd { | |||
} | |||
leaf-list passive-interface { | |||
when "../passive-default = 'false'"; | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
description | |||
"A list of interfaces where the sending of RIP packets | |||
is disabled."; | |||
} | |||
leaf-list non-passive-interface { | |||
when "../passive-default = 'true'"; | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
description | |||
"A list of interfaces where the sending of RIP packets | |||
is enabled."; | |||
diff --git a/yang/frr-ripngd.yang b/yang/frr-ripngd.yang | |||
index 831758af86..b341b438a4 100644 | |||
--- a/yang/frr-ripngd.yang | |||
+++ b/yang/frr-ripngd.yang | |||
@@ -24,11 +24,6 @@ module frr-ripngd { | |||
description | |||
"This module defines a model for managing FRR ripngd daemon."; | |||
- revision 2019-09-09 { | |||
- description | |||
- "Changed interface references to use | |||
- frr-interface:interface-ref typedef"; | |||
- } | |||
revision 2018-11-27 { | |||
description | |||
"Initial revision."; | |||
@@ -76,7 +71,9 @@ module frr-ripngd { | |||
"Enable RIPng on the specified IPv6 network."; | |||
} | |||
leaf-list interface { | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
description | |||
"Enable RIPng on the specified interface."; | |||
} | |||
@@ -85,15 +82,7 @@ module frr-ripngd { | |||
description | |||
"Offset-list to modify route metric."; | |||
leaf interface { | |||
- type union { | |||
- type frr-interface:interface-ref; | |||
- type enumeration { | |||
- enum '*' { | |||
- description | |||
- "Match all interfaces."; | |||
- } | |||
- } | |||
- } | |||
+ type string; | |||
description | |||
"Interface to match. Use '*' to match all interfaces."; | |||
} | |||
@@ -129,7 +118,9 @@ module frr-ripngd { | |||
} | |||
} | |||
leaf-list passive-interface { | |||
- type frr-interface:interface-ref; | |||
+ type string { | |||
+ length "1..16"; | |||
+ } | |||
description | |||
"A list of interfaces where the sending of RIPng packets | |||
is disabled."; |
@ -0,0 +1,174 @@ | |||
From c9d7f8c0126b7b078b06f36096a2b3bbbc1f63b4 Mon Sep 17 00:00:00 2001 | |||
From: Stephen Worley <sworley@cumulusnetworks.com> | |||
Date: Tue, 24 Mar 2020 17:10:08 -0400 | |||
Subject: [PATCH 1/2] zebra: abstract route src determiniation into func | |||
Abstraction the route src determination from a nexthop in the | |||
netlink code into a function for both singlepath and mutlipath | |||
to call. | |||
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com> | |||
(cherry picked from commit 762288f50f5fa29512864fcc7814be83e1b58ff4) | |||
--- | |||
zebra/rt_netlink.c | 81 ++++++++++++++++------------------------------ | |||
1 file changed, 28 insertions(+), 53 deletions(-) | |||
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c | |||
index 705536595b..dcaf2155f0 100644 | |||
--- a/zebra/rt_netlink.c | |||
+++ b/zebra/rt_netlink.c | |||
@@ -1513,6 +1513,30 @@ static int netlink_neigh_update(int cmd, int ifindex, uint32_t addr, char *lla, | |||
0); | |||
} | |||
+static bool nexthop_set_src(const struct nexthop *nexthop, int family, | |||
+ union g_addr *src) | |||
+{ | |||
+ if (family == AF_INET) { | |||
+ if (nexthop->rmap_src.ipv4.s_addr != INADDR_ANY) { | |||
+ src->ipv4 = nexthop->rmap_src.ipv4; | |||
+ return true; | |||
+ } else if (nexthop->src.ipv4.s_addr != INADDR_ANY) { | |||
+ src->ipv4 = nexthop->src.ipv4; | |||
+ return true; | |||
+ } | |||
+ } else if (family == AF_INET6) { | |||
+ if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->rmap_src.ipv6)) { | |||
+ src->ipv6 = nexthop->rmap_src.ipv6; | |||
+ return true; | |||
+ } else if (!IN6_IS_ADDR_UNSPECIFIED(&nexthop->src.ipv6)) { | |||
+ src->ipv6 = nexthop->src.ipv6; | |||
+ return true; | |||
+ } | |||
+ } | |||
+ | |||
+ return false; | |||
+} | |||
+ | |||
/* | |||
* Routing table change via netlink interface, using a dataplane context object | |||
*/ | |||
@@ -1523,7 +1547,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) | |||
unsigned int nexthop_num; | |||
int family; | |||
const char *routedesc; | |||
- int setsrc = 0; | |||
+ bool setsrc = false; | |||
union g_addr src; | |||
const struct prefix *p, *src_p; | |||
uint32_t table_id; | |||
@@ -1689,32 +1713,8 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) | |||
if (setsrc) | |||
continue; | |||
- if (family == AF_INET) { | |||
- if (nexthop->rmap_src.ipv4.s_addr | |||
- != 0) { | |||
- src.ipv4 = | |||
- nexthop->rmap_src.ipv4; | |||
- setsrc = 1; | |||
- } else if (nexthop->src.ipv4.s_addr | |||
- != 0) { | |||
- src.ipv4 = | |||
- nexthop->src.ipv4; | |||
- setsrc = 1; | |||
- } | |||
- } else if (family == AF_INET6) { | |||
- if (!IN6_IS_ADDR_UNSPECIFIED( | |||
- &nexthop->rmap_src.ipv6)) { | |||
- src.ipv6 = | |||
- nexthop->rmap_src.ipv6; | |||
- setsrc = 1; | |||
- } else if ( | |||
- !IN6_IS_ADDR_UNSPECIFIED( | |||
- &nexthop->src.ipv6)) { | |||
- src.ipv6 = | |||
- nexthop->src.ipv6; | |||
- setsrc = 1; | |||
- } | |||
- } | |||
+ setsrc = nexthop_set_src(nexthop, family, &src); | |||
+ | |||
continue; | |||
} | |||
@@ -1757,32 +1757,7 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) | |||
if (setsrc) | |||
continue; | |||
- if (family == AF_INET) { | |||
- if (nexthop->rmap_src.ipv4.s_addr | |||
- != 0) { | |||
- src.ipv4 = | |||
- nexthop->rmap_src.ipv4; | |||
- setsrc = 1; | |||
- } else if (nexthop->src.ipv4.s_addr | |||
- != 0) { | |||
- src.ipv4 = | |||
- nexthop->src.ipv4; | |||
- setsrc = 1; | |||
- } | |||
- } else if (family == AF_INET6) { | |||
- if (!IN6_IS_ADDR_UNSPECIFIED( | |||
- &nexthop->rmap_src.ipv6)) { | |||
- src.ipv6 = | |||
- nexthop->rmap_src.ipv6; | |||
- setsrc = 1; | |||
- } else if ( | |||
- !IN6_IS_ADDR_UNSPECIFIED( | |||
- &nexthop->src.ipv6)) { | |||
- src.ipv6 = | |||
- nexthop->src.ipv6; | |||
- setsrc = 1; | |||
- } | |||
- } | |||
+ setsrc = nexthop_set_src(nexthop, family, &src); | |||
continue; | |||
} | |||
From e85c67d05decf340dcf5663a48c652719d04387f Mon Sep 17 00:00:00 2001 | |||
From: Stephen Worley <sworley@cumulusnetworks.com> | |||
Date: Tue, 24 Mar 2020 17:32:21 -0400 | |||
Subject: [PATCH 2/2] zebra: determine src when using nexthop objects | |||
Determine src based on nexthop data even when we are using | |||
kernel nexthop objects. | |||
Before, we were entirely skipping this step and just sending the | |||
nexthop ID, ignoring src determination. | |||
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com> | |||
(cherry picked from commit d8bfd8dc9a899f841967257a6b5f30910fdc17c8) | |||
--- | |||
zebra/rt_netlink.c | 17 +++++++++++++++++ | |||
1 file changed, 17 insertions(+) | |||
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c | |||
index dcaf2155f0..ee8ef6558f 100644 | |||
--- a/zebra/rt_netlink.c | |||
+++ b/zebra/rt_netlink.c | |||
@@ -1666,6 +1666,23 @@ static int netlink_route_multipath(int cmd, struct zebra_dplane_ctx *ctx) | |||
/* Kernel supports nexthop objects */ | |||
addattr32(&req.n, sizeof(req), RTA_NH_ID, | |||
dplane_ctx_get_nhe_id(ctx)); | |||
+ | |||
+ /* Have to determine src still */ | |||
+ for (ALL_NEXTHOPS_PTR(dplane_ctx_get_ng(ctx), nexthop)) { | |||
+ if (setsrc) | |||
+ break; | |||
+ | |||
+ setsrc = nexthop_set_src(nexthop, family, &src); | |||
+ } | |||
+ | |||
+ if (setsrc) { | |||
+ if (family == AF_INET) | |||
+ addattr_l(&req.n, sizeof(req), RTA_PREFSRC, | |||
+ &src.ipv4, bytelen); | |||
+ else if (family == AF_INET6) | |||
+ addattr_l(&req.n, sizeof(req), RTA_PREFSRC, | |||
+ &src.ipv6, bytelen); | |||
+ } | |||
goto skip; | |||
} | |||
@ -0,0 +1,61 @@ | |||
From 7cc9f2c7953d48cfb70b7e0c1b0c57e45ae68ce8 Mon Sep 17 00:00:00 2001 | |||
From: Stephen Worley <sworley@cumulusnetworks.com> | |||
Date: Wed, 1 Apr 2020 15:31:40 -0400 | |||
Subject: [PATCH] zebra: free unhashable (dup) NHEs via ID table cleanup | |||
Free unhashable (duplicate NHEs from the kernel) via ID table | |||
cleanup. Since the NHE ID hash table contains extra entries, | |||
that's the one we need to be calling zebra_nhg_hash_free() | |||
on, otherwise we will never free the unhashable NHEs. | |||
This was found via a memleak: | |||
==1478713== HEAP SUMMARY: | |||
==1478713== in use at exit: 10,267 bytes in 46 blocks | |||
==1478713== total heap usage: 76,810 allocs, 76,764 frees, 3,901,237 bytes allocated | |||
==1478713== | |||
==1478713== 208 (88 direct, 120 indirect) bytes in 1 blocks are definitely lost in loss record 35 of 41 | |||
==1478713== at 0x483BB1A: calloc (vg_replace_malloc.c:762) | |||
==1478713== by 0x48E35E8: qcalloc (memory.c:110) | |||
==1478713== by 0x451CCB: zebra_nhg_alloc (zebra_nhg.c:369) | |||
==1478713== by 0x453DE3: zebra_nhg_copy (zebra_nhg.c:379) | |||
==1478713== by 0x452670: nhg_ctx_process_new (zebra_nhg.c:1143) | |||
==1478713== by 0x4523A8: nhg_ctx_process (zebra_nhg.c:1234) | |||
==1478713== by 0x452A2D: zebra_nhg_kernel_find (zebra_nhg.c:1294) | |||
==1478713== by 0x4326E0: netlink_nexthop_change (rt_netlink.c:2433) | |||
==1478713== by 0x427320: netlink_parse_info (kernel_netlink.c:945) | |||
==1478713== by 0x432DAD: netlink_nexthop_read (rt_netlink.c:2488) | |||
==1478713== by 0x41B600: interface_list (if_netlink.c:1486) | |||
==1478713== by 0x457275: zebra_ns_enable (zebra_ns.c:127) | |||
Repro with: | |||
ip next add id 1 blackhole | |||
ip next add id 2 blackhole | |||
valgrind /usr/lib/frr/zebra | |||
Signed-off-by: Stephen Worley <sworley@cumulusnetworks.com> | |||
(cherry picked from commit c25c3ea57a3dcd3b36d86ba76dd34961bcb662f0) | |||
--- | |||
zebra/zebra_router.c | 7 ++++--- | |||
1 file changed, 4 insertions(+), 3 deletions(-) | |||
diff --git a/zebra/zebra_router.c b/zebra/zebra_router.c | |||
index a891ffb76a..ea2b6752b3 100644 | |||
--- a/zebra/zebra_router.c | |||
+++ b/zebra/zebra_router.c | |||
@@ -223,10 +223,11 @@ void zebra_router_terminate(void) | |||
zebra_vxlan_disable(); | |||
zebra_mlag_terminate(); | |||
- hash_clean(zrouter.nhgs, zebra_nhg_hash_free); | |||
- hash_free(zrouter.nhgs); | |||
- hash_clean(zrouter.nhgs_id, NULL); | |||
+ /* Free NHE in ID table only since it has unhashable entries as well */ | |||
+ hash_clean(zrouter.nhgs_id, zebra_nhg_hash_free); | |||
hash_free(zrouter.nhgs_id); | |||
+ hash_clean(zrouter.nhgs, NULL); | |||
+ hash_free(zrouter.nhgs); | |||
hash_clean(zrouter.rules_hash, zebra_pbr_rules_free); | |||
hash_free(zrouter.rules_hash); |
@ -0,0 +1,83 @@ | |||
From 21d5b651bbc4bcad3656a1804692c70e32797c69 Mon Sep 17 00:00:00 2001 | |||
From: David Lamparter <equinox@diac24.net> | |||
Date: Thu, 2 Apr 2020 21:16:04 +0200 | |||
Subject: [PATCH] bgpd, ospfd, ospf6d: long is not bool :( | |||
... Oops ... | |||
(for context, the defaults code originally didn't have a dedicated | |||
"bool" variant and just used long for bools... I derp'd this when | |||
adding bool as a separate case :( ) | |||
Reported-by: Donald Sharp <sharpd@cumulusnetworks.com> | |||
Signed-off-by: David Lamparter <equinox@diac24.net> | |||
(cherry picked from commit 4c1458b595282bff6a6e0b20767bb5cb655d0b4c) | |||
--- | |||
bgpd/bgp_vty.c | 16 ++++++++-------- | |||
ospf6d/ospf6_top.c | 4 ++-- | |||
ospfd/ospf_vty.c | 4 ++-- | |||
3 files changed, 12 insertions(+), 12 deletions(-) | |||
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c | |||
index 243822206c..4f5ba285aa 100644 | |||
--- a/bgpd/bgp_vty.c | |||
+++ b/bgpd/bgp_vty.c | |||
@@ -73,20 +73,20 @@ | |||
#endif | |||
FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
FRR_CFG_DEFAULT_BOOL(BGP_SHOW_HOSTNAME, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
FRR_CFG_DEFAULT_BOOL(BGP_LOG_NEIGHBOR_CHANGES, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
FRR_CFG_DEFAULT_BOOL(BGP_DETERMINISTIC_MED, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY, | |||
{ .val_ulong = 10, .match_profile = "datacenter", }, | |||
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c | |||
index 95537eb86e..ba3c1b8907 100644 | |||
--- a/ospf6d/ospf6_top.c | |||
+++ b/ospf6d/ospf6_top.c | |||
@@ -52,8 +52,8 @@ | |||
DEFINE_QOBJ_TYPE(ospf6) | |||
FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
/* global ospf6d variable */ | |||
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c | |||
index 152a7e83b7..92c9191801 100644 | |||
--- a/ospfd/ospf_vty.c | |||
+++ b/ospfd/ospf_vty.c | |||
@@ -54,8 +54,8 @@ | |||
#include "ospfd/ospf_bfd.h" | |||
FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES, | |||
- { .val_long = true, .match_profile = "datacenter", }, | |||
- { .val_long = false }, | |||
+ { .val_bool = true, .match_profile = "datacenter", }, | |||
+ { .val_bool = false }, | |||
) | |||
static const char *const ospf_network_type_str[] = { |
@ -0,0 +1,14 @@ | |||
--- a/lib/northbound.h | |||
+++ b/lib/northbound.h | |||
@@ -504,11 +504,7 @@ struct frr_yang_module_info { | |||
/* Priority - lower priorities are processed first. */ | |||
uint32_t priority; | |||
-#if defined(__GNUC__) && ((__GNUC__ - 0) < 5) && !defined(__clang__) | |||
} nodes[YANG_MODULE_MAX_NODES + 1]; | |||
-#else | |||
- } nodes[]; | |||
-#endif | |||
}; | |||
/* Northbound error codes. */ |