Browse Source

frr: makefile cleanup and misc fixes

fix mips runtime by backporting some yang changes from master
added commited fixes to 7.3
also add option for snmp support

Signed-off-by: Lucian Cristian <lucian.cristian@gmail.com>
lilik-openwrt-22.03
Lucian Cristian 5 years ago
parent
commit
7d2c647f2d
17 changed files with 7369 additions and 48 deletions
  1. +14
    -0
      net/frr/Config.in
  2. +42
    -48
      net/frr/Makefile
  3. +7
    -0
      net/frr/files/vtysh.conf
  4. +385
    -0
      net/frr/patches/010-add_yahng_filter.patch
  5. +390
    -0
      net/frr/patches/010-add_yang_routemap.patch
  6. +5045
    -0
      net/frr/patches/011-mod_yang_routemap_model.patch
  7. +83
    -0
      net/frr/patches/012-add_yang_filter.patch
  8. +147
    -0
      net/frr/patches/013-backport_northbound.patch
  9. +330
    -0
      net/frr/patches/014-backport_northbound.patch
  10. +33
    -0
      net/frr/patches/020-7.3_backports.patch
  11. +218
    -0
      net/frr/patches/021-7.3_backports.patch
  12. +177
    -0
      net/frr/patches/022-7.3_backports.patch
  13. +166
    -0
      net/frr/patches/023-7.3_backports.patch
  14. +174
    -0
      net/frr/patches/024-7.3_backports.patch
  15. +61
    -0
      net/frr/patches/025-7.3_backports.patch
  16. +83
    -0
      net/frr/patches/026-7.3_backports.patch
  17. +14
    -0
      net/frr/patches/098-fix_mips_libyang.patch

+ 14
- 0
net/frr/Config.in View File

@ -13,6 +13,20 @@ choice
bool "internal SSL support"
endchoice
comment "SNMP support"
choice
prompt "Enable SNMP support"
default FRR_NO_SNMP
config FRR_SNMP
bool "SNMP enable"
config FRR_NO_SNMP
bool "SNMP disable"
endchoice
comment "Packages"
endif

+ 42
- 48
net/frr/Makefile View File

@ -8,13 +8,15 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=frr
PKG_VERSION:=7.3
PKG_RELEASE:=2
PKG_RELEASE:=3
PKG_SOURCE_URL:=https://github.com/FRRouting/frr/releases/download/$(PKG_NAME)-$(PKG_VERSION)/
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
PKG_HASH:=529e1bbc3a20d55e94c38a95513bcf971d4b403ecb00afdaf0c229e3f560b2b6
PKG_MAINTAINER:=Lucian Cristian <lucian.cristian@gmail.com>
PKG_LICENSE:=GPL-2.0-only LGPL-2.1-only
PKG_DAEMON_AVAILABLE:= \
babeld \
bfdd \
@ -38,15 +40,20 @@ PKG_CONFIG_DEPENDS:= \
CONFIG_IPV6 \
CONFIG_FRR_OPENSSL \
CONFIG_FRR_INTERNAL \
CONFIG_FRR_SNMP \
CONFIG_FRR_NO_SNMP \
CONFIG_PACKAGE_frr-libfrr \
CONFIG_PACKAGE_frr-vtysh \
CONFIG_PACKAGE_frr-watchfrr \
CONFIG_PACKAGE_frr-zebra \
$(patsubst %,CONFIG_PACKAGE_frr-%,$(PKG_DAEMON_AVAILABLE)) \
PKG_FIXUP:=autoreconf
PKG_BUILD_PARALLEL:=1
PKG_BUILD_DEPENDS:=python3/host
PKG_LICENSE:=GPL-2.0
PKG_INSTALL:=1
PKG_BUILD_DEPENDS:=frr/host
HOST_BUILD_DEPENDS:=python3/host
include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/host-build.mk
@ -82,7 +89,7 @@ endef
define Package/frr-libfrr
$(call Package/frr/Default)
TITLE:=zebra library
DEPENDS+=+librt +libatomic +libjson-c +libyang +FRR_OPENSSL:libopenssl
DEPENDS+=+librt +libatomic +libcap +libjson-c +libyang +FRR_OPENSSL:libopenssl +FRR_SNMP:libnetsnmp
CONFLICTS:=quagga-libzebra
endef
@ -128,98 +135,85 @@ define BuildDaemon
define Package/frr-$(1)/install
$(INSTALL_DIR) $$(1)/usr/sbin
if [ "$(1)" != "fabricd" ]; then \
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/$(1)/.libs/$(1) $$(1)/usr/sbin/; \
else \
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/isisd/.libs/$(1) $$(1)/usr/sbin/; fi
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/$(1) $$(1)/usr/sbin/; \
if [ "$(1)" == "nhrpd" ]; then \
$(INSTALL_DIR) $$(1)/usr/lib; \
$(CP) $(PKG_BUILD_DIR)/build/lib/.libs/libfrrcares.so* $$(1)/usr/lib/; fi
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfrrcares.so* $$(1)/usr/lib/; fi
endef
$$(eval $$(call BuildPackage,frr-$(1)))
endef
define Package/frr-libfrr/conffiles
/etc/frr/
/etc/frr/daemons
/etc/frr/frr.conf
/etc/frr/vtysh.conf
endef
TARGET_LDFLAGS += -Wl,--gc-sections,--as-needed -latomic
TARGET_CFLAGS += -flto
define Host/Configure
$(Host/Configure/Default)
$(SED) 's/$$$$(MAKE) $$$$(AM_MAKEFLAGS) install-am/# $$$$(MAKE) $$$$(AM_MAKEFLAGS) install-am/' $(HOST_BUILD_DIR)/Makefile.in
endef
TARGET_LDFLAGS += -latomic
HOST_CONFIGURE_ARGS+= \
--enable-clippy-only
define Build/Prepare
$(Build/Prepare/Default)
mkdir -p $(PKG_BUILD_DIR)/build
define Host/Install
$(INSTALL_DIR) $(STAGING_DIR_HOSTPKG)/bin
$(INSTALL_BIN) $(HOST_BUILD_DIR)/lib/clippy $(STAGING_DIR_HOSTPKG)/bin/
endef
define Build/Configure
( cd $(PKG_BUILD_DIR)/build/ ; \
../configure \
--host="$(GNU_TARGET_NAME)" \
--build="$(GNU_HOST_NAME)" \
CFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
CXXFLAGS="$(TARGET_CFLAGS) $(EXTRA_CFLAGS)" \
LDFLAGS="$(TARGET_LDFLAGS) $(EXTRA_LDFLAGS)" \
HOST_CFLAGS="$(HOST_CFLAGS)" \
HOST_LDFLAGS="$(HOST_LDFLAGS)" \
BUILD_CPPFLAGS="$(TARGET_CPPLAGS)" \
BUILD_CFLAGS="$(TARGET_CFLAGS)" \
BUILD_LDFLAGS="$(TARGET_LDFLAGS)" \
CONFIGURE_ARGS+= \
--with-clippy=$(STAGING_DIR_HOSTPKG)/bin/clippy \
--prefix=/usr \
--enable-shared \
--disable-static \
--enable-user=network \
--enable-group=network \
--enable-multipath=16 \
--disable-capabilities \
--disable-ospfclient \
--disable-doc \
--disable-backtrace \
--localstatedir=/var/run/frr \
--sysconfdir=/etc/frr/ \
$(if $(CONFIG_FRR_OPENSSL),--with-crypto=openssl,) \
$(if $(CONFIG_FRR_SNMP),--enable-snmp,) \
$(foreach m,$(PKG_DAEMON_AVAILABLE), \
$(call autoconf_bool,CONFIG_PACKAGE_frr-$(m),$(m)) ) \
$(call autoconf_bool,CONFIG_PACKAGE_frr-vtysh,vtysh) \
$(call autoconf_bool,CONFIG_PACKAGE_frr-libfrr,zebra) \
)
endef
# just speed it up
NUM_CORES ?= $(shell grep -c "vendor_id" /proc/cpuinfo)
$(call autoconf_bool,CONFIG_PACKAGE_frr-libfrr,zebra)
define Build/Compile
$(MAKE) -C $(PKG_BUILD_DIR)/build -j$(NUM_CORES)
endef
define Package/frr/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d
$(INSTALL_BIN) ./files/frrcommon.sh $(1)/usr/sbin/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/frr $(1)/etc/init.d/
endef
define Package/frr-watchfrr/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) ./files/watchfrr.sh $(1)/usr/sbin/
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/watchfrr/.libs/watchfrr $(1)/usr/sbin/
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/watchfrr $(1)/usr/sbin/
endef
define Package/frr-zebra/install
$(INSTALL_DIR) $(1)/usr/sbin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/zebra/.libs/zebra $(1)/usr/sbin/
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/zebra $(1)/usr/sbin/
endef
define Package/frr-libfrr/install
$(INSTALL_DIR) $(1)/usr/lib
$(CP) $(PKG_BUILD_DIR)/build/lib/.libs/libfrr.so* $(1)/usr/lib/
$(INSTALL_DIR) $(1)/etc/frr
chmod 0750 $(1)/etc/frr
$(INSTALL_DIR) $(1)/usr/lib $(1)/etc/frr
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfrr.so* $(1)/usr/lib/
$(if $(CONFIG_FRR_SNMP),$(CP) $(PKG_INSTALL_DIR)/usr/lib/libfrrsnmp.so* $(1)/usr/lib/,)
$(INSTALL_CONF) ./files/{frr.conf,daemons} $(1)/etc/frr/
endef
define Package/frr-vtysh/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/build/vtysh/.libs/vtysh $(1)/usr/bin/
$(INSTALL_DIR) $(1)/usr/bin $(1)/etc/frr
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/vtysh $(1)/usr/bin/
$(INSTALL_CONF) ./files/vtysh.conf $(1)/etc/frr/
endef
$(eval $(call HostBuild))


+ 7
- 0
net/frr/files/vtysh.conf View File

@ -0,0 +1,7 @@
!
! Sample configuration file for vtysh.
!
!service integrated-vtysh-config
!hostname quagga-router
!username root nopassword
!

+ 385
- 0
net/frr/patches/010-add_yahng_filter.patch View File

@ -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;
+ }
+ }
+ }
+ }
+ }
+}

+ 390
- 0
net/frr/patches/010-add_yang_routemap.patch View File

@ -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";
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}

+ 5045
- 0
net/frr/patches/011-mod_yang_routemap_model.patch
File diff suppressed because it is too large
View File


+ 83
- 0
net/frr/patches/012-add_yang_filter.patch View File

@ -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;
}
}
}

+ 147
- 0
net/frr/patches/013-backport_northbound.patch View File

@ -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 = {
{

+ 330
- 0
net/frr/patches/014-backport_northbound.patch View File

@ -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);

+ 33
- 0
net/frr/patches/020-7.3_backports.patch View File

@ -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 */

+ 218
- 0
net/frr/patches/021-7.3_backports.patch View File

@ -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));

+ 177
- 0
net/frr/patches/022-7.3_backports.patch View File

@ -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);

+ 166
- 0
net/frr/patches/023-7.3_backports.patch View File

@ -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.";

+ 174
- 0
net/frr/patches/024-7.3_backports.patch View File

@ -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;
}

+ 61
- 0
net/frr/patches/025-7.3_backports.patch View File

@ -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);

+ 83
- 0
net/frr/patches/026-7.3_backports.patch View File

@ -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[] = {

+ 14
- 0
net/frr/patches/098-fix_mips_libyang.patch View File

@ -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. */

Loading…
Cancel
Save