summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--alpine/APKBUILD.in3
-rw-r--r--bgpd/bgp_evpn.c7
-rw-r--r--bgpd/bgp_label.c4
-rw-r--r--bgpd/bgp_mplsvpn.c14
-rw-r--r--bgpd/bgp_route.c4
-rw-r--r--bgpd/bgp_rpki.c2
-rw-r--r--bgpd/bgp_zebra.c12
-rw-r--r--debianpkg/README.deb_build.md13
-rwxr-xr-xdebianpkg/backports/ubuntu12.04/debian/rules4
-rwxr-xr-xdebianpkg/backports/ubuntu14.04/debian/rules27
-rw-r--r--debianpkg/frr.install5
-rwxr-xr-xdebianpkg/rules27
-rw-r--r--doc/Makefile.am1
-rw-r--r--doc/developer/Building_FRR_on_Alpine.rst47
-rw-r--r--doc/developer/building.rst1
-rw-r--r--doc/manpages/vtysh.rst14
-rw-r--r--doc/user/bgp.rst134
-rw-r--r--docker/.gitignore2
-rw-r--r--docker/alpine/Dockerfile30
-rwxr-xr-xdocker/alpine/alpine-build.sh11
-rwxr-xr-xdocker/alpine/build.sh21
-rw-r--r--docker/alpine/builder1
-rw-r--r--isisd/isis_bpf.c29
-rw-r--r--isisd/isis_pdu.c4
-rw-r--r--isisd/isis_pdu.h2
-rw-r--r--lib/zclient.c10
-rw-r--r--pimd/pim_igmp_mtrace.c4
-rw-r--r--redhat/README.rpm_build.md5
-rw-r--r--redhat/frr.spec.in15
-rw-r--r--sharpd/sharp_vty.c42
-rw-r--r--sharpd/sharp_zebra.c60
-rw-r--r--sharpd/sharp_zebra.h1
-rwxr-xr-xtools/checkpatch.pl24
-rwxr-xr-xtools/checkpatch.sh29
-rwxr-xr-xtools/frr-reload7
-rw-r--r--tools/frr.service2
-rw-r--r--tools/subdir.am2
-rw-r--r--zebra/main.c3
-rw-r--r--zebra/redistribute.c3
-rw-r--r--zebra/rib.h59
-rw-r--r--zebra/zebra_mpls.c38
-rw-r--r--zebra/zebra_netns_id.c1
-rw-r--r--zebra/zebra_ns.c26
-rw-r--r--zebra/zebra_ns.h3
-rw-r--r--zebra/zebra_pbr.c19
-rw-r--r--zebra/zebra_pbr.h3
-rw-r--r--zebra/zebra_rib.c45
-rw-r--r--zebra/zebra_rnh.c38
-rw-r--r--zebra/zebra_vty.c75
-rw-r--r--zebra/zserv.c21
50 files changed, 743 insertions, 211 deletions
diff --git a/alpine/APKBUILD.in b/alpine/APKBUILD.in
index 33c2859245..2b211ccafd 100644
--- a/alpine/APKBUILD.in
+++ b/alpine/APKBUILD.in
@@ -18,7 +18,8 @@ makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1
mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base
patch pax-utils pcre perl pkgconf python2 python2-dev readline
- readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs"
+ readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs
+ py-sphinx"
subpackages="$pkgname-dev $pkgname-doc $pkgname-dbg"
source="$pkgname-$pkgver.tar.gz"
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 94d9cb465b..b3d6f388b9 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -3754,13 +3754,6 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
u_char rlen;
struct prefix p;
- /* Check peer status. */
- if (peer->status != Established) {
- zlog_err("%u:%s - EVPN update received in state %d",
- peer->bgp->vrf_id, peer->host, peer->status);
- return -1;
- }
-
/* Start processing the NLRI - there may be multiple in the MP_REACH */
pnt = packet->nlri;
lim = pnt + packet->length;
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 38b39075be..546ed0ed68 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -212,10 +212,6 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
mpls_label_t label = MPLS_INVALID_LABEL;
u_char llen;
- /* Check peer status. */
- if (peer->status != Established)
- return 0;
-
pnt = packet->nlri;
lim = pnt + packet->length;
afi = packet->afi;
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 04dc60621e..5ed43e4bd9 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -109,10 +109,6 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
int addpath_encoded;
u_int32_t addpath_id;
- /* Check peer status. */
- if (peer->status != Established)
- return 0;
-
/* Make prefix_rd */
prd.family = AF_UNSPEC;
prd.prefixlen = 64;
@@ -627,14 +623,12 @@ void vpn_leak_from_vrf_update(struct bgp *bgp_vpn, /* to */
&static_attr); /* hashed refcounted everything */
bgp_attr_flush(&static_attr); /* free locally-allocated parts */
- if (debug) {
- const char *s = "";
+ if (debug && new_attr->ecommunity) {
+ char *s = ecommunity_ecom2str(new_attr->ecommunity,
+ ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- if (new_attr->ecommunity) {
- s = ecommunity_ecom2str(new_attr->ecommunity,
- ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- }
zlog_debug("%s: new_attr->ecommunity{%s}", __func__, s);
+ XFREE(MTYPE_ECOMMUNITY_STR, s);
}
/* Now new_attr is an allocated interned attr */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 032b33229c..35732d1bf5 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4060,10 +4060,6 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
int addpath_encoded;
u_int32_t addpath_id;
- /* Check peer status. */
- if (peer->status != Established)
- return 0;
-
pnt = packet->nlri;
lim = pnt + packet->length;
afi = packet->afi;
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 1fb5bf19f1..7c9a134b0f 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -730,7 +730,7 @@ DEFPY (rpki_expire_interval,
"Set expire interval\n"
"Expire interval value\n")
{
- if (tmp >= polling_period) {
+ if ((unsigned int)tmp >= polling_period) {
expire_interval = tmp;
return CMD_SUCCESS;
}
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index 97b4c916d7..486ea3937a 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1078,8 +1078,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
continue;
api_nh = &api.nexthops[valid_nh_count];
- api_nh->vrf_id = bgp->vrf_id;
-
+ api_nh->vrf_id = nh_othervrf ? info->extra->bgp_orig->vrf_id
+ : bgp->vrf_id;
if (nh_family == AF_INET) {
struct in_addr *nexthop;
@@ -1129,11 +1129,8 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
}
nexthop = &mpinfo_cp->attr->nexthop;
-
api_nh->gate.ipv4 = *nexthop;
- api_nh->vrf_id = nh_othervrf
- ? info->extra->bgp_orig->vrf_id
- : bgp->vrf_id;
+
/* EVPN type-2 routes are
programmed as onlink on l3-vni SVI
*/
@@ -1206,9 +1203,6 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
api_nh->gate.ipv6 = *nexthop;
api_nh->ifindex = ifindex;
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
- /* api_nh->vrf_id is not set for normal case? */
- if (nh_othervrf)
- api_nh->vrf_id = info->extra->bgp_orig->vrf_id;
}
if (mpinfo->extra
diff --git a/debianpkg/README.deb_build.md b/debianpkg/README.deb_build.md
index 889e831744..8ccce93f55 100644
--- a/debianpkg/README.deb_build.md
+++ b/debianpkg/README.deb_build.md
@@ -71,10 +71,15 @@ adding a new backport.
Or change some options:
(see `rules` file for available options)
- export WANT_BGP_VNC=1
- export WANT_CUMULUS_MODE=1
- debuild -b -uc -us
-
+ debuild --set-envvar=WANT_BGP_VNC=1 --set-envvar=WANT_CUMULUS_MODE=1 -b -uc -us
+
+ To build with RPKI, download the librtr packages from
+ https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
+ install librtr-dev on the build server and build the packages as
+ debuild --set-envvar=WANT_RPKI=1 -b -uc -us
+ RPKI packages have an additonal dependency of librtr0 which can be
+ found at the same URL
+
DONE.
If all works correctly, then you should end up with the Debian packages under
diff --git a/debianpkg/backports/ubuntu12.04/debian/rules b/debianpkg/backports/ubuntu12.04/debian/rules
index 9a3ea1ffbd..01ad81d371 100755
--- a/debianpkg/backports/ubuntu12.04/debian/rules
+++ b/debianpkg/backports/ubuntu12.04/debian/rules
@@ -16,8 +16,10 @@ WANT_CUMULUS_MODE ?= 0
WANT_MULTIPATH ?= 1
WANT_SNMP ?= 0
+# NOTES:
+#
# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
-# Please be aware that 0 is NOT disabled, but treated as unlimited
+# Please be aware that 0 is NOT disabled, but treated as unlimited
MULTIPATH ?= 256
diff --git a/debianpkg/backports/ubuntu14.04/debian/rules b/debianpkg/backports/ubuntu14.04/debian/rules
index 20b821ead7..f7b9428658 100755
--- a/debianpkg/backports/ubuntu14.04/debian/rules
+++ b/debianpkg/backports/ubuntu14.04/debian/rules
@@ -15,9 +15,20 @@ WANT_BGP_VNC ?= 1
WANT_CUMULUS_MODE ?= 0
WANT_MULTIPATH ?= 1
WANT_SNMP ?= 0
+WANT_RPKI ?= 0
+# NOTES:
+#
+# If you use WANT_RPKI, then there is a new dependency for librtr0 package
+# and a build dependency of the librtr-dev package.
+# While the librtr0 is added to the depenencies automatically, the build
+# dependency can't be changed dynamically and building will fail if the
+# librtr-dev isn't installed during package build
+# Tested versions of both packages can be found at
+# https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
+#
# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
-# Please be aware that 0 is NOT disabled, but treated as unlimited
+# Please be aware that 0 is NOT disabled, but treated as unlimited
MULTIPATH ?= 256
@@ -91,6 +102,12 @@ else
USE_CUMULUS=--enable-cumulus=no
endif
+ifeq ($(WANT_RPKI), 1)
+ USE_RPKI=--enable-rpki
+else
+ USE_RPKI=--disable-rpki
+endif
+
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
endif
@@ -102,6 +119,13 @@ endif
%:
dh $@ --with=autoreconf --parallel --dbg-package=frr-dbg --list-missing
+override_dh_gencontrol:
+ifeq ($(WANT_RPKI), 1)
+ dh_gencontrol -- -Vdist:Depends="librtr0 (>= 0.5)"
+else
+ dh_gencontrol
+endif
+
override_dh_auto_configure:
# Frr needs /proc to check some BSD vs Linux specific stuff.
# Else it fails with an obscure error message pointing out that
@@ -134,6 +158,7 @@ override_dh_auto_configure:
$(USE_PIM) \
--enable-dependency-tracking \
$(USE_BGP_VNC) \
+ $(USE_RPKI) \
$(shell dpkg-buildflags --export=configure); \
fi
diff --git a/debianpkg/frr.install b/debianpkg/frr.install
index 8d12662702..20a58bb0e9 100644
--- a/debianpkg/frr.install
+++ b/debianpkg/frr.install
@@ -7,5 +7,6 @@ tools/frr usr/lib/frr
usr/share/doc/frr/
usr/share/snmp/mibs/
tools/etc/* etc/
-tools/*.service lib/systemd/system
-debian/frr.conf usr/lib/tmpfiles.d
+tools/*.service lib/systemd/system
+tools/frr-reload usr/lib/frr/
+debian/frr.conf usr/lib/tmpfiles.d
diff --git a/debianpkg/rules b/debianpkg/rules
index 82a5148039..0f2f4ebe16 100755
--- a/debianpkg/rules
+++ b/debianpkg/rules
@@ -15,9 +15,20 @@ WANT_BGP_VNC ?= 1
WANT_CUMULUS_MODE ?= 0
WANT_MULTIPATH ?= 1
WANT_SNMP ?= 0
+WANT_RPKI ?= 0
+# NOTES:
+#
+# If you use WANT_RPKI, then there is a new dependency for librtr0 package
+# and a build dependency of the librtr-dev package.
+# While the librtr0 is added to the depenencies automatically, the build
+# dependency can't be changed dynamically and building will fail if the
+# librtr-dev isn't installed during package build
+# Tested versions of both packages can be found at
+# https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
+#
# If multipath is enabled (WANT_MULTIPATH=1), then set number of multipaths here
-# Please be aware that 0 is NOT disabled, but treated as unlimited
+# Please be aware that 0 is NOT disabled, but treated as unlimited
MULTIPATH ?= 256
@@ -91,6 +102,12 @@ else
USE_CUMULUS=--enable-cumulus=no
endif
+ifeq ($(WANT_RPKI), 1)
+ USE_RPKI=--enable-rpki
+else
+ USE_RPKI=--disable-rpki
+endif
+
ifneq (,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
DEBIAN_JOBS := $(subst parallel=,,$(filter parallel=%,$(DEB_BUILD_OPTIONS)))
endif
@@ -102,6 +119,13 @@ endif
%:
dh $@ --with=systemd,autoreconf --parallel --dbg-package=frr-dbg --list-missing
+override_dh_gencontrol:
+ifeq ($(WANT_RPKI), 1)
+ dh_gencontrol -- -Vdist:Depends="librtr0 (>= 0.5)"
+else
+ dh_gencontrol
+endif
+
override_dh_auto_configure:
# Frr needs /proc to check some BSD vs Linux specific stuff.
# Else it fails with an obscure error message pointing out that
@@ -135,6 +159,7 @@ override_dh_auto_configure:
$(USE_PIM) \
--enable-dependency-tracking \
$(USE_BGP_VNC) \
+ $(USE_RPKI) \
$(shell dpkg-buildflags --export=configure); \
fi
diff --git a/doc/Makefile.am b/doc/Makefile.am
index aeabc0981d..8d35d4540b 100644
--- a/doc/Makefile.am
+++ b/doc/Makefile.am
@@ -179,6 +179,7 @@ EXTRA_DIST = frr-sphinx.mk \
developer/OSPF-API.md \
developer/workflow.rst \
developer/Building_FRR_on_Ubuntu1404.rst \
+ developer/Building_FRR_on_Alpine.rst \
user/ospf_fundamentals.rst \
user/routemap.rst \
user/index.rst \
diff --git a/doc/developer/Building_FRR_on_Alpine.rst b/doc/developer/Building_FRR_on_Alpine.rst
new file mode 100644
index 0000000000..27718bdc80
--- /dev/null
+++ b/doc/developer/Building_FRR_on_Alpine.rst
@@ -0,0 +1,47 @@
+Building FRR dev packages on Alpine Linux from Git Source
+=========================================================
+
+For building Alpine Linux dev packages, we use docker.
+
+Install docker 17.05 or later
+-----------------------------
+
+Depending on your host, there are different ways of installing
+docker. Refer to the documentation here for instructions on how
+to install a free version of docker: https://www.docker.com/community-edition
+
+Work with sources
+-----------------
+
+ git clone https://github.com/frrouting/frr.git frr
+ cd frr
+
+Build apk packages
+------------------
+
+ ./docker/alpine/build.sh
+
+This will put the apk packages in:
+
+ ./docker/pkgs/apk/x86_64/
+
+Usage
+-----
+
+To add the packages to a docker image, create a Dockerfile in ./docker/pkgs:
+
+ FROM alpine:3.7
+ RUN mkdir -p /pkgs
+ ADD apk/ /pkgs/
+ RUN apk add --no-cache --allow-untrusted /pkgs/x86_64/*.apk
+
+And build a docker image:
+
+ docker build --rm --force-rm -t alpine-dev-pkgs:latest docker/pkgs
+
+And run the image:
+
+ docker run -it --rm alpine-dev-pkgs:latest /bin/sh
+
+Currently, we only package the raw daemons and example files, so, you'll
+need to run the daemons by hand (or, better, orchestrate in the Dockerfile).
diff --git a/doc/developer/building.rst b/doc/developer/building.rst
index 4715bca532..e56744ad87 100644
--- a/doc/developer/building.rst
+++ b/doc/developer/building.rst
@@ -5,6 +5,7 @@ Building FRR
:maxdepth: 2
Building_FRR_on_LEDE-OpenWRT
+ Building_FRR_on_Alpine
Building_FRR_on_CentOS6
Building_FRR_on_CentOS7
Building_FRR_on_Debian8
diff --git a/doc/manpages/vtysh.rst b/doc/manpages/vtysh.rst
index 38cb668e82..2db746020d 100644
--- a/doc/manpages/vtysh.rst
+++ b/doc/manpages/vtysh.rst
@@ -3,7 +3,7 @@ VTYSH
*****
.. include:: defines.rst
-.. |DAEMON| replace:: eigrpd
+.. |DAEMON| replace:: vtysh
SYNOPSIS
========
@@ -41,6 +41,18 @@ OPTIONS available for the vtysh command:
When the -c option is being used, this flag will cause the standard vtysh prompt and command to be echoed prior to displaying the results. This is particularly useful to separate the results when executing multiple commands.
+.. option:: -C, --dryrun
+
+ When the -C option is being used, this flag will check the config for syntatic validity.
+
+.. option:: -m, --markfile
+
+ Mark the input file with context ends, useful for cleanup of a config file that has a lot of extraneous space and end markers
+
+.. option:: -n, --noerror
+
+ When executing cli that does not invoke a vtysh shell, if an error ocurrs ignore it for purposes of return codes from vtysh.
+
.. option:: -h, --help
Display a usage message on standard output and exit.
diff --git a/doc/user/bgp.rst b/doc/user/bgp.rst
index 0cc2c511c3..b5ee632271 100644
--- a/doc/user/bgp.rst
+++ b/doc/user/bgp.rst
@@ -1529,6 +1529,140 @@ BGP Large Communities in Route Map
large-community list. The third will add a large-community value without
overwriting other values. Multiple large-community values can be specified.
+
+.. _bgp-vrfs:
+
+BGP VRFs
+========
+
+Bgpd supports multiple VRF instances via the *router bgp* command:
+
+.. index:: router bgp ASN vrf VRFNAME
+.. clicmd:: router bgp ASN vrf VRFNAME
+
+VRFNAME is matched against VRFs configured in the kernel. When no
+*vrf VRFNAME* is specified, the BGP protocol process belongs to
+the default VRF.
+
+BGP routes may be leaked (i.e., copied) between a unicast VRF RIB
+and the VPN safi RIB of the default VRF (leaking is also permitted
+between the unicast RIB of the default VRF and VPN). A common
+application of this feature is to connect a customer's private
+routing domain to a provider's VPN service. Leaking is configured
+from the point of view of an individual VRF: ``import`` refers to
+routes leaked from VPN to a unicast VRF, whereas ``export`` refers
+to routes leaked from a unicast VRF to VPN.
+
+Required Parameters
+-------------------
+
+Routes exported from a unicast VRF to the VPN RIB must be augmented
+by two parameters:
+a route-distinguisher (RD) and a route-target list (RTLIST).
+Configuration for these exported routes must, at a minimum, specify
+these two parameters.
+
+Routes imported from the VPN RIB to a unicast VRF are selected
+according to their RTLISTs.
+Routes whose RTLIST contains at least one route-target in common with
+the configured import RTLIST are leaked.
+Configuration for these imported routes must specify an RTLIST to be matched.
+
+The RD, which carries no semantic value, is intended to make the
+route unique in the VPN RIB among all routes of its prefix that
+originate from all the customers and sites that are attached
+to the provider's VPN service. Accordingly, each site of each customer
+is typically assigned an RD that is unique across the entire provider
+network.
+
+The RTLIST is a set of route-target extended community values whose
+purpose is to specify route-leaking policy. Typically, a customer
+is assigned a single route-target value for import and export to be
+used at all customer sites. This configuration specifies a simple
+topology wherein a customer has a single routing domain which is
+shared across all its sites. More complex routing topologies are possible
+through use of additional route-targets to augment the leaking of
+sets of routes in various ways.
+
+Configuration
+-------------
+
+Configuration of route leaking between a unicast VRF RIB and the
+VPN safi RIB of the default VRF is accomplished via commands in the
+context of a VRF address-family:
+
+.. index:: rd vpn export AS:NN|IP:nn
+.. clicmd:: rd vpn export AS:NN|IP:nn
+
+ Specifies the route distinguisher to be added to a route exported
+ from the current unicast VRF to VPN.
+
+.. index:: no rd vpn export [AS:NN|IP:nn]
+.. clicmd:: no rd vpn export [AS:NN|IP:nn]
+
+ Deletes any previously-configured export route distinguisher.
+
+.. index:: rt vpn import|export|both RTLIST...
+.. clicmd:: rt vpn import|export|both RTLIST...
+
+ Specifies the route-target list to be attached to a route (export)
+ or the route-target list to match against (import) when
+ exporting/importing between the current unicast VRF and VPN.
+
+ The RTLIST is a space-separated list of route-targets, which are
+ BGP extended community values as described in
+ :ref:`bgp-extended-communities-attribute`.
+
+.. index:: no rt vpn import|export|both [RTLIST...]
+.. clicmd:: no rt vpn import|export|both [RTLIST...]
+
+ Deletes any previously-configured import or export route-target list.
+
+.. index:: label vpn export (0..1048575)
+.. clicmd:: label vpn export (0..1048575)
+
+ Specifies an optional MPLS label to be attached to a route exported
+ from the current unicast VRF to VPN.
+
+.. index:: no label vpn export [(0..1048575)]
+.. clicmd:: no label vpn export [(0..1048575)]
+
+ Deletes any previously-configured export label.
+
+.. index:: nexthop vpn export A.B.C.D|X:X::X:X
+.. clicmd:: nexthop vpn export A.B.C.D|X:X::X:X
+
+ Specifies an optional nexthop value to be assigned to a route exported
+ from the current unicast VRF to VPN. If left unspecified, the nexthop
+ will be set to 0.0.0.0 or 0:0::0:0 (self).
+
+.. index:: no nexthop vpn export [A.B.C.D|X:X::X:X]
+.. clicmd:: no nexthop vpn export [A.B.C.D|X:X::X:X]
+
+ Deletes any previously-configured export nexthop.
+
+.. index:: route-map vpn import|export MAP
+.. clicmd:: route-map vpn import|export MAP
+
+ Specifies an optional route-map to be applied to routes imported
+ or exported betwen the current unicast VRF and VPN.
+
+.. index:: no route-map vpn import|export [MAP]
+.. clicmd:: no route-map vpn import|export [MAP]
+
+ Deletes any previously-configured import or export route-map.
+
+.. index:: import|export vpn
+.. clicmd:: import|export vpn
+
+ Enables import or export of routes betwen the current unicast VRF and VPN.
+
+.. index:: no import|export vpn
+.. clicmd:: no import|export vpn
+
+ Disables import or export of routes betwen the current unicast VRF and VPN.
+
+
.. _displaying-bgp-information:
Displaying BGP information
diff --git a/docker/.gitignore b/docker/.gitignore
new file mode 100644
index 0000000000..e9beab556e
--- /dev/null
+++ b/docker/.gitignore
@@ -0,0 +1,2 @@
+src.tar
+pkgs/
diff --git a/docker/alpine/Dockerfile b/docker/alpine/Dockerfile
new file mode 100644
index 0000000000..e186fdccdf
--- /dev/null
+++ b/docker/alpine/Dockerfile
@@ -0,0 +1,30 @@
+FROM alpine:3.7 as source-builder
+ARG commit
+RUN apk add --no-cache abuild acct alpine-sdk attr autoconf automake bash \
+ binutils binutils-libs bison bsd-compat-headers build-base \
+ c-ares c-ares-dev ca-certificates cryptsetup-libs curl \
+ device-mapper-libs expat fakeroot flex fortify-headers g++ gcc gdbm \
+ git gmp isl json-c json-c-dev kmod lddtree libacl libatomic libattr \
+ libblkid libburn libbz2 libc-dev libcap libcurl libedit libffi libgcc \
+ libgomp libisoburn libisofs libltdl libressl libssh2 \
+ libstdc++ libtool libuuid linux-headers lzip lzo m4 make mkinitfs mpc1 \
+ mpfr3 mtools musl-dev ncurses-libs ncurses-terminfo ncurses-terminfo-base \
+ patch pax-utils pcre perl pkgconf python2 python2-dev readline \
+ readline-dev sqlite-libs squashfs-tools sudo tar texinfo xorriso xz-libs \
+ groff gzip bc py-sphinx
+RUN mkdir -p /src
+ADD src.tar /src
+RUN (cd /src && \
+ ./bootstrap.sh && \
+ ./configure \
+ --enable-numeric-version \
+ --with-pkg-extra-version=_git$commit && \
+ make dist)
+FROM alpine:3.7 as alpine-builder
+RUN apk add --no-cache abuild alpine-sdk && mkdir -p /pkgs/apk
+ADD alpine-build.sh /usr/bin/
+ADD builder /etc/sudoers.d
+COPY --from=source-builder /src/*.tar.gz /src/alpine/APKBUILD /dist/
+RUN adduser -D -G abuild builder && chown -R builder /dist /pkgs
+USER builder
+RUN /usr/bin/alpine-build.sh
diff --git a/docker/alpine/alpine-build.sh b/docker/alpine/alpine-build.sh
new file mode 100755
index 0000000000..d4c0311122
--- /dev/null
+++ b/docker/alpine/alpine-build.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+set -e
+
+cd /dist
+
+sudo apk --update add alpine-conf
+sudo setup-apkcache /var/cache/apk
+abuild-keygen -a -n
+abuild checksum
+abuild -r -P /pkgs/apk
diff --git a/docker/alpine/build.sh b/docker/alpine/build.sh
new file mode 100755
index 0000000000..357ea12dee
--- /dev/null
+++ b/docker/alpine/build.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+set -e
+set -v
+set -x
+
+##
+# commit must be converted to decimal
+##
+c=`git rev-parse --short=10 HEAD`
+commit=`printf '%u\n' 0x$c`
+git archive --format=tar $c > docker/alpine/src.tar
+(cd docker/alpine && \
+ docker build --build-arg commit=$commit --rm --force-rm -t \
+ frr:alpine-$c . && \
+ rm -f src.tar)
+
+id=`docker create frr:alpine-$c`
+docker cp ${id}:/pkgs/ docker
+docker rm $id
+docker rmi frr:alpine-$c
diff --git a/docker/alpine/builder b/docker/alpine/builder
new file mode 100644
index 0000000000..a950b8abaf
--- /dev/null
+++ b/docker/alpine/builder
@@ -0,0 +1 @@
+builder ALL=(ALL) NOPASSWD:ALL
diff --git a/isisd/isis_bpf.c b/isisd/isis_bpf.c
index 0493c125bd..872bc5bc72 100644
--- a/isisd/isis_bpf.c
+++ b/isisd/isis_bpf.c
@@ -216,7 +216,8 @@ end:
int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa)
{
- int bytesread = 0, bytestoread, offset, one = 1;
+ int bytesread = 0, bytestoread, offset, one = 1, err = ISIS_OK;
+ u_char *buff_ptr;
struct bpf_hdr *bpf_hdr;
assert(circuit->fd > 0);
@@ -230,25 +231,33 @@ int isis_recv_pdu_bcast(struct isis_circuit *circuit, u_char *ssnpa)
}
if (bytesread < 0) {
zlog_warn("isis_recv_pdu_bcast(): read() failed: %s",
- safe_strerror(errno));
+ safe_strerror(errno));
return ISIS_WARNING;
}
if (bytesread == 0)
return ISIS_WARNING;
- bpf_hdr = (struct bpf_hdr *)readbuff;
+ buff_ptr = readbuff;
+ while (buff_ptr < readbuff + bytesread) {
+ bpf_hdr = (struct bpf_hdr *) buff_ptr;
+ assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
+ offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
- assert(bpf_hdr->bh_caplen == bpf_hdr->bh_datalen);
+ /* then we lose the BPF, LLC and ethernet headers */
+ stream_write(circuit->rcv_stream, buff_ptr + offset,
+ bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
+ stream_set_getp(circuit->rcv_stream, 0);
- offset = bpf_hdr->bh_hdrlen + LLC_LEN + ETHER_HDR_LEN;
+ memcpy(ssnpa, buff_ptr + bpf_hdr->bh_hdrlen + ETHER_ADDR_LEN,
+ ETHER_ADDR_LEN);
- /* then we lose the BPF, LLC and ethernet headers */
- stream_write(circuit->rcv_stream, readbuff + offset,
- bpf_hdr->bh_caplen - LLC_LEN - ETHER_HDR_LEN);
- stream_set_getp(circuit->rcv_stream, 0);
+ err = isis_handle_pdu(circuit, ssnpa);
+ stream_reset(circuit->rcv_stream);
+ buff_ptr += BPF_WORDALIGN(bpf_hdr->bh_hdrlen +
+ bpf_hdr->bh_datalen);
+ }
- memcpy(ssnpa, readbuff + bpf_hdr->bh_hdrlen + ETH_ALEN, ETH_ALEN);
if (ioctl(circuit->fd, BIOCFLUSH, &one) < 0)
zlog_warn("Flushing failed: %s", safe_strerror(errno));
diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c
index bcbda33088..ebcf197a37 100644
--- a/isisd/isis_pdu.c
+++ b/isisd/isis_pdu.c
@@ -1337,7 +1337,7 @@ static int pdu_size(uint8_t pdu_type, uint8_t *size)
* PDU Dispatcher
*/
-static int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa)
+int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa)
{
int retval = ISIS_OK;
@@ -1460,8 +1460,10 @@ int isis_receive(struct thread *thread)
retval = circuit->rx(circuit, ssnpa);
+#if ISIS_METHOD != ISIS_METHOD_BPF
if (retval == ISIS_OK)
retval = isis_handle_pdu(circuit, ssnpa);
+#endif //ISIS_METHOD != ISIS_METHOD_BPF
/*
* prepare for next packet.
diff --git a/isisd/isis_pdu.h b/isisd/isis_pdu.h
index 7096761879..2d9100c10b 100644
--- a/isisd/isis_pdu.h
+++ b/isisd/isis_pdu.h
@@ -215,5 +215,5 @@ int send_l2_psnp(struct thread *thread);
int send_lsp(struct thread *thread);
void fill_fixed_hdr(uint8_t pdu_type, struct stream *stream);
int send_hello(struct isis_circuit *circuit, int level);
-
+int isis_handle_pdu(struct isis_circuit *circuit, u_char *ssnpa);
#endif /* _ZEBRA_ISIS_PDU_H */
diff --git a/lib/zclient.c b/lib/zclient.c
index 777f6fcf9b..2cac71ac45 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -1340,6 +1340,16 @@ bool zapi_nexthop_update_decode(struct stream *s, struct zapi_route *nhr)
case NEXTHOP_TYPE_BLACKHOLE:
break;
}
+ STREAM_GETC(s, nhr->nexthops[i].label_num);
+ if (nhr->nexthops[i].label_num > MPLS_MAX_LABELS) {
+ zlog_warn("%s: invalid number of MPLS labels (%u)",
+ __func__, nhr->nexthops[i].label_num);
+ return false;
+ }
+ if (nhr->nexthops[i].label_num)
+ STREAM_GET(&nhr->nexthops[i].labels[0], s,
+ nhr->nexthops[i].label_num
+ * sizeof(mpls_label_t));
}
return true;
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index 5e2e316d85..9e59dc31b6 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -256,9 +256,11 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,
pim_socket_ip_hdr(fd);
if (interface == NULL) {
+ memset(&nexthop, 0, sizeof(nexthop));
ret = pim_nexthop_lookup(pim, &nexthop, ip_hdr->ip_dst, 0);
if (ret != 0) {
+ close(fd);
if (PIM_DEBUG_MTRACE)
zlog_warn(
"Dropping mtrace packet, "
@@ -434,6 +436,7 @@ static int mtrace_send_response(struct pim_instance *pim,
if (PIM_DEBUG_MTRACE)
zlog_debug("mtrace response to RP");
} else {
+ memset(&nexthop, 0, sizeof(nexthop));
/* TODO: should use unicast rib lookup */
ret = pim_nexthop_lookup(pim, &nexthop, mtracep->rsp_addr, 1);
@@ -613,6 +616,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
nh_addr.s_addr = 0;
+ memset(&nexthop, 0, sizeof(nexthop));
ret = pim_nexthop_lookup(pim, &nexthop, mtracep->src_addr, 1);
if (ret == 0) {
diff --git a/redhat/README.rpm_build.md b/redhat/README.rpm_build.md
index 7deea54de4..c461e543d2 100644
--- a/redhat/README.rpm_build.md
+++ b/redhat/README.rpm_build.md
@@ -63,11 +63,16 @@ Building your own FRRouting RPM
%{!?with_watchfrr: %global with_watchfrr 1 }
%{!?with_bgp_vnc: %global with_bgp_vnc 0 }
%{!?with_pimd: %global with_pimd 1 }
+ %{!?with_rpki: %global with_rpki 0 }
7. Build the RPM
rpmbuild --define "_topdir `pwd`/rpmbuild" -ba rpmbuild/SPECS/frr.spec
+ If building with RPKI, then download and install the additional RPKI
+ packages from
+ https://ci1.netdef.org/browse/RPKI-RTRLIB/latestSuccessful/artifact
+
DONE.
If all works correctly, then you should end up with the RPMs under
diff --git a/redhat/frr.spec.in b/redhat/frr.spec.in
index b4073f94f3..14fb910219 100644
--- a/redhat/frr.spec.in
+++ b/redhat/frr.spec.in
@@ -26,6 +26,7 @@
%{!?with_watchfrr: %global with_watchfrr 1 }
%{!?with_bgp_vnc: %global with_bgp_vnc 0 }
%{!?with_pimd: %global with_pimd 1 }
+%{!?with_rpki: %global with_rpki 0 }
# path defines
%define _sysconfdir /etc/frr
@@ -145,6 +146,7 @@ Requires(post): /sbin/install-info
BuildRequires: gcc patch libcap-devel
BuildRequires: readline readline-devel ncurses ncurses-devel
BuildRequires: json-c-devel bison >= 2.7 flex make
+BuildRequires: c-ares-devel texinfo
%if 0%{?rhel} && 0%{?rhel} < 7
#python27-devel is available from ius community repo for RedHat/CentOS 6
BuildRequires: python27-devel python27-sphinx
@@ -156,6 +158,10 @@ Requires: ncurses json-c initscripts
BuildRequires: pam-devel
Requires: pam
%endif
+%if %{with_rpki}
+BuildRequires: librtr-devel >= 0.5
+Requires: librtr >= 0.5
+%endif
%if "%{initsystem}" == "systemd"
BuildRequires: systemd systemd-devel
Requires(post): systemd
@@ -305,6 +311,9 @@ developing OSPF-API and frr applications.
--enable-systemd=yes \
%endif
--enable-poll=yes
+%if %{with_rpki}
+ --enable-rpki
+%endif
make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" SPHINXBUILD=%{sphinx}
@@ -572,6 +581,7 @@ rm -rf %{buildroot}
%endif
%config(noreplace) /etc/pam.d/frr
%config(noreplace) %attr(640,root,root) /etc/logrotate.d/*
+%{_sbindir}/frr-reload
%files contrib
%defattr(-,root,root)
@@ -604,7 +614,10 @@ rm -rf %{buildroot}
%endif
%changelog
-* Tue Feb 20 2018 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+* Sun Mar 4 2018 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+- Add option to build with RPKI (default: disabled)
+
+* Tue Feb 20 2018 Martin Winter <mwinter@opensourcerouting.org>
- Adapt to new documentation structure based on Sphinx
* Fri Oct 20 2017 Martin Winter <mwinter@opensourcerouting.org>
diff --git a/sharpd/sharp_vty.c b/sharpd/sharp_vty.c
index 3065ad19c3..4d19484a64 100644
--- a/sharpd/sharp_vty.c
+++ b/sharpd/sharp_vty.c
@@ -39,6 +39,46 @@ extern uint32_t total_routes;
extern uint32_t installed_routes;
extern uint32_t removed_routes;
+DEFPY(watch_nexthop_v6, watch_nexthop_v6_cmd,
+ "sharp watch nexthop X:X::X:X$nhop",
+ "Sharp routing Protocol\n"
+ "Watch for changes\n"
+ "Watch for nexthop changes\n"
+ "The v6 nexthop to signal for watching\n")
+{
+ struct prefix p;
+
+ memset(&p, 0, sizeof(p));
+
+ p.prefixlen = 128;
+ memcpy(&p.u.prefix6, &nhop, 16);
+ p.family = AF_INET6;
+
+ sharp_zebra_nexthop_watch(&p, true);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY(watch_nexthop_v4, watch_nexthop_v4_cmd,
+ "sharp watch nexthop A.B.C.D$nhop",
+ "Sharp routing Protocol\n"
+ "Watch for changes\n"
+ "Watch for nexthop changes\n"
+ "The v4 nexthop to signal for watching\n")
+{
+ struct prefix p;
+
+ memset(&p, 0, sizeof(p));
+
+ p.prefixlen = 32;
+ p.u.prefix4 = nhop;
+ p.family = AF_INET;
+
+ sharp_zebra_nexthop_watch(&p, true);
+
+ return CMD_SUCCESS;
+}
+
DEFPY (install_routes,
install_routes_cmd,
"sharp install routes A.B.C.D$start nexthop A.B.C.D$nexthop (1-1000000)$routes",
@@ -147,5 +187,7 @@ void sharp_vty_init(void)
install_element(ENABLE_NODE, &install_routes_cmd);
install_element(ENABLE_NODE, &remove_routes_cmd);
install_element(ENABLE_NODE, &vrf_label_cmd);
+ install_element(ENABLE_NODE, &watch_nexthop_v6_cmd);
+ install_element(ENABLE_NODE, &watch_nexthop_v4_cmd);
return;
}
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 8915397c7e..999255e925 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -214,6 +214,65 @@ void route_delete(struct prefix *p)
return;
}
+void sharp_zebra_nexthop_watch(struct prefix *p, bool watch)
+{
+ int command = ZEBRA_NEXTHOP_REGISTER;
+
+ if (!watch)
+ command = ZEBRA_NEXTHOP_UNREGISTER;
+
+ zclient_send_rnh(zclient, command, p, true, VRF_DEFAULT);
+}
+
+static int sharp_nexthop_update(int command, struct zclient *zclient,
+ zebra_size_t length, vrf_id_t vrf_id)
+{
+ struct zapi_route nhr;
+ char buf[PREFIX_STRLEN];
+ int i;
+
+ if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
+ zlog_warn("%s: Decode of update failed", __PRETTY_FUNCTION__);
+
+ return 0;
+ }
+
+ zlog_debug("Received update for %s",
+ prefix2str(&nhr.prefix, buf, sizeof(buf)));
+ for (i = 0; i < nhr.nexthop_num; i++) {
+ struct zapi_nexthop *znh = &nhr.nexthops[i];
+
+ switch (znh->type) {
+ case NEXTHOP_TYPE_IPV4_IFINDEX:
+ case NEXTHOP_TYPE_IPV4:
+ zlog_debug(
+ "\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ inet_ntop(AF_INET, &znh->gate.ipv4.s_addr, buf,
+ sizeof(buf)),
+ znh->type, znh->ifindex, znh->vrf_id,
+ znh->label_num);
+ break;
+ case NEXTHOP_TYPE_IPV6_IFINDEX:
+ case NEXTHOP_TYPE_IPV6:
+ zlog_debug(
+ "\tNexthop %s, type: %d, ifindex: %d, vrf: %d, label_num: %d",
+ inet_ntop(AF_INET6, &znh->gate.ipv6, buf,
+ sizeof(buf)),
+ znh->type, znh->ifindex, znh->vrf_id,
+ znh->label_num);
+ break;
+ case NEXTHOP_TYPE_IFINDEX:
+ zlog_debug("\tNexthop IFINDEX: %d, ifindex: %d",
+ znh->type, znh->ifindex);
+ break;
+ case NEXTHOP_TYPE_BLACKHOLE:
+ zlog_debug("\tNexthop blackhole");
+ break;
+ }
+ }
+ return 0;
+}
+
extern struct zebra_privs_t sharp_privs;
void sharp_zebra_init(void)
@@ -231,4 +290,5 @@ void sharp_zebra_init(void)
zclient->interface_address_add = interface_address_add;
zclient->interface_address_delete = interface_address_delete;
zclient->route_notify_owner = route_notify_owner;
+ zclient->nexthop_update = sharp_nexthop_update;
}
diff --git a/sharpd/sharp_zebra.h b/sharpd/sharp_zebra.h
index 0bba443bd4..0c906fc4ff 100644
--- a/sharpd/sharp_zebra.h
+++ b/sharpd/sharp_zebra.h
@@ -27,4 +27,5 @@ extern void sharp_zebra_init(void);
extern void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label);
extern void route_add(struct prefix *p, struct nexthop *nh);
extern void route_delete(struct prefix *p);
+extern void sharp_zebra_nexthop_watch(struct prefix *p, bool watch);
#endif
diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl
index a952de8947..a85d811c96 100755
--- a/tools/checkpatch.pl
+++ b/tools/checkpatch.pl
@@ -1249,11 +1249,6 @@ sub sanitise_line {
$res =~ s@(\#\s*(?:error|warning)\s+).*@$1$clean@;
}
- if ($allow_c99_comments && $res =~ m@(//.*$)@) {
- my $match = $1;
- $res =~ s/\Q$match\E/"$;" x length($match)/e;
- }
-
return $res;
}
@@ -3612,14 +3607,19 @@ sub process {
# no C99 // comments
if ($line =~ m{//}) {
- if (ERROR("C99_COMMENTS",
- "do not use C99 // comments\n" . $herecurr) &&
- $fix) {
- my $line = $fixed[$fixlinenr];
- if ($line =~ /\/\/(.*)$/) {
- my $comment = trim($1);
- $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
+ if (!$allow_c99_comments) {
+ if(ERROR("C99_COMMENTS",
+ "do not use C99 // comments\n" . $herecurr) &&
+ $fix) {
+ my $line = $fixed[$fixlinenr];
+ if ($line =~ /\/\/(.*)$/) {
+ my $comment = trim($1);
+ $fixed[$fixlinenr] =~ s@\/\/(.*)$@/\* $comment \*/@;
+ }
}
+ } else {
+ WARN("C99_COMMENTS",
+ "C99 // comments do not match recommendation\n" . $herecurr);
}
}
# Remove C99 comments.
diff --git a/tools/checkpatch.sh b/tools/checkpatch.sh
index e6110f0c7a..e1fb529d35 100755
--- a/tools/checkpatch.sh
+++ b/tools/checkpatch.sh
@@ -8,6 +8,8 @@ ignore="ldpd\|babeld"
cwd=${PWD##*/}
dirty=0
stat=0
+tmp1=/tmp/f1-$$
+tmp2=/tmp/f2-$$
if [[ -z "$1" || -z "$2" ]]; then
echo "$usage"
@@ -15,7 +17,7 @@ if [[ -z "$1" || -z "$2" ]]; then
fi
# remove temp directories
-rm -rf /tmp/f1 /tmp/f2
+rm -rf ${tmp1} ${tmp2}
# save working tree
if git -C $tree status --porcelain | egrep --silent '^(\?\?|.[DM])'; then
@@ -38,7 +40,7 @@ fi
git -C $tree reset --hard
git -C $tree apply < $patch
-mkdir -p /tmp/f1 /tmp/f2
+mkdir -p ${tmp1} ${tmp2}
mod=$(git -C $tree ls-files -m | grep ".*\.[ch]" | grep -v $ignore)
mod+=" $(git -C $tree ls-files --others --exclude-standard | grep '.*\.[ch]' | grep -v $ignore)"
echo $mod
@@ -47,32 +49,32 @@ if [ -z "$mod" ]; then
else
echo "Copying source to temp directory..."
for file in $mod; do
- echo "$tree/$file --> /tmp/f1/$file"
- cp $tree/$file /tmp/f1/
+ echo "$tree/$file --> ${tmp1}/$file"
+ cp $tree/$file ${tmp1}/
done
git -C $tree reset --hard
git -C $tree clean -fd
for file in $mod; do
if [ -f $tree/$file ]; then
- echo "$tree/$file --> /tmp/f2/$file"
- cp $tree/$file /tmp/f2/
+ echo "$tree/$file --> ${tmp2}/$file"
+ cp $tree/$file ${tmp2}/
fi
done
echo "Running style checks..."
- for file in /tmp/f1/*; do
+ for file in ${tmp1}/*; do
echo "$checkpatch $file > $file _cp"
$checkpatch $file > "$file"_cp 2> /dev/null
done
- for file in /tmp/f2/*; do
+ for file in ${tmp2}/*; do
echo "$checkpatch $file > $file _cp"
$checkpatch $file > "$file"_cp 2> /dev/null
done
echo "Done."
- for file in /tmp/f1/*_cp; do
- if [ -a /tmp/f2/$(basename $file) ]; then
- result=$(diff $file /tmp/f2/$(basename $file) | grep -A3 "ERROR\|WARNING" | grep -A2 -B2 '/tmp/f1')
+ for file in ${tmp1}/*_cp; do
+ if [ -a ${tmp2}/$(basename $file) ]; then
+ result=$(diff $file ${tmp2}/$(basename $file) | grep -A3 "ERROR\|WARNING" | grep -A2 -B2 "${tmp1}")
else
- result=$(cat $file | grep -A3 "ERROR\|WARNING" | grep -A2 -B2 '/tmp/f1')
+ result=$(cat $file | grep -A3 "ERROR\|WARNING" | grep -A2 -B2 "${tmp1}")
fi
if [ "$?" -eq "0" ]; then
echo "Report for $(basename $file _cp)" 1>&2
@@ -98,4 +100,7 @@ if [ $dirty -eq 1 ]; then
git -C $tree config --unset gc.auto;
fi
+# remove temp directories
+rm -rf ${tmp1} ${tmp2}
+
exit $stat
diff --git a/tools/frr-reload b/tools/frr-reload
new file mode 100755
index 0000000000..75b31d0622
--- /dev/null
+++ b/tools/frr-reload
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if test -e /usr/lib/frr/frr-reload.py; then
+ exec /usr/lib/frr/frr-reload.py --reload /etc/frr/frr.conf
+fi
+>&2 echo "Please install frr-pythontools package. Required for reload"
+exit 1
diff --git a/tools/frr.service b/tools/frr.service
index 4301ec9dc7..8800bf6b0f 100644
--- a/tools/frr.service
+++ b/tools/frr.service
@@ -17,6 +17,6 @@ Restart=on-abnormal
LimitNOFILE=1024
ExecStart=/usr/lib/frr/frr start
ExecStop=/usr/lib/frr/frr stop
-ExecReload=/usr/lib/frr/frr-reload.py --reload /etc/frr/frr.conf
+ExecReload=/usr/lib/frr/frr-reload
[Install]
WantedBy=network-online.target
diff --git a/tools/subdir.am b/tools/subdir.am
index 79aea179a9..602822e589 100644
--- a/tools/subdir.am
+++ b/tools/subdir.am
@@ -5,6 +5,7 @@
noinst_PROGRAMS += tools/permutations
sbin_PROGRAMS += tools/ssd
sbin_SCRIPTS += \
+ tools/frr-reload \
tools/frr-reload.py \
tools/frr \
# end
@@ -17,6 +18,7 @@ tools_ssd_SOURCES = tools/start-stop-daemon.c
EXTRA_DIST += \
tools/etc \
tools/frr \
+ tools/frr-reload \
tools/frr-reload.py \
tools/frr.service \
tools/multiple-bgpd.sh \
diff --git a/zebra/main.c b/zebra/main.c
index 00d853ea26..b0a19c5aa5 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -351,9 +351,6 @@ int main(int argc, char **argv)
*/
frr_config_fork();
- /* Clean up rib -- before fork (?) */
- /* rib_weed_tables (); */
-
/* After we have successfully acquired the pidfile, we can be sure
* about being the only copy of zebra process, which is submitting
* changes to the FIB.
diff --git a/zebra/redistribute.c b/zebra/redistribute.c
index 3a66aea45f..89c17b069a 100644
--- a/zebra/redistribute.c
+++ b/zebra/redistribute.c
@@ -58,7 +58,8 @@ int is_zebra_import_table_enabled(afi_t afi, u_int32_t table_id)
if (afi == AFI_MAX)
return 0;
- if (is_zebra_valid_kernel_table(table_id))
+ if (is_zebra_valid_kernel_table(table_id) &&
+ table_id < ZEBRA_KERNEL_TABLE_MAX)
return zebra_import_table_used[afi][table_id];
return 0;
}
diff --git a/zebra/rib.h b/zebra/rib.h
index 0ee89e015a..0562d544e6 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -230,23 +230,24 @@ typedef enum {
RIB_UPDATE_OTHER
} rib_update_event_t;
-extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *,
- ifindex_t,
+extern struct nexthop *route_entry_nexthop_ifindex_add(struct route_entry *re,
+ ifindex_t ifindex,
vrf_id_t nh_vrf_id);
-extern struct nexthop *route_entry_nexthop_blackhole_add(struct route_entry *,
- enum blackhole_type);
-extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *,
- struct in_addr *,
- struct in_addr *,
+extern struct nexthop *
+route_entry_nexthop_blackhole_add(struct route_entry *re,
+ enum blackhole_type bh_type);
+extern struct nexthop *route_entry_nexthop_ipv4_add(struct route_entry *re,
+ struct in_addr *ipv4,
+ struct in_addr *src,
vrf_id_t nh_vrf_id);
extern struct nexthop *
-route_entry_nexthop_ipv4_ifindex_add(struct route_entry *, struct in_addr *,
- struct in_addr *, ifindex_t,
- vrf_id_t nh_vrf_id);
+route_entry_nexthop_ipv4_ifindex_add(struct route_entry *re,
+ struct in_addr *ipv4, struct in_addr *src,
+ ifindex_t ifindex, vrf_id_t nh_vrf_id);
extern void route_entry_nexthop_delete(struct route_entry *re,
struct nexthop *nexthop);
-extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *,
- struct in6_addr *,
+extern struct nexthop *route_entry_nexthop_ipv6_add(struct route_entry *re,
+ struct in6_addr *ipv6,
vrf_id_t nh_vrf_id);
extern struct nexthop *
route_entry_nexthop_ipv6_ifindex_add(struct route_entry *re,
@@ -258,8 +259,9 @@ extern void route_entry_copy_nexthops(struct route_entry *re,
struct nexthop *nh);
#define route_entry_dump(prefix, src, re) _route_entry_dump(__func__, prefix, src, re)
-extern void _route_entry_dump(const char *, union prefixconstptr,
- union prefixconstptr, const struct route_entry *);
+extern void _route_entry_dump(const char *func, union prefixconstptr pp,
+ union prefixconstptr src_pp,
+ const struct route_entry *re);
/* RPF lookup behaviour */
enum multicast_mode {
MCAST_NO_CONFIG = 0, /* MIX_MRIB_FIRST, but no show in config write */
@@ -274,11 +276,11 @@ enum multicast_mode {
extern void multicast_mode_ipv4_set(enum multicast_mode mode);
extern enum multicast_mode multicast_mode_ipv4_get(void);
-extern void rib_lookup_and_dump(struct prefix_ipv4 *, vrf_id_t);
-extern void rib_lookup_and_pushup(struct prefix_ipv4 *, vrf_id_t);
+extern void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id);
+extern void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id);
-extern int rib_lookup_ipv4_route(struct prefix_ipv4 *, union sockunion *,
- vrf_id_t);
+extern int rib_lookup_ipv4_route(struct prefix_ipv4 *p, union sockunion *qgate,
+ vrf_id_t vrf_id);
#define ZEBRA_RIB_LOOKUP_ERROR -1
#define ZEBRA_RIB_FOUND_EXACT 0
#define ZEBRA_RIB_FOUND_NOGATE 1
@@ -305,8 +307,8 @@ extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_int32_t table_id, u_int32_t metric, u_int32_t mtu,
uint8_t distance, route_tag_t tag);
-extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *,
- struct prefix_ipv6 *src_p, struct route_entry *);
+extern int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
+ struct prefix_ipv6 *src_p, struct route_entry *re);
extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_short instance, int flags, struct prefix *p,
@@ -314,27 +316,30 @@ extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
u_int32_t table_id, u_int32_t metric, bool fromkernel,
struct ethaddr *rmac);
-extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t,
- union g_addr *,
+extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
+ union g_addr *addr,
struct route_node **rn_out);
extern struct route_entry *rib_match_ipv4_multicast(vrf_id_t vrf_id,
struct in_addr addr,
struct route_node **rn_out);
-extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *, vrf_id_t);
+extern struct route_entry *rib_lookup_ipv4(struct prefix_ipv4 *p,
+ vrf_id_t vrf_id);
-extern void rib_update(vrf_id_t, rib_update_event_t);
-extern void rib_weed_tables(void);
+extern void rib_update(vrf_id_t vrf_id, rib_update_event_t event);
extern void rib_sweep_route(void);
-extern void rib_close_table(struct route_table *);
+extern void rib_sweep_table(struct route_table *table);
+extern void rib_close_table(struct route_table *table);
extern void rib_init(void);
extern unsigned long rib_score_proto(u_char proto, u_short instance);
+extern unsigned long rib_score_proto_table(u_char proto, u_short instance,
+ struct route_table *table);
extern void rib_queue_add(struct route_node *rn);
extern void meta_queue_free(struct meta_queue *mq);
extern int zebra_rib_labeled_unicast(struct route_entry *re);
extern struct route_table *rib_table_ipv6;
-extern void rib_unlink(struct route_node *, struct route_entry *);
+extern void rib_unlink(struct route_node *rn, struct route_entry *re);
extern int rib_gc_dest(struct route_node *rn);
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
diff --git a/zebra/zebra_mpls.c b/zebra/zebra_mpls.c
index 1868b4676d..8375d45d2f 100644
--- a/zebra/zebra_mpls.c
+++ b/zebra/zebra_mpls.c
@@ -2254,6 +2254,19 @@ void zebra_mpls_print_fec(struct vty *vty, struct zebra_vrf *zvrf,
fec_print(rn->info, vty);
}
+static bool mpls_ftn_update_nexthop(int add, struct nexthop *nexthop,
+ enum lsp_types_t type, mpls_label_t label)
+{
+ if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
+ nexthop_add_labels(nexthop, type, 1, &label);
+ else if (!add && nexthop->nh_label_type == type)
+ nexthop_del_labels(nexthop);
+ else
+ return false;
+
+ return true;
+}
+
/*
* Install/uninstall a FEC-To-NHLFE (FTN) binding.
*/
@@ -2266,6 +2279,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
struct route_node *rn;
struct route_entry *re;
struct nexthop *nexthop;
+ bool found;
/* Lookup table. */
table = zebra_vrf_table(family2afi(prefix->family), SAFI_UNICAST,
@@ -2285,6 +2299,7 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (re == NULL)
return -1;
+ found = false;
for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next) {
switch (nexthop->type) {
case NEXTHOP_TYPE_IPV4:
@@ -2297,7 +2312,11 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
&& nexthop->ifindex != ifindex)
continue;
- goto found;
+ if (!mpls_ftn_update_nexthop(add, nexthop, type,
+ out_label))
+ return 0;
+ found = true;
+ break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
if (gtype != NEXTHOP_TYPE_IPV6
@@ -2308,21 +2327,18 @@ int mpls_ftn_update(int add, struct zebra_vrf *zvrf, enum lsp_types_t type,
if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
&& nexthop->ifindex != ifindex)
continue;
- goto found;
+ if (!mpls_ftn_update_nexthop(add, nexthop, type,
+ out_label))
+ return 0;
+ found = true;
+ break;
default:
break;
}
}
- /* nexthop not found */
- return -1;
-found:
- if (add && nexthop->nh_label_type == ZEBRA_LSP_NONE)
- nexthop_add_labels(nexthop, type, 1, &out_label);
- else if (!add && nexthop->nh_label_type == type)
- nexthop_del_labels(nexthop);
- else
- return 0;
+ if (!found)
+ return -1;
SET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
SET_FLAG(re->status, ROUTE_ENTRY_LABELS_CHANGED);
diff --git a/zebra/zebra_netns_id.c b/zebra/zebra_netns_id.c
index a81413f5a9..d278ebe913 100644
--- a/zebra/zebra_netns_id.c
+++ b/zebra/zebra_netns_id.c
@@ -172,6 +172,7 @@ ns_id_t zebra_ns_id_get(const char *netnspath)
if (sock < 0) {
zlog_err("netlink( %u) socket() error: %s", sock,
safe_strerror(errno));
+ close(fd);
return NS_UNKNOWN;
}
memset(&snl, 0, sizeof(snl));
diff --git a/zebra/zebra_ns.c b/zebra/zebra_ns.c
index 192e8ad413..29c179245b 100644
--- a/zebra/zebra_ns.c
+++ b/zebra/zebra_ns.c
@@ -37,6 +37,7 @@
#include "zebra_netns_notify.h"
#include "zebra_netns_id.h"
#include "zebra_pbr.h"
+#include "rib.h"
extern struct zebra_privs_t zserv_privs;
@@ -162,6 +163,31 @@ struct route_table *zebra_ns_find_table(struct zebra_ns *zns, uint32_t tableid,
return NULL;
}
+unsigned long zebra_ns_score_proto(u_char proto, u_short instance)
+{
+ struct zebra_ns *zns;
+ struct zebra_ns_table *znst;
+ unsigned long cnt = 0;
+
+ zns = zebra_ns_lookup(NS_DEFAULT);
+
+ RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables)
+ cnt += rib_score_proto_table(proto, instance, znst->table);
+
+ return cnt;
+}
+
+void zebra_ns_sweep_route(void)
+{
+ struct zebra_ns_table *znst;
+ struct zebra_ns *zns;
+
+ zns = zebra_ns_lookup(NS_DEFAULT);
+
+ RB_FOREACH (znst, zebra_ns_table_head, &zns->ns_tables)
+ rib_sweep_table(znst->table);
+}
+
struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
struct zebra_vrf *zvrf, uint32_t tableid,
afi_t afi)
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index 19ecba1f0e..6655e5c019 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -90,4 +90,7 @@ extern struct route_table *zebra_ns_get_table(struct zebra_ns *zns,
struct zebra_vrf *zvrf,
uint32_t tableid, afi_t afi);
int zebra_ns_config_write(struct vty *vty, struct ns *ns);
+
+unsigned long zebra_ns_score_proto(u_char proto, u_short instance);
+void zebra_ns_sweep_route(void);
#endif
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 4da09dc538..090ec2c502 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -133,6 +133,25 @@ void zebra_pbr_del_rule(struct zebra_ns *zns, struct zebra_pbr_rule *rule)
__PRETTY_FUNCTION__);
}
+static void zebra_pbr_cleanup_rules(struct hash_backet *b, void *data)
+{
+ struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
+ struct zebra_pbr_rule *rule = b->data;
+ int *sock = data;
+
+ if (rule->sock == *sock) {
+ kernel_del_pbr_rule(rule);
+ hash_release(zns->rules_hash, rule);
+ }
+}
+
+void zebra_pbr_client_close_cleanup(int sock)
+{
+ struct zebra_ns *zns = zebra_ns_lookup(NS_DEFAULT);
+
+ hash_iterate(zns->rules_hash, zebra_pbr_cleanup_rules, &sock);
+}
+
/*
* Handle success or failure of rule (un)install in the kernel.
*/
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 4b28b6ec35..f910d8e742 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -132,7 +132,10 @@ extern void kernel_pbr_rule_add_del_status(struct zebra_pbr_rule *rule,
*/
extern int kernel_pbr_rule_del(struct zebra_pbr_rule *rule);
+extern void zebra_pbr_client_close_cleanup(int sock);
+
extern void zebra_pbr_rules_free(void *arg);
extern uint32_t zebra_pbr_rules_hash_key(void *arg);
extern int zebra_pbr_rules_hash_equal(const void *arg1, const void *arg2);
+
#endif /* _ZEBRA_PBR_H */
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index d654579b1c..69cd6697d2 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -139,9 +139,6 @@ uint8_t route_distance(int type)
int is_zebra_valid_kernel_table(u_int32_t table_id)
{
- if ((table_id > ZEBRA_KERNEL_TABLE_MAX))
- return 0;
-
#ifdef linux
if ((table_id == RT_TABLE_UNSPEC) || (table_id == RT_TABLE_LOCAL)
|| (table_id == RT_TABLE_COMPAT))
@@ -2705,40 +2702,8 @@ void rib_update(vrf_id_t vrf_id, rib_update_event_t event)
rib_update_table(table, event);
}
-/* Remove all routes which comes from non main table. */
-static void rib_weed_table(struct route_table *table)
-{
- struct route_node *rn;
- struct route_entry *re;
- struct route_entry *next;
-
- if (table)
- for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
- RNODE_FOREACH_RE_SAFE (rn, re, next) {
- if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
- continue;
-
- if (re->table != zebrad.rtm_table_default
- && re->table != RT_TABLE_MAIN)
- rib_delnode(rn, re);
- }
-}
-
-/* Delete all routes from non main table. */
-void rib_weed_tables(void)
-{
- struct vrf *vrf;
- struct zebra_vrf *zvrf;
-
- RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
- if ((zvrf = vrf->info) != NULL) {
- rib_weed_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
- rib_weed_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
- }
-}
-
/* Delete self installed routes after zebra is relaunched. */
-static void rib_sweep_table(struct route_table *table)
+void rib_sweep_table(struct route_table *table)
{
struct route_node *rn;
struct route_entry *re;
@@ -2799,11 +2764,13 @@ void rib_sweep_route(void)
rib_sweep_table(zvrf->table[AFI_IP][SAFI_UNICAST]);
rib_sweep_table(zvrf->table[AFI_IP6][SAFI_UNICAST]);
}
+
+ zebra_ns_sweep_route();
}
/* Remove specific by protocol routes from 'table'. */
-static unsigned long rib_score_proto_table(u_char proto, u_short instance,
- struct route_table *table)
+unsigned long rib_score_proto_table(u_char proto, u_short instance,
+ struct route_table *table)
{
struct route_node *rn;
struct route_entry *re;
@@ -2840,6 +2807,8 @@ unsigned long rib_score_proto(u_char proto, u_short instance)
proto, instance,
zvrf->table[AFI_IP6][SAFI_UNICAST]);
+ cnt += zebra_ns_score_proto(proto, instance);
+
return cnt;
}
diff --git a/zebra/zebra_rnh.c b/zebra/zebra_rnh.c
index c9fb782ba6..48f9f4f366 100644
--- a/zebra/zebra_rnh.c
+++ b/zebra/zebra_rnh.c
@@ -986,7 +986,7 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
struct route_entry *re;
unsigned long nump;
u_char num;
- struct nexthop *nexthop;
+ struct nexthop *nh;
struct route_node *rn;
int cmd = (type == RNH_IMPORT_CHECK_TYPE) ? ZEBRA_IMPORT_CHECK_UPDATE
: ZEBRA_NEXTHOP_UPDATE;
@@ -1022,32 +1022,40 @@ static int send_client(struct rnh *rnh, struct zserv *client, rnh_type_t type,
num = 0;
nump = stream_get_endp(s);
stream_putc(s, 0);
- for (nexthop = re->ng.nexthop; nexthop; nexthop = nexthop->next)
- if ((CHECK_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB)
- || CHECK_FLAG(nexthop->flags,
- NEXTHOP_FLAG_RECURSIVE))
- && CHECK_FLAG(nexthop->flags,
- NEXTHOP_FLAG_ACTIVE)) {
- stream_putc(s, nexthop->type);
- switch (nexthop->type) {
+ for (nh = re->ng.nexthop; nh; nh = nh->next)
+ if ((CHECK_FLAG(nh->flags, NEXTHOP_FLAG_FIB)
+ || CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
+ && CHECK_FLAG(nh->flags, NEXTHOP_FLAG_ACTIVE)) {
+ stream_putc(s, nh->type);
+ switch (nh->type) {
case NEXTHOP_TYPE_IPV4:
case NEXTHOP_TYPE_IPV4_IFINDEX:
- stream_put_in_addr(s,
- &nexthop->gate.ipv4);
- stream_putl(s, nexthop->ifindex);
+ stream_put_in_addr(s, &nh->gate.ipv4);
+ stream_putl(s, nh->ifindex);
break;
case NEXTHOP_TYPE_IFINDEX:
- stream_putl(s, nexthop->ifindex);
+ stream_putl(s, nh->ifindex);
break;
case NEXTHOP_TYPE_IPV6:
case NEXTHOP_TYPE_IPV6_IFINDEX:
- stream_put(s, &nexthop->gate.ipv6, 16);
- stream_putl(s, nexthop->ifindex);
+ stream_put(s, &nh->gate.ipv6, 16);
+ stream_putl(s, nh->ifindex);
break;
default:
/* do nothing */
break;
}
+ if (nh->nh_label) {
+ stream_putc(s,
+ nh->nh_label->num_labels);
+ if (nh->nh_label->num_labels)
+ stream_put(
+ s,
+ &nh->nh_label->label[0],
+ nh->nh_label->num_labels
+ * sizeof(mpls_label_t));
+ } else
+ stream_putc(s, 0);
num++;
}
stream_putc_at(s, nump, num);
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 32d5286d5e..35d4bd533d 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -249,7 +249,11 @@ static int zebra_static_route_holdem(struct zebra_vrf *zvrf,
return CMD_SUCCESS;
}
- assert(!"We should not have found a duplicate and not remove it");
+ /*
+ * If a person enters the same line again
+ * we need to silently accept it
+ */
+ return CMD_SUCCESS;
}
listnode_add_sort(static_list, shr);
@@ -489,6 +493,34 @@ static int zebra_static_route_leak(
return CMD_SUCCESS;
}
+static struct zebra_vrf *zebra_vty_get_unknown_vrf(struct vty *vty,
+ const char *vrf_name)
+{
+ struct zebra_vrf *zvrf;
+ struct vrf *vrf;
+
+ zvrf = zebra_vrf_lookup_by_name(vrf_name);
+
+ if (zvrf)
+ return zvrf;
+
+ vrf = vrf_get(VRF_UNKNOWN, vrf_name);
+ if (!vrf) {
+ vty_out(vty, "%% Could not create vrf %s\n", vrf_name);
+ return NULL;
+ }
+ zvrf = vrf->info;
+ if (!zvrf) {
+ vty_out(vty, "%% Could not create vrf-info %s\n",
+ vrf_name);
+ return NULL;
+ }
+ /* Mark as having FRR configuration */
+ vrf_set_user_cfged(vrf);
+
+ return zvrf;
+}
+
static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *negate, const char *dest_str,
const char *mask_str, const char *src_str,
@@ -498,7 +530,6 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *label_str)
{
struct zebra_vrf *zvrf;
- struct vrf *vrf;
/* VRF id */
zvrf = zebra_vrf_lookup_by_name(vrf_name);
@@ -513,19 +544,9 @@ static int zebra_static_route(struct vty *vty, afi_t afi, safi_t safi,
* Note: The VRF isn't active until we hear about it from the kernel.
*/
if (!zvrf) {
- vrf = vrf_get(VRF_UNKNOWN, vrf_name);
- if (!vrf) {
- vty_out(vty, "%% Could not create vrf %s\n", vrf_name);
- return CMD_WARNING_CONFIG_FAILED;
- }
- zvrf = vrf->info;
- if (!zvrf) {
- vty_out(vty, "%% Could not create vrf-info %s\n",
- vrf_name);
+ zvrf = zebra_vty_get_unknown_vrf(vty, vrf_name);
+ if (!zvrf)
return CMD_WARNING_CONFIG_FAILED;
- }
- /* Mark as having FRR configuration */
- vrf_set_user_cfged(vrf);
}
return zebra_static_route_leak(
vty, zvrf, zvrf, afi, safi, negate, dest_str, mask_str, src_str,
@@ -777,14 +798,14 @@ DEFPY(ip_route_address_interface,
ifname = NULL;
}
- zvrf = zebra_vrf_lookup_by_name(vrf);
+ zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
return CMD_WARNING_CONFIG_FAILED;
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -835,7 +856,7 @@ DEFPY(ip_route_address_interface_vrf,
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -884,14 +905,14 @@ DEFPY(ip_route,
ifname = NULL;
}
- zvrf = zebra_vrf_lookup_by_name(vrf);
+ zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
return CMD_WARNING_CONFIG_FAILED;
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -941,7 +962,7 @@ DEFPY(ip_route_vrf,
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -2209,7 +2230,7 @@ int static_config(struct vty *vty, struct zebra_vrf *zvrf, afi_t afi,
if (shr->flag_str)
vty_out(vty, "%s ", shr->flag_str);
if (shr->tag_str)
- vty_out(vty, "tag %s", shr->tag_str);
+ vty_out(vty, "tag %s ", shr->tag_str);
if (shr->distance_str)
vty_out(vty, "%s ", shr->distance_str);
if (shr->label_str)
@@ -2388,14 +2409,14 @@ DEFPY(ipv6_route_address_interface,
struct zebra_vrf *zvrf;
struct zebra_vrf *nh_zvrf;
- zvrf = zebra_vrf_lookup_by_name(vrf);
+ zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
return CMD_WARNING_CONFIG_FAILED;
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -2439,7 +2460,7 @@ DEFPY(ipv6_route_address_interface_vrf,
struct zebra_vrf *nh_zvrf;
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -2482,14 +2503,14 @@ DEFPY(ipv6_route,
struct zebra_vrf *zvrf;
struct zebra_vrf *nh_zvrf;
- zvrf = zebra_vrf_lookup_by_name(vrf);
+ zvrf = zebra_vty_get_unknown_vrf(vty, vrf);
if (!zvrf) {
vty_out(vty, "%% vrf %s is not defined\n", vrf);
return CMD_WARNING_CONFIG_FAILED;
}
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
@@ -2532,7 +2553,7 @@ DEFPY(ipv6_route_vrf,
struct zebra_vrf *nh_zvrf;
if (nexthop_vrf)
- nh_zvrf = zebra_vrf_lookup_by_name(nexthop_vrf);
+ nh_zvrf = zebra_vty_get_unknown_vrf(vty, nexthop_vrf);
else
nh_zvrf = zvrf;
diff --git a/zebra/zserv.c b/zebra/zserv.c
index 57b1be4b8b..fc23d4e0dd 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -222,11 +222,15 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
/* Check this client need interface information. */
- if (!client->ifinfo)
+ if (!client->ifinfo) {
+ stream_free(s);
return 0;
+ }
- if (!ifp->link_params)
+ if (!ifp->link_params) {
+ stream_free(s);
return 0;
+ }
zclient_create_header(s, ZEBRA_INTERFACE_LINK_PARAMS, ifp->vrf_id);
@@ -234,8 +238,10 @@ int zsend_interface_link_params(struct zserv *client, struct interface *ifp)
stream_putl(s, ifp->ifindex);
/* Then TE Link Parameters */
- if (zebra_interface_link_params_write(s, ifp) == 0)
+ if (zebra_interface_link_params_write(s, ifp) == 0) {
+ stream_free(s);
return 0;
+ }
/* Write packet size. */
stream_putw_at(s, 0, stream_get_endp(s));
@@ -595,8 +601,10 @@ int zsend_redistribute_route(int cmd, struct zserv *client, struct prefix *p,
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);
/* Encode route and send. */
- if (zapi_route_encode(cmd, s, &api) < 0)
+ if (zapi_route_encode(cmd, s, &api) < 0) {
+ stream_free(s);
return -1;
+ }
if (IS_ZEBRA_DEBUG_SEND) {
char buf_prefix[PREFIX_STRLEN];
@@ -2614,7 +2622,7 @@ static inline void zserv_handle_commands(struct zserv *client,
struct stream *msg,
struct zebra_vrf *zvrf)
{
- if (hdr->command > sizeof(zserv_handlers)
+ if (hdr->command > array_size(zserv_handlers)
|| zserv_handlers[hdr->command] == NULL)
zlog_info("Zebra received unknown command %d", hdr->command);
else
@@ -2631,6 +2639,9 @@ static void zebra_client_free(struct zserv *client)
/* Send client de-registration to BFD */
zebra_ptm_bfd_client_deregister(client->proto);
+ /* Cleanup any rules installed from this client */
+ zebra_pbr_client_close_cleanup(client->sock);
+
/* Cleanup any registered nexthops - across all VRFs. */
zebra_client_close_cleanup_rnh(client);