Compare commits

...

No commits in common. "c8" and "a9" have entirely different histories.
c8 ... a9

41 changed files with 1272 additions and 1322 deletions

1
.frr.metadata Normal file
View File

@ -0,0 +1 @@
467835eb73a6018948fd667663ce68282cf6d16b SOURCES/frr-8.3.1.tar.gz

2
.gitignore vendored
View File

@ -1 +1 @@
SOURCES/frr-7.5.1.tar.gz
SOURCES/frr-8.3.1.tar.gz

View File

@ -1,20 +0,0 @@
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 208fb11..0692adc 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
# Frr Reloader
# Copyright (C) 2014 Cumulus Networks, Inc.
#
diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py
index 540b7a1..0876ebb 100755
--- a/tools/generate_support_bundle.py
+++ b/tools/generate_support_bundle.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
########################################################
### Python Script to generate the FRR support bundle ###

View File

@ -10,22 +10,6 @@ index 0b7af18..0533e24 100644
lib/memory.c \
lib/mlag.c \
lib/module.c \
diff --git a/lib/subdir.am b/lib/subdir.am
index 0533e24..b3d3700 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -170,7 +170,6 @@ pkginclude_HEADERS += \
lib/linklist.h \
lib/log.h \
lib/log_vty.h \
- lib/md5.h \
lib/memory.h \
lib/module.h \
lib/monotime.h \
diff --git a/lib/subdir.am b/lib/subdir.am
index 53f7115..cea866f 100644
--- a/lib/subdir.am
+++ b/lib/subdir.am
@@ -64,7 +64,6 @@ lib_libfrr_la_SOURCES = \
lib/routemap_northbound.c \
lib/sbuf.c \
@ -34,8 +18,16 @@ index 53f7115..cea866f 100644
lib/sigevent.c \
lib/skiplist.c \
lib/sockopt.c \
@@ -170,7 +170,6 @@ pkginclude_HEADERS += \
lib/link_state.h \
lib/log.h \
lib/log_vty.h \
- lib/md5.h \
lib/memory.h \
lib/module.h \
lib/monotime.h \
@@ -191,7 +190,6 @@ pkginclude_HEADERS += \
lib/routemap.h \
lib/route_opaque.h \
lib/sbuf.h \
lib/seqlock.h \
- lib/sha256.h \

View File

@ -101,3 +101,15 @@ index 5bb81ef..02a09ef 100644
nb_cli_enqueue_change(vty, "./authentication-scheme/mode", NB_OP_MODIFY,
strmatch(mode, "md5") ? "md5" : "plain-text");
if (strmatch(mode, "md5"))
diff --git a/lib/zebra.h b/lib/zebra.h
index 53ae5b4..930307f 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -114,6 +114,7 @@
#ifdef CRYPTO_OPENSSL
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include <openssl/fips.h>
#endif
#include "openbsd-tree.h"

View File

@ -0,0 +1,25 @@
diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c
index 74a5674..aec9037 100644
--- a/ospfd/ospf_spf.c
+++ b/ospfd/ospf_spf.c
@@ -48,7 +48,10 @@
#include "ospfd/ospf_sr.h"
#include "ospfd/ospf_ti_lfa.h"
#include "ospfd/ospf_errors.h"
+
+#ifdef SUPPORT_OSPF_API
#include "ospfd/ospf_apiserver.h"
+#endif
/* Variables to ensure a SPF scheduled log message is printed only once */
@@ -1897,7 +1900,9 @@ static void ospf_spf_calculate_schedule_worker(struct thread *thread)
/* Update all routers routing table */
ospf->oall_rtrs = ospf->all_rtrs;
ospf->all_rtrs = all_rtrs;
+#ifdef SUPPORT_OSPF_API
ospf_apiserver_notify_reachable(ospf->oall_rtrs, ospf->all_rtrs);
+#endif
/* Free old ABR/ASBR routing table */
if (ospf->old_rtrs)

View File

@ -1,17 +0,0 @@
diff --git a/tools/frr.in b/tools/frr.in
index b860797..eb64a93 100755
--- a/tools/frr.in
+++ b/tools/frr.in
@@ -105,10 +105,12 @@ check_daemon()
if [ ! -r "$C_PATH/$1-$2.conf" ]; then
touch "$C_PATH/$1-$2.conf"
chownfrr "$C_PATH/$1-$2.conf"
+ chmod 0600 "$C_PATH/$1-$2.conf"
fi
elif [ ! -r "$C_PATH/$1.conf" ]; then
touch "$C_PATH/$1.conf"
chownfrr "$C_PATH/$1.conf"
+ chmod 0600 "$C_PATH/$1.conf"
fi
fi
return 0

View File

@ -12,10 +12,10 @@ Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 3d4ef7c..f8089c6 100644
index 749e46ebe9d..ae1308db423 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -2564,11 +2564,34 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
@@ -2755,11 +2755,34 @@ int peer_group_remote_as(struct bgp *bgp, const char *group_name, as_t *as,
void peer_notify_unconfig(struct peer *peer)
{
@ -50,7 +50,7 @@ index 3d4ef7c..f8089c6 100644
void peer_group_notify_unconfig(struct peer_group *group)
{
struct peer *peer, *other;
@@ -3380,11 +3403,8 @@ int bgp_delete(struct bgp *bgp)
@@ -3676,11 +3699,8 @@ int bgp_delete(struct bgp *bgp)
}
/* Inform peers we're going down. */
@ -64,16 +64,15 @@ index 3d4ef7c..f8089c6 100644
/* Delete static routes (networks). */
bgp_static_delete(bgp);
@@ -7238,11 +7258,7 @@ void bgp_terminate(void)
@@ -8252,10 +8272,7 @@ void bgp_terminate(void)
for (ALL_LIST_ELEMENTS(bm->bgp, mnode, mnnode, bgp))
for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
- if (peer->status == Established
- || peer->status == OpenSent
- if (peer_established(peer) || peer->status == OpenSent
- || peer->status == OpenConfirm)
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+ peer_notify_unconfig(peer);
if (bm->process_main_queue)
work_queue_free_and_null(&bm->process_main_queue);
BGP_TIMER_OFF(bm->t_rmap_update);

View File

@ -1,31 +0,0 @@
diff --git a/tools/frrinit.sh.in b/tools/frrinit.sh.in
index 539ab7d..d27d1be 100644
--- a/tools/frrinit.sh.in
+++ b/tools/frrinit.sh.in
@@ -43,7 +43,7 @@ fi
case "$1" in
start)
daemon_list daemons
- watchfrr_options="$watchfrr_options $daemons"
+ watchfrr_options="$daemons"
daemon_start watchfrr
;;
stop)
@@ -57,7 +57,7 @@ restart|force-reload)
all_stop --reallyall
daemon_list daemons
- watchfrr_options="$watchfrr_options $daemons"
+ watchfrr_options="$daemons"
daemon_start watchfrr
;;
@@ -87,7 +87,7 @@ reload)
# restart watchfrr to pick up added daemons.
# NB: This will NOT cause the other daemons to be restarted.
daemon_list daemons
- watchfrr_options="$watchfrr_options $daemons"
+ watchfrr_options="$daemons"
daemon_stop watchfrr && \
daemon_start watchfrr

View File

@ -1,33 +0,0 @@
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 69a3e4587..57ef6029a 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -3737,6 +3737,28 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
vty_out(vty,
" No backup designated router on this network\n");
} else {
+ nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &DR(oi));
+ if (nbr) {
+ if (use_json) {
+ json_object_string_add(
+ json_interface_sub, "drId",
+ inet_ntoa(nbr->router_id));
+ json_object_string_add(
+ json_interface_sub, "drAddress",
+ inet_ntoa(nbr->address.u
+ .prefix4));
+ } else {
+ vty_out(vty,
+ " Designated Router (ID) %s",
+ inet_ntoa(nbr->router_id));
+ vty_out(vty,
+ " Interface Address %s\n",
+ inet_ntoa(nbr->address.u
+ .prefix4));
+ }
+ }
+ nbr = NULL;
+
nbr = ospf_nbr_lookup_by_addr(oi->nbrs, &BDR(oi));
if (nbr == NULL) {
if (!use_json)

View File

@ -0,0 +1,67 @@
From 1d42fb941af17a29346b2af03338f8e18470f009 Mon Sep 17 00:00:00 2001
From: Michal Ruprich <michalruprich@gmail.com>
Date: Tue, 22 Nov 2022 12:38:05 +0100
Subject: [PATCH] tools: Enable start of FRR for non-root user
There might be use cases when this would make sense, for example
running FRR in a container as a designated user.
Signed-off-by: Michal Ruprich <mruprich@redhat.com>
---
tools/etc/frr/daemons | 5 +++++
tools/frrcommon.sh.in | 4 ++++
2 files changed, 9 insertions(+)
diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons
index 8aa08871e35..2427bfff777 100644
--- a/tools/etc/frr/daemons
+++ b/tools/etc/frr/daemons
@@ -91,6 +91,12 @@ pathd_options=" -A 127.0.0.1"
# say BGP.
#MAX_FDS=1024
+# Uncomment this option if you want to run FRR as a non-root user. Note that
+# you should know what you are doing since most of the daemons need root
+# to work. This could be useful if you want to run FRR in a container
+# for instance.
+# FRR_NO_ROOT="yes"
+
# The list of daemons to watch is automatically generated by the init script.
#watchfrr_options=""
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
index 3c16c27c6df..4f095a176e4 100755
--- a/tools/frrcommon.sh.in
+++ b/tools/frrcommon.sh.in
@@ -43,6 +43,10 @@ RELOAD_SCRIPT="$D_PATH/frr-reload.py"
#
is_user_root () {
+ if [[ ! -z $FRR_NO_ROOT && "${FRR_NO_ROOT}" == "yes" ]]; then
+ return 0
+ fi
+
[ "${EUID:-$(id -u)}" -eq 0 ] || {
log_failure_msg "Only users having EUID=0 can start/stop daemons"
return 1
diff --git a/doc/user/setup.rst b/doc/user/setup.rst
index 25934df..51ffd32 100644
--- a/doc/user/setup.rst
+++ b/doc/user/setup.rst
@@ -114,6 +114,16 @@ most operating systems is 1024. If the operator plans to run bgp with
several thousands of peers than this is where we would modify FRR to
allow this to happen.
+::
+
+ FRR_NO_ROOT="yes"
+
+This option allows you to run FRR as a non-root user. Use this option
+only when you know what you are doing since most of the daemons
+in FRR will not be able to run under a regular user. This option
+is useful for example when you run FRR in a container with a designated
+user instead of root.
+
::
zebra_options=" -s 90000000 --daemon -A 127.0.0.1"

View File

@ -0,0 +1,59 @@
From 3e46b43e3788f0f87bae56a86b54d412b4710286 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Fri, 30 Sep 2022 08:51:45 -0400
Subject: [PATCH] bgpd: Ensure FRR has enough data to read 2 bytes in
peek_for_as4_capability
In peek_for_as4_capability the code is checking that the
stream has at least 2 bytes to read ( the opt_type and the
opt_length ). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
is configured then FRR is reading 3 bytes. Which is not good
since the packet could be badly formated. Ensure that
FRR has the appropriate data length to read the data.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_open.c | 27 +++++++++++++++++++++------
1 file changed, 21 insertions(+), 6 deletions(-)
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index 7248f034a5a..a760a7ca013 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1185,15 +1185,30 @@ as_t peek_for_as4_capability(struct peer *peer, uint16_t length)
uint8_t opt_type;
uint16_t opt_length;
- /* Check the length. */
- if (stream_get_getp(s) + 2 > end)
+ /* Ensure we can read the option type */
+ if (stream_get_getp(s) + 1 > end)
goto end;
- /* Fetch option type and length. */
+ /* Fetch the option type */
opt_type = stream_getc(s);
- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
- ? stream_getw(s)
- : stream_getc(s);
+
+ /*
+ * Check the length and fetch the opt_length
+ * If the peer is BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
+ * then we do a getw which is 2 bytes. So we need to
+ * ensure that we can read that as well
+ */
+ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
+ if (stream_get_getp(s) + 2 > end)
+ goto end;
+
+ opt_length = stream_getw(s);
+ } else {
+ if (stream_get_getp(s) + 1 > end)
+ goto end;
+
+ opt_length = stream_getc(s);
+ }
/* Option length check. */
if (stream_get_getp(s) + opt_length > end)

View File

@ -0,0 +1,267 @@
From edc3f63167fd95e4e70287743c9b252415c9336e Mon Sep 17 00:00:00 2001
From: Philippe Guibert <philippe.guibert@6wind.com>
Date: Thu, 7 Jul 2022 14:33:48 +0200
Subject: [PATCH] bfdd: allow l3vrf bfd sessions without udp leaking
Until now, when in vrf-lite mode, the BFD implementation
creates a single UDP socket and relies on the following
sysctl value to 1:
echo 1 > /proc/sys/net/ipv4/udp_l3mdev_accept
With this setting, the incoming BFD packets from a given
vrf, would leak to the default vrf, and would match the
UDP socket.
The drawback of this solution is that udp packets received
on a given vrf may leak to an other vrf. This may be a
security concern.
The commit addresses this issue by avoiding this leak
mechanism. An UDP socket is created for each vrf, and each
socket uses new setsockopt option: SO_REUSEADDR + SO_REUSEPORT.
With this option, the incoming UDP packets are distributed on
the available sockets. The impact of those options with l3mdev
devices is unknown. It has been observed that this option is not
needed, until the default vrf sockets are created.
To ensure the BFD packets are correctly routed to the appropriate
socket, a BPF filter has been put in place and attached to the
sockets : SO_ATTACH_REUSEPORT_CBPF. This option adds a criterium
to force the packet to choose a given socket. If initial criteria
from the default distribution algorithm were not good, at least
two sockets would be available, and the CBPF would force the
selection to the same socket. This would come to the situation
where an incoming packet would be processed on a different vrf.
The bpf code is the following one:
struct sock_filter code[] = {
{ BPF_RET | BPF_K, 0, 0, 0 },
};
struct sock_fprog p = {
.len = sizeof(code)/sizeof(struct sock_filter),
.filter = code,
};
if (setsockopt(sd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p))) {
zlog_warn("unable to set SO_ATTACH_REUSEPORT_CBPF on socket: %s",
strerror(errno));
return -1;
}
Some tests have been done with by creating vrf contexts, and by using
the below vtysh configuration:
ip route 2.2.2.2/32 10.126.0.2
vrf vrf2
ip route 2.2.2.2/32 10.126.0.2
!
interface ntfp2
ip address 10.126.0.1/24
!
interface ntfp3 vrf vrf4
ip address 10.126.0.1/24
!
interface ntfp2 vrf vrf1
ip address 10.126.0.1/24
!
interface ntfp2.100 vrf vrf2
ip address 10.126.0.1/24
!
interface ntfp2.200 vrf vrf3
ip address 10.126.0.1/24
!
line vty
!
bfd
peer 10.126.0.2 vrf vrf2
!
peer 10.126.0.2 vrf vrf3
!
peer 10.126.0.2
!
peer 10.126.0.2 vrf vrf4
!
peer 2.2.2.2 multihop local-address 1.1.1.1
!
peer 2.2.2.2 multihop local-address 1.1.1.1 vrf vrf2
transmit-interval 1500
receive-interval 1500
!
The results showed no issue related to packets received by
the wrong vrf. Even changing the udp_l3mdev_accept flag to
1 did not change the test results.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bfdd/bfd.c | 66 +++++++++++++++++++++++------------------------
bfdd/bfd_packet.c | 45 ++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 34 deletions(-)
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 483beb1b17c..a1619263588 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -1950,40 +1950,38 @@ static int bfd_vrf_enable(struct vrf *vrf)
if (bglobal.debug_zebra)
zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
- if (vrf->vrf_id == VRF_DEFAULT ||
- vrf_get_backend() == VRF_BACKEND_NETNS) {
- if (!bvrf->bg_shop)
- bvrf->bg_shop = bp_udp_shop(vrf);
- if (!bvrf->bg_mhop)
- bvrf->bg_mhop = bp_udp_mhop(vrf);
- if (!bvrf->bg_shop6)
- bvrf->bg_shop6 = bp_udp6_shop(vrf);
- if (!bvrf->bg_mhop6)
- bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
- if (!bvrf->bg_echo)
- bvrf->bg_echo = bp_echo_socket(vrf);
- if (!bvrf->bg_echov6)
- bvrf->bg_echov6 = bp_echov6_socket(vrf);
-
- if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop, &bvrf->bg_ev[0]);
- if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop, &bvrf->bg_ev[1]);
- if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop6, &bvrf->bg_ev[2]);
- if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop6, &bvrf->bg_ev[3]);
- if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echo, &bvrf->bg_ev[4]);
- if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echov6, &bvrf->bg_ev[5]);
- }
+ if (!bvrf->bg_shop)
+ bvrf->bg_shop = bp_udp_shop(vrf);
+ if (!bvrf->bg_mhop)
+ bvrf->bg_mhop = bp_udp_mhop(vrf);
+ if (!bvrf->bg_shop6)
+ bvrf->bg_shop6 = bp_udp6_shop(vrf);
+ if (!bvrf->bg_mhop6)
+ bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
+ if (!bvrf->bg_echo)
+ bvrf->bg_echo = bp_echo_socket(vrf);
+ if (!bvrf->bg_echov6)
+ bvrf->bg_echov6 = bp_echov6_socket(vrf);
+
+ if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
+ &bvrf->bg_ev[0]);
+ if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
+ &bvrf->bg_ev[1]);
+ if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
+ &bvrf->bg_ev[2]);
+ if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
+ &bvrf->bg_ev[3]);
+ if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
+ &bvrf->bg_ev[4]);
+ if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
+ &bvrf->bg_ev[5]);
+
if (vrf->vrf_id != VRF_DEFAULT) {
bfdd_zclient_register(vrf->vrf_id);
bfdd_sessions_enable_vrf(vrf);
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index d34d6427628..054a9bfbf21 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -876,6 +876,14 @@ void bfd_recv_cb(struct thread *t)
"no session found");
return;
}
+ /*
+ * We may have a situation where received packet is on wrong vrf
+ */
+ if (bfd && bfd->vrf && bfd->vrf != bvrf->vrf) {
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
+ "wrong vrfid.");
+ return;
+ }
/* Ensure that existing good sessions are not overridden. */
if (!cp->discrs.remote_discr && bfd->ses_state != PTM_BFD_DOWN &&
@@ -1208,10 +1216,41 @@ int bp_set_tos(int sd, uint8_t value)
return 0;
}
+static bool bp_set_reuse_addr(int sd)
+{
+ int one = 1;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
+ zlog_warn("set-reuse-addr: setsockopt(SO_REUSEADDR, %d): %s",
+ one, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+static bool bp_set_reuse_port(int sd)
+{
+ int one = 1;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) {
+ zlog_warn("set-reuse-port: setsockopt(SO_REUSEPORT, %d): %s",
+ one, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+
static void bp_set_ipopts(int sd)
{
int rcvttl = BFD_RCV_TTL_VAL;
+ if (!bp_set_reuse_addr(sd))
+ zlog_fatal("set-reuse-addr: failed");
+
+ if (!bp_set_reuse_port(sd))
+ zlog_fatal("set-reuse-port: failed");
+
if (bp_set_ttl(sd, BFD_TTL_VAL) != 0)
zlog_fatal("set-ipopts: TTL configuration failed");
@@ -1453,6 +1492,12 @@ static void bp_set_ipv6opts(int sd)
int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL;
int ipv6_only = BFD_IPV6_ONLY_VAL;
+ if (!bp_set_reuse_addr(sd))
+ zlog_fatal("set-reuse-addr: failed");
+
+ if (!bp_set_reuse_port(sd))
+ zlog_fatal("set-reuse-port: failed");
+
if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1)
zlog_fatal(
"set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s",
diff --git a/lib/zebra.h b/lib/zebra.h
index 53ae5b4..930307f 100644
--- a/lib/zebra.h
+++ b/lib/zebra.h
@@ -114,6 +114,7 @@
#ifdef CRYPTO_OPENSSL
#include <openssl/evp.h>
#include <openssl/hmac.h>
+#include <openssl/fips.h>
#endif
#include "openbsd-tree.h"

View File

@ -1,25 +0,0 @@
diff --git a/lib/routemap.c b/lib/routemap.c
index a90443a..0b594b2 100644
--- a/lib/routemap.c
+++ b/lib/routemap.c
@@ -1649,9 +1649,9 @@ static struct list *route_map_get_index_list(struct route_node **rn,
*/
static struct route_map_index *
route_map_get_index(struct route_map *map, const struct prefix *prefix,
- route_map_object_t type, void *object, uint8_t *match_ret)
+ route_map_object_t type, void *object, enum route_map_cmd_result_t *match_ret)
{
- int ret = 0;
+ enum route_map_cmd_result_t ret = RMAP_NOMATCH;
struct list *candidate_rmap_list = NULL;
struct route_node *rn = NULL;
struct listnode *ln = NULL, *nn = NULL;
@@ -2399,7 +2399,7 @@ route_map_result_t route_map_apply(struct route_map *map,
if ((!map->optimization_disabled)
&& (map->ipv4_prefix_table || map->ipv6_prefix_table)) {
index = route_map_get_index(map, prefix, type, object,
- (uint8_t *)&match_ret);
+ &match_ret);
if (index) {
if (rmap_debug)
zlog_debug(

View File

@ -0,0 +1,47 @@
From 766eec1b7accffe2c04a5c9ebb14e9f487bb9f78 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Wed, 2 Nov 2022 13:24:48 -0400
Subject: [PATCH] bgpd: Ensure that bgp open message stream has enough data to
read
If a operator receives an invalid packet that is of insufficient size
then it is possible for BGP to assert during reading of the packet
instead of gracefully resetting the connection with the peer.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_packet.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 769f9613da8..72d6a923175 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -1386,8 +1386,27 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
|| CHECK_FLAG(peer->flags, PEER_FLAG_EXTENDED_OPT_PARAMS)) {
uint8_t opttype;
+ if (STREAM_READABLE(peer->curr) < 1) {
+ flog_err(
+ EC_BGP_PKT_OPEN,
+ "%s: stream does not have enough bytes for extended optional parameters",
+ peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+ BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+ return BGP_Stop;
+ }
+
opttype = stream_getc(peer->curr);
if (opttype == BGP_OPEN_NON_EXT_OPT_TYPE_EXTENDED_LENGTH) {
+ if (STREAM_READABLE(peer->curr) < 2) {
+ flog_err(
+ EC_BGP_PKT_OPEN,
+ "%s: stream does not have enough bytes to read the extended optional parameters optlen",
+ peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+ BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+ return BGP_Stop;
+ }
optlen = stream_getw(peer->curr);
SET_FLAG(peer->sflags,
PEER_STATUS_EXT_OPT_PARAMS_LENGTH);

View File

@ -0,0 +1,128 @@
From bcb6b58d9530173df41d3a3cbc4c600ee0b4b186 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Thu, 13 Jul 2023 22:32:03 +0300
Subject: [PATCH] bgpd: Use treat-as-withdraw for tunnel encapsulation
attribute
Before this path we used session reset method, which is discouraged by rfc7606.
Handle this as rfc requires.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgp_attr.c | 61 ++++++++++++++++++++-----------------------------
1 file changed, 25 insertions(+), 36 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index dcf0f4d47cfb..8c53191d680f 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1301,6 +1301,7 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
case BGP_ATTR_LARGE_COMMUNITIES:
case BGP_ATTR_ORIGINATOR_ID:
case BGP_ATTR_CLUSTER_LIST:
+ case BGP_ATTR_ENCAP:
return BGP_ATTR_PARSE_WITHDRAW;
case BGP_ATTR_MP_REACH_NLRI:
case BGP_ATTR_MP_UNREACH_NLRI:
@@ -2434,26 +2435,21 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args)
}
/* Parse Tunnel Encap attribute in an UPDATE */
-static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
- bgp_size_t length, /* IN: attr's length field */
- struct attr *attr, /* IN: caller already allocated */
- uint8_t flag, /* IN: attr's flags field */
- uint8_t *startp)
+static int bgp_attr_encap(struct bgp_attr_parser_args *args)
{
- bgp_size_t total;
uint16_t tunneltype = 0;
-
- total = length + (CHECK_FLAG(flag, BGP_ATTR_FLAG_EXTLEN) ? 4 : 3);
+ struct peer *const peer = args->peer;
+ struct attr *const attr = args->attr;
+ bgp_size_t length = args->length;
+ uint8_t type = args->type;
+ uint8_t flag = args->flags;
if (!CHECK_FLAG(flag, BGP_ATTR_FLAG_TRANS)
|| !CHECK_FLAG(flag, BGP_ATTR_FLAG_OPTIONAL)) {
- zlog_info(
- "Tunnel Encap attribute flag isn't optional and transitive %d",
- flag);
- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_ATTR_FLAG_ERR,
- startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute flag isn't optional and transitive %d",
+ flag);
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
if (BGP_ATTR_ENCAP == type) {
@@ -2461,12 +2457,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
uint16_t tlv_length;
if (length < 4) {
- zlog_info(
+ zlog_err(
"Tunnel Encap attribute not long enough to contain outer T,L");
- bgp_notify_send_with_data(
- peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
- return -1;
+ return bgp_attr_malformed(args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
tunneltype = stream_getw(BGP_INPUT(peer));
tlv_length = stream_getw(BGP_INPUT(peer));
@@ -2496,13 +2491,11 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
}
if (sublength > length) {
- zlog_info(
- "Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
- sublength, length);
- bgp_notify_send_with_data(
- peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute sub-tlv length %d exceeds remaining length %d",
+ sublength, length);
+ return bgp_attr_malformed(args,
+ BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
/* alloc and copy sub-tlv */
@@ -2550,13 +2543,10 @@ static int bgp_attr_encap(uint8_t type, struct peer *peer, /* IN */
if (length) {
/* spurious leftover data */
- zlog_info(
- "Tunnel Encap attribute length is bad: %d leftover octets",
- length);
- bgp_notify_send_with_data(peer, BGP_NOTIFY_UPDATE_ERR,
- BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
- startp, total);
- return -1;
+ zlog_err("Tunnel Encap attribute length is bad: %d leftover octets",
+ length);
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
+ args->total);
}
return 0;
@@ -3396,8 +3386,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
case BGP_ATTR_VNC:
#endif
case BGP_ATTR_ENCAP:
- ret = bgp_attr_encap(type, peer, length, attr, flag,
- startp);
+ ret = bgp_attr_encap(&attr_args);
break;
case BGP_ATTR_PREFIX_SID:
ret = bgp_attr_prefix_sid(&attr_args);

View File

@ -1,40 +0,0 @@
diff --git a/tools/frr.service b/tools/frr.service
index aa45f42..a3f0103 100644
--- a/tools/frr.service
+++ b/tools/frr.service
@@ -17,9 +17,9 @@ WatchdogSec=60s
RestartSec=5
Restart=on-abnormal
LimitNOFILE=1024
-ExecStart=/usr/lib/frr/frrinit.sh start
-ExecStop=/usr/lib/frr/frrinit.sh stop
-ExecReload=/usr/lib/frr/frrinit.sh reload
+ExecStart=/usr/libexec/frr/frrinit.sh start
+ExecStop=/usr/libexec/frr/frrinit.sh stop
+ExecReload=/usr/libexec/frr/frrinit.sh reload
[Install]
WantedBy=multi-user.target
diff --git a/tools/frrcommon.sh.in b/tools/frrcommon.sh.in
index 9a144b2..a334d95 100644
--- a/tools/frrcommon.sh.in
+++ b/tools/frrcommon.sh.in
@@ -59,6 +59,9 @@ chownfrr() {
[ -n "$FRR_USER" ] && chown "$FRR_USER" "$1"
[ -n "$FRR_GROUP" ] && chgrp "$FRR_GROUP" "$1"
[ -n "$FRR_CONFIG_MODE" ] && chmod "$FRR_CONFIG_MODE" "$1"
+ if [ -d "$1" ]; then
+ chmod gu+x "$1"
+ fi
}
vtysh_b () {
@@ -152,7 +155,7 @@ daemon_start() {
daemon_prep "$daemon" "$inst" || return 1
if test ! -d "$V_PATH"; then
mkdir -p "$V_PATH"
- chown frr "$V_PATH"
+ chownfrr "$V_PATH"
fi
eval wrap="\$${daemon}_wrap"

View File

@ -0,0 +1,70 @@
From 1117baca3c592877a4d8a13ed6a1d9bd83977487 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Fri, 30 Sep 2022 08:57:43 -0400
Subject: [PATCH] bgpd: Ensure FRR has enough data to read 2 bytes in
bgp_open_option_parse
In bgp_open_option_parse the code is checking that the
stream has at least 2 bytes to read ( the opt_type and
the opt_length). However if BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
is configured then FRR is reading 3 bytes. Which is not good
since the packet could be badly formateed. Ensure that
FRR has the appropriate data length to read the data.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_open.c | 35 ++++++++++++++++++++++++++++-------
1 file changed, 28 insertions(+), 7 deletions(-)
diff --git a/bgpd/bgp_open.c b/bgpd/bgp_open.c
index a760a7ca013..d1667fac261 100644
--- a/bgpd/bgp_open.c
+++ b/bgpd/bgp_open.c
@@ -1278,19 +1278,40 @@ int bgp_open_option_parse(struct peer *peer, uint16_t length,
uint8_t opt_type;
uint16_t opt_length;
- /* Must have at least an OPEN option header */
- if (STREAM_READABLE(s) < 2) {
+ /*
+ * Check that we can read the opt_type and fetch it
+ */
+ if (STREAM_READABLE(s) < 1) {
zlog_info("%s Option length error", peer->host);
bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
BGP_NOTIFY_OPEN_MALFORMED_ATTR);
return -1;
}
-
- /* Fetch option type and length. */
opt_type = stream_getc(s);
- opt_length = BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)
- ? stream_getw(s)
- : stream_getc(s);
+
+ /*
+ * Check the length of the stream to ensure that
+ * FRR can properly read the opt_length. Then read it
+ */
+ if (BGP_OPEN_EXT_OPT_PARAMS_CAPABLE(peer)) {
+ if (STREAM_READABLE(s) < 2) {
+ zlog_info("%s Option length error", peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+ BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+ return -1;
+ }
+
+ opt_length = stream_getw(s);
+ } else {
+ if (STREAM_READABLE(s) < 1) {
+ zlog_info("%s Option length error", peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_OPEN_ERR,
+ BGP_NOTIFY_OPEN_MALFORMED_ATTR);
+ return -1;
+ }
+
+ opt_length = stream_getc(s);
+ }
/* Option length check. */
if (STREAM_READABLE(s) < opt_length) {

View File

@ -1,77 +0,0 @@
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 9979c8b..1c24f90 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -785,6 +785,48 @@ def line_exist(lines, target_ctx_keys, target_line, exact_match=True):
return True
return False
+def delete_bgp_bfd(lines_to_add, lines_to_del):
+ """
+ When 'neighbor <peer> bfd profile <profile>' is present without a
+ 'neighbor <peer> bfd' line, FRR explicitily adds it to the running
+ configuration. When the new configuration drops the bfd profile
+ line, the user's intent is to delete any bfd configuration on the
+ peer. On reload, deleting the bfd profile line after the bfd line
+ will re-enable BFD with the default BFD profile. Move the bfd line
+ to the end, if it exists in the new configuration.
+
+ Example:
+
+ neighbor 10.0.0.1 bfd
+ neighbor 10.0.0.1 bfd profile bfd-profile-1
+
+ Move to end:
+ neighbor 10.0.0.1 bfd profile bfd-profile-1
+ ...
+
+ neighbor 10.0.0.1 bfd
+
+ """
+ lines_to_del_to_app = []
+ for (ctx_keys, line) in lines_to_del:
+ if (
+ ctx_keys[0].startswith("router bgp")
+ and line
+ and line.startswith("neighbor ")
+ ):
+ # 'no neighbor [peer] bfd>'
+ nb_bfd = "neighbor (\S+) .*bfd$"
+ re_nb_bfd = re.search(nb_bfd, line)
+ if re_nb_bfd:
+ lines_to_del_to_app.append((ctx_keys, line))
+
+ for (ctx_keys, line) in lines_to_del_to_app:
+ lines_to_del.remove((ctx_keys, line))
+ lines_to_del.append((ctx_keys, line))
+
+ return (lines_to_add, lines_to_del)
+
+
def check_for_exit_vrf(lines_to_add, lines_to_del):
# exit-vrf is a bit tricky. If the new config is missing it but we
@@ -1248,6 +1290,7 @@ def compare_context_objects(newconf, running):
for line in newconf_ctx.lines:
lines_to_add.append((newconf_ctx_keys, line))
+ (lines_to_add, lines_to_del) = delete_bgp_bfd(lines_to_add, lines_to_del)
(lines_to_add, lines_to_del) = check_for_exit_vrf(lines_to_add, lines_to_del)
(lines_to_add, lines_to_del) = ignore_delete_re_add_lines(lines_to_add, lines_to_del)
(lines_to_add, lines_to_del) = ignore_unconfigurable_lines(lines_to_add, lines_to_del)
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index b566b0e..1bd6249 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -686,9 +686,9 @@ void bgp_bfd_peer_config_write(struct vty *vty, struct peer *peer, char *addr)
if (!CHECK_FLAG(bfd_info->flags, BFD_FLAG_PARAM_CFG)
&& (bfd_info->type == BFD_TYPE_NOT_CONFIGURED)) {
- vty_out(vty, " neighbor %s bfd", addr);
+ vty_out(vty, " neighbor %s bfd\n", addr);
if (bfd_info->profile[0])
- vty_out(vty, " profile %s", bfd_info->profile);
+ vty_out(vty, " neighbor %s bfd profile %s", addr, bfd_info->profile);
vty_out(vty, "\n");
}

View File

@ -0,0 +1,255 @@
From edc3f63167fd95e4e70287743c9b252415c9336e Mon Sep 17 00:00:00 2001
From: Philippe Guibert <philippe.guibert@6wind.com>
Date: Thu, 7 Jul 2022 14:33:48 +0200
Subject: [PATCH] bfdd: allow l3vrf bfd sessions without udp leaking
Until now, when in vrf-lite mode, the BFD implementation
creates a single UDP socket and relies on the following
sysctl value to 1:
echo 1 > /proc/sys/net/ipv4/udp_l3mdev_accept
With this setting, the incoming BFD packets from a given
vrf, would leak to the default vrf, and would match the
UDP socket.
The drawback of this solution is that udp packets received
on a given vrf may leak to an other vrf. This may be a
security concern.
The commit addresses this issue by avoiding this leak
mechanism. An UDP socket is created for each vrf, and each
socket uses new setsockopt option: SO_REUSEADDR + SO_REUSEPORT.
With this option, the incoming UDP packets are distributed on
the available sockets. The impact of those options with l3mdev
devices is unknown. It has been observed that this option is not
needed, until the default vrf sockets are created.
To ensure the BFD packets are correctly routed to the appropriate
socket, a BPF filter has been put in place and attached to the
sockets : SO_ATTACH_REUSEPORT_CBPF. This option adds a criterium
to force the packet to choose a given socket. If initial criteria
from the default distribution algorithm were not good, at least
two sockets would be available, and the CBPF would force the
selection to the same socket. This would come to the situation
where an incoming packet would be processed on a different vrf.
The bpf code is the following one:
struct sock_filter code[] = {
{ BPF_RET | BPF_K, 0, 0, 0 },
};
struct sock_fprog p = {
.len = sizeof(code)/sizeof(struct sock_filter),
.filter = code,
};
if (setsockopt(sd, SOL_SOCKET, SO_ATTACH_REUSEPORT_CBPF, &p, sizeof(p))) {
zlog_warn("unable to set SO_ATTACH_REUSEPORT_CBPF on socket: %s",
strerror(errno));
return -1;
}
Some tests have been done with by creating vrf contexts, and by using
the below vtysh configuration:
ip route 2.2.2.2/32 10.126.0.2
vrf vrf2
ip route 2.2.2.2/32 10.126.0.2
!
interface ntfp2
ip address 10.126.0.1/24
!
interface ntfp3 vrf vrf4
ip address 10.126.0.1/24
!
interface ntfp2 vrf vrf1
ip address 10.126.0.1/24
!
interface ntfp2.100 vrf vrf2
ip address 10.126.0.1/24
!
interface ntfp2.200 vrf vrf3
ip address 10.126.0.1/24
!
line vty
!
bfd
peer 10.126.0.2 vrf vrf2
!
peer 10.126.0.2 vrf vrf3
!
peer 10.126.0.2
!
peer 10.126.0.2 vrf vrf4
!
peer 2.2.2.2 multihop local-address 1.1.1.1
!
peer 2.2.2.2 multihop local-address 1.1.1.1 vrf vrf2
transmit-interval 1500
receive-interval 1500
!
The results showed no issue related to packets received by
the wrong vrf. Even changing the udp_l3mdev_accept flag to
1 did not change the test results.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
---
bfdd/bfd.c | 66 +++++++++++++++++++++++------------------------
bfdd/bfd_packet.c | 45 ++++++++++++++++++++++++++++++++
2 files changed, 77 insertions(+), 34 deletions(-)
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 483beb1b17c..a1619263588 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -1950,40 +1950,38 @@ static int bfd_vrf_enable(struct vrf *vrf)
if (bglobal.debug_zebra)
zlog_debug("VRF enable add %s id %u", vrf->name, vrf->vrf_id);
- if (vrf->vrf_id == VRF_DEFAULT ||
- vrf_get_backend() == VRF_BACKEND_NETNS) {
- if (!bvrf->bg_shop)
- bvrf->bg_shop = bp_udp_shop(vrf);
- if (!bvrf->bg_mhop)
- bvrf->bg_mhop = bp_udp_mhop(vrf);
- if (!bvrf->bg_shop6)
- bvrf->bg_shop6 = bp_udp6_shop(vrf);
- if (!bvrf->bg_mhop6)
- bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
- if (!bvrf->bg_echo)
- bvrf->bg_echo = bp_echo_socket(vrf);
- if (!bvrf->bg_echov6)
- bvrf->bg_echov6 = bp_echov6_socket(vrf);
-
- if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop, &bvrf->bg_ev[0]);
- if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop, &bvrf->bg_ev[1]);
- if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_shop6, &bvrf->bg_ev[2]);
- if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_mhop6, &bvrf->bg_ev[3]);
- if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echo, &bvrf->bg_ev[4]);
- if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
- thread_add_read(master, bfd_recv_cb, bvrf,
- bvrf->bg_echov6, &bvrf->bg_ev[5]);
- }
+ if (!bvrf->bg_shop)
+ bvrf->bg_shop = bp_udp_shop(vrf);
+ if (!bvrf->bg_mhop)
+ bvrf->bg_mhop = bp_udp_mhop(vrf);
+ if (!bvrf->bg_shop6)
+ bvrf->bg_shop6 = bp_udp6_shop(vrf);
+ if (!bvrf->bg_mhop6)
+ bvrf->bg_mhop6 = bp_udp6_mhop(vrf);
+ if (!bvrf->bg_echo)
+ bvrf->bg_echo = bp_echo_socket(vrf);
+ if (!bvrf->bg_echov6)
+ bvrf->bg_echov6 = bp_echov6_socket(vrf);
+
+ if (!bvrf->bg_ev[0] && bvrf->bg_shop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop,
+ &bvrf->bg_ev[0]);
+ if (!bvrf->bg_ev[1] && bvrf->bg_mhop != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop,
+ &bvrf->bg_ev[1]);
+ if (!bvrf->bg_ev[2] && bvrf->bg_shop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_shop6,
+ &bvrf->bg_ev[2]);
+ if (!bvrf->bg_ev[3] && bvrf->bg_mhop6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_mhop6,
+ &bvrf->bg_ev[3]);
+ if (!bvrf->bg_ev[4] && bvrf->bg_echo != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echo,
+ &bvrf->bg_ev[4]);
+ if (!bvrf->bg_ev[5] && bvrf->bg_echov6 != -1)
+ thread_add_read(master, bfd_recv_cb, bvrf, bvrf->bg_echov6,
+ &bvrf->bg_ev[5]);
+
if (vrf->vrf_id != VRF_DEFAULT) {
bfdd_zclient_register(vrf->vrf_id);
bfdd_sessions_enable_vrf(vrf);
diff --git a/bfdd/bfd_packet.c b/bfdd/bfd_packet.c
index d34d6427628..054a9bfbf21 100644
--- a/bfdd/bfd_packet.c
+++ b/bfdd/bfd_packet.c
@@ -876,6 +876,14 @@ void bfd_recv_cb(struct thread *t)
"no session found");
return;
}
+ /*
+ * We may have a situation where received packet is on wrong vrf
+ */
+ if (bfd && bfd->vrf && bfd->vrf != bvrf->vrf) {
+ cp_debug(is_mhop, &peer, &local, ifindex, vrfid,
+ "wrong vrfid.");
+ return;
+ }
/* Ensure that existing good sessions are not overridden. */
if (!cp->discrs.remote_discr && bfd->ses_state != PTM_BFD_DOWN &&
@@ -1208,10 +1216,41 @@ int bp_set_tos(int sd, uint8_t value)
return 0;
}
+static bool bp_set_reuse_addr(int sd)
+{
+ int one = 1;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)) == -1) {
+ zlog_warn("set-reuse-addr: setsockopt(SO_REUSEADDR, %d): %s",
+ one, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+static bool bp_set_reuse_port(int sd)
+{
+ int one = 1;
+
+ if (setsockopt(sd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) == -1) {
+ zlog_warn("set-reuse-port: setsockopt(SO_REUSEPORT, %d): %s",
+ one, strerror(errno));
+ return false;
+ }
+ return true;
+}
+
+
static void bp_set_ipopts(int sd)
{
int rcvttl = BFD_RCV_TTL_VAL;
+ if (!bp_set_reuse_addr(sd))
+ zlog_fatal("set-reuse-addr: failed");
+
+ if (!bp_set_reuse_port(sd))
+ zlog_fatal("set-reuse-port: failed");
+
if (bp_set_ttl(sd, BFD_TTL_VAL) != 0)
zlog_fatal("set-ipopts: TTL configuration failed");
@@ -1453,6 +1492,12 @@ static void bp_set_ipv6opts(int sd)
int ipv6_pktinfo = BFD_IPV6_PKT_INFO_VAL;
int ipv6_only = BFD_IPV6_ONLY_VAL;
+ if (!bp_set_reuse_addr(sd))
+ zlog_fatal("set-reuse-addr: failed");
+
+ if (!bp_set_reuse_port(sd))
+ zlog_fatal("set-reuse-port: failed");
+
if (bp_set_ttlv6(sd, BFD_TTL_VAL) == -1)
zlog_fatal(
"set-ipv6opts: setsockopt(IPV6_UNICAST_HOPS, %d): %s",

View File

@ -1,117 +0,0 @@
From 4b793d1eb35ab5794db12725a28fcdb4fef23af7 Mon Sep 17 00:00:00 2001
From: Igor Ryzhov <iryzhov@nfware.com>
Date: Thu, 1 Apr 2021 15:29:18 +0300
Subject: [PATCH] bfdd: remove profiles when removing bfd node
Fixes #8379.
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
---
bfdd/bfd.c | 8 ++++++++
bfdd/bfd.h | 1 +
bfdd/bfdd_nb_config.c | 1 +
3 files changed, 10 insertions(+)
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index c966efd8ea71..cf292a836354 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -1889,6 +1889,14 @@ void bfd_sessions_remove_manual(void)
hash_iterate(bfd_key_hash, _bfd_session_remove_manual, NULL);
}
+void bfd_profiles_remove(void)
+{
+ struct bfd_profile *bp;
+
+ while ((bp = TAILQ_FIRST(&bplist)) != NULL)
+ bfd_profile_free(bp);
+}
+
/*
* Profile related hash functions.
*/
diff --git a/bfdd/bfd.h b/bfdd/bfd.h
index af3f92d6a8f8..9ee1da728717 100644
--- a/bfdd/bfd.h
+++ b/bfdd/bfd.h
@@ -596,6 +596,7 @@ void bfd_session_free(struct bfd_session *bs);
const struct bfd_session *bfd_session_next(const struct bfd_session *bs,
bool mhop);
void bfd_sessions_remove_manual(void);
+void bfd_profiles_remove(void);
/**
* Set the BFD session echo state.
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 0046bc625b45..77f8cbd09c07 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -203,6 +203,7 @@ int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
case NB_EV_APPLY:
bfd_sessions_remove_manual();
+ bfd_profiles_remove();
break;
case NB_EV_ABORT:
diff --git a/bfdd/bfdd_nb_config.c b/bfdd/bfdd_nb_config.c
index 77f8cbd09c07..4030e2eefa50 100644
--- a/bfdd/bfdd_nb_config.c
+++ b/bfdd/bfdd_nb_config.c
@@ -186,7 +186,15 @@ static int bfd_session_destroy(enum nb_event event,
*/
int bfdd_bfd_create(struct nb_cb_create_args *args)
{
- /* NOTHING */
+ if (args->event != NB_EV_APPLY)
+ return NB_OK;
+
+ /*
+ * Set any non-NULL value to be able to call
+ * nb_running_unset_entry in bfdd_bfd_destroy.
+ */
+ nb_running_set_entry(args->dnode, (void *)0x1);
+
return NB_OK;
}
@@ -202,6 +210,12 @@ int bfdd_bfd_destroy(struct nb_cb_destroy_args *args)
return NB_OK;
case NB_EV_APPLY:
+ /*
+ * We need to call this to unset pointers from
+ * the child nodes - sessions and profiles.
+ */
+ nb_running_unset_entry(args->dnode);
+
bfd_sessions_remove_manual();
bfd_profiles_remove();
break;
diff --git a/bfdd/bfdd_cli.c b/bfdd/bfdd_cli.c
index b64e36b36a44..5a844e56e121 100644
--- a/bfdd/bfdd_cli.c
+++ b/bfdd/bfdd_cli.c
@@ -486,7 +486,7 @@ void bfd_cli_show_echo_interval(struct vty *vty, struct lyd_node *dnode,
* Profile commands.
*/
DEFPY_YANG_NOSH(bfd_profile, bfd_profile_cmd,
- "profile WORD$name",
+ "profile BFDPROF$name",
BFD_PROFILE_STR
BFD_PROFILE_NAME_STR)
{
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 74f13e1a44e8..cf1811bb1f2f 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -1959,7 +1959,7 @@ DEFUNSH(VTYSH_BFDD, bfd_peer_enter, bfd_peer_enter_cmd,
}
DEFUNSH(VTYSH_BFDD, bfd_profile_enter, bfd_profile_enter_cmd,
- "profile WORD",
+ "profile BFDPROF",
BFD_PROFILE_STR
BFD_PROFILE_NAME_STR)
{

View File

@ -1,48 +0,0 @@
From 0f9e4c4a36cf2b0dd585a7ef97acccb8eebdf7bd Mon Sep 17 00:00:00 2001
From: Chirag Shah <chirag@nvidia.com>
Date: Mon, 25 Jan 2021 11:44:56 -0800
Subject: [PATCH] lib: fix a crash in plist update
Problem:
Prefix-list with mulitiple rules, an update to
a rule/sequence with different prefix/prefixlen
reset prefix-list next-base pointer to avoid
having stale value.
In some case the old next-bast's reference leads
to an assert in tri (trie_install_fn ) add.
bt:
(object=0x55576a4c8a00, updptr=0x55576a4b97e0) at lib/plist.c:560
(plist=0x55576a4a1770, pentry=0x55576a4c8a00) at lib/plist.c:585
(ple=0x55576a4c8a00) at lib/plist.c:745
(args=0x7fffe04beb50) at lib/filter_nb.c:1181
Solution:
Reset prefix-list next-base pointer whenver a
sequence/rule is updated.
Ticket:CM-33109
Testing Done:
Signed-off-by: Chirag Shah <chirag@nvidia.com>
Signed-off-by: Rafael Zalamena <rzalamena@opensourcerouting.org>
(cherry picked from commit f7f101156eb0e225f375f12cf4f863ebbe3fed03)
---
lib/plist.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/lib/plist.c b/lib/plist.c
index 981e86e2a..c746d1946 100644
--- a/lib/plist.c
+++ b/lib/plist.c
@@ -684,6 +684,7 @@ void prefix_list_entry_update_start(struct prefix_list_entry *ple)
if (pl->head || pl->tail || pl->desc)
pl->master->recent = pl;
+ ple->next_best = NULL;
ple->installed = false;
}
--
2.41.0

View File

@ -1,47 +0,0 @@
From 4fc5dafd1c8167a98e3a5f51efc1ea5092513364 Mon Sep 17 00:00:00 2001
From: rgirada <rgirada@vmware.com>
Date: Thu, 18 Feb 2021 20:15:40 -0800
Subject: [PATCH] lib: Routemap is not getting applied upon changing the
routemap action
Description:
This looks broken after NB changes in routemap. When routemap
action modified from permit to deny, it is expected to apply
the new action on the filtered routes before the action in the
routemap data structure has been changed. But currently this is
not handled by the corresponding northbound API.
Signed-off-by: Rajesh Girada <rgirada@vmware.com>
---
lib/routemap_northbound.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/lib/routemap_northbound.c b/lib/routemap_northbound.c
index db06e9caac75..3473ca2aea8c 100644
--- a/lib/routemap_northbound.c
+++ b/lib/routemap_northbound.c
@@ -271,6 +271,7 @@ lib_route_map_entry_description_destroy(struct nb_cb_destroy_args *args)
static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args)
{
struct route_map_index *rmi;
+ struct route_map *map;
switch (args->event) {
case NB_EV_VALIDATE:
@@ -281,7 +282,15 @@ static int lib_route_map_entry_action_modify(struct nb_cb_modify_args *args)
case NB_EV_APPLY:
rmi = nb_running_get_entry(args->dnode, NULL, true);
rmi->type = yang_dnode_get_enum(args->dnode, NULL);
- /* TODO: notify? */
+ map = rmi->map;
+
+ /* Execute event hook. */
+ if (route_map_master.event_hook) {
+ (*route_map_master.event_hook)(map->name);
+ route_map_notify_dependencies(map->name,
+ RMAP_EVENT_CALL_ADDED);
+ }
+
break;
}

View File

@ -1,76 +0,0 @@
From b08afc81c60607a4f736f418f2e3eb06087f1a35 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Fri, 20 Oct 2023 17:49:18 +0300
Subject: [PATCH] bgpd: Handle MP_REACH_NLRI malformed packets with session
reset
Avoid crashing bgpd.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgp_attr.c | 6 +-----
bgpd/bgp_attr.h | 1 -
bgpd/bgp_packet.c | 6 +-----
3 files changed, 2 insertions(+), 11 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 6925aff727e2..e7bb42a5d989 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2421,7 +2421,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
mp_update->afi = afi;
mp_update->safi = safi;
- return BGP_ATTR_PARSE_EOR;
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_ATTR, 0);
}
mp_update->afi = afi;
@@ -3759,10 +3759,6 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
goto done;
}
- if (ret == BGP_ATTR_PARSE_EOR) {
- goto done;
- }
-
if (ret == BGP_ATTR_PARSE_ERROR) {
flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
"%s: Attribute %s, parse error", peer->host,
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index 961e5f122470..fc347e7a1b4b 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -364,7 +364,6 @@ enum bgp_attr_parse_ret {
/* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR
*/
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
- BGP_ATTR_PARSE_EOR = -4,
BGP_ATTR_PARSE_MISSING_MANDATORY = -4,
} bgp_attr_parse_ret_t;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index b585591e2f69..5ecf343b6657 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2397,8 +2397,7 @@ static int bgp_update_receive(struct peer_connection *connection,
* Non-MP IPv4/Unicast EoR is a completely empty UPDATE
* and MP EoR should have only an empty MP_UNREACH
*/
- if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0)
- || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) {
+ if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) {
afi_t afi = 0;
safi_t safi;
struct graceful_restart_info *gr_info;
@@ -2419,9 +2418,6 @@ static int bgp_update_receive(struct peer_connection *connection,
&& nlris[NLRI_MP_WITHDRAW].length == 0) {
afi = nlris[NLRI_MP_WITHDRAW].afi;
safi = nlris[NLRI_MP_WITHDRAW].safi;
- } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) {
- afi = nlris[NLRI_MP_UPDATE].afi;
- safi = nlris[NLRI_MP_UPDATE].safi;
}
if (afi && peer->afc[afi][safi]) {

View File

@ -1,60 +0,0 @@
From d8482bf011cb2b173e85b65b4bf3d5061250cdb9 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Mon, 23 Oct 2023 23:34:10 +0300
Subject: [PATCH] bgpd: Check mandatory attributes more carefully for UPDATE
message
If we send a crafted BGP UPDATE message without mandatory attributes, we do
not check if the length of the path attributes is zero or not. We only check
if attr->flag is at least set or not. Imagine we send only unknown transit
attribute, then attr->flag is always 0. Also, this is true only if graceful-restart
capability is received.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgp_attr.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 26fd3de..bcc4424 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -3400,7 +3400,8 @@ bgp_attr_unknown(struct bgp_attr_parser_args *args)
}
/* Well-known attribute check. */
-static int bgp_attr_check(struct peer *peer, struct attr *attr)
+static int bgp_attr_check(struct peer *peer, struct attr *attr,
+ bgp_size_t length)
{
uint8_t type = 0;
@@ -3409,7 +3410,8 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr)
* we will pass it to be processed as a normal UPDATE without mandatory
* attributes, that could lead to harmful behavior.
*/
- if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
+ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag &&
+ !length)
return BGP_ATTR_PARSE_WITHDRAW;
if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
@@ -3462,7 +3464,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
bgp_attr_parse_ret_t ret;
uint8_t flag = 0;
uint8_t type = 0;
- bgp_size_t length;
+ bgp_size_t length = 0;
uint8_t *startp, *endp;
uint8_t *attr_endp;
uint8_t seen[BGP_ATTR_BITMAP_SIZE];
@@ -3216,7 +3218,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
}
/* Check all mandatory well-known attributes are present */
- if ((ret = bgp_attr_check(peer, attr)) < 0)
+ if ((ret = bgp_attr_check(peer, attr, length)) < 0)
goto done;
/*

View File

@ -1,150 +0,0 @@
From 06431bfa7570f169637ebb5898f0b0cc3b010802 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Tue, 6 Dec 2022 10:23:11 -0500
Subject: [PATCH] bgpd: Ensure stream received has enough data
BGP_PREFIX_SID_SRV6_L3_SERVICE attributes must not
fully trust the length value specified in the nlri.
Always ensure that the amount of data we need to read
can be fullfilled.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_attr.c | 79 ++++++++++++++++---------------------------------
1 file changed, 25 insertions(+), 54 deletions(-)
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index c35e45275c9b..5b06bc391375 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -2927,9 +2927,21 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
uint16_t endpoint_behavior;
char buf[BUFSIZ];
+ /*
+ * Check that we actually have at least as much data as
+ * specified by the length field
+ */
+ if (STREAM_READABLE(peer->curr) < length) {
+ flog_err(
+ EC_BGP_ATTR_LEN,
+ "Prefix SID specifies length %hu, but only %zu bytes remain",
+ length, STREAM_READABLE(peer->curr));
+ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
+ }
+
if (type == BGP_PREFIX_SID_LABEL_INDEX) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
+ if (length != BGP_PREFIX_SID_LABEL_INDEX_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID label index length is %hu instead of %u",
length, BGP_PREFIX_SID_LABEL_INDEX_LENGTH);
@@ -2951,12 +2963,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
/* Store label index; subsequently, we'll check on
* address-family */
attr->label_index = label_index;
- }
-
- /* Placeholder code for the IPv6 SID type */
- else if (type == BGP_PREFIX_SID_IPV6) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_IPV6_LENGTH) {
+ } else if (type == BGP_PREFIX_SID_IPV6) {
+ if (length != BGP_PREFIX_SID_IPV6_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID IPv6 length is %hu instead of %u",
length, BGP_PREFIX_SID_IPV6_LENGTH);
@@ -2970,10 +2978,7 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
stream_getw(peer->curr);
stream_get(&ipv6_sid, peer->curr, 16);
- }
-
- /* Placeholder code for the Originator SRGB type */
- else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
+ } else if (type == BGP_PREFIX_SID_ORIGINATOR_SRGB) {
/*
* ietf-idr-bgp-prefix-sid-05:
* Length is the total length of the value portion of the
@@ -2998,19 +3003,6 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
args->total);
}
- /*
- * Check that we actually have at least as much data as
- * specified by the length field
- */
- if (STREAM_READABLE(peer->curr) < length) {
- flog_err(EC_BGP_ATTR_LEN,
- "Prefix SID Originator SRGB specifies length %hu, but only %zu bytes remain",
- length, STREAM_READABLE(peer->curr));
- return bgp_attr_malformed(
- args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
- }
-
/*
* Check that the portion of the TLV containing the sequence of
* SRGBs corresponds to a multiple of the SRGB size; to get
@@ -3034,12 +3026,8 @@ bgp_attr_psid_sub(uint8_t type, uint16_t length,
stream_get(&srgb_base, peer->curr, 3);
stream_get(&srgb_range, peer->curr, 3);
}
- }
-
- /* Placeholder code for the VPN-SID Service type */
- else if (type == BGP_PREFIX_SID_VPN_SID) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
+ } else if (type == BGP_PREFIX_SID_VPN_SID) {
+ if (length != BGP_PREFIX_SID_VPN_SID_LENGTH) {
flog_err(EC_BGP_ATTR_LEN,
"Prefix SID VPN SID length is %hu instead of %u",
length, BGP_PREFIX_SID_VPN_SID_LENGTH);
@@ -2601,18 +2589,13 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
sizeof(struct bgp_attr_srv6_vpn));
attr->srv6_vpn->sid_flags = sid_flags;
sid_copy(&attr->srv6_vpn->sid, &ipv6_sid);
- }
-
- /* Placeholder code for the SRv6 L3 Service type */
- else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
- if (STREAM_READABLE(peer->curr) < length
- || length != BGP_PREFIX_SID_SRV6_L3_SERVICE_LENGTH) {
- flog_err(EC_BGP_ATTR_LEN,
- "Prefix SID SRv6 L3-Service length is %hu instead of %u",
- length, BGP_PREFIX_SID_SRV6_L3_SERVICE_LENGTH);
- return bgp_attr_malformed(args,
- BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
+ } else if (type == BGP_PREFIX_SID_SRV6_L3_SERVICE) {
+ if (STREAM_READABLE(peer->curr) < 1) {
+ flog_err(EC_BGP_ATTR_LEN,
+ "Prefix SID SRV6 L3 Service not enough data left, it must be at least 1 byte");
+ return bgp_attr_malformed(
+ args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
+ args->total);
}
/* Parse L3-SERVICE Sub-TLV */
@@ -2647,17 +2630,6 @@ static bgp_attr_parse_ret_t bgp_attr_psid_sub(uint8_t type, uint16_t length,
/* Placeholder code for Unsupported TLV */
else {
-
- if (STREAM_READABLE(peer->curr) < length) {
- flog_err(
- EC_BGP_ATTR_LEN,
- "Prefix SID SRv6 length is %hu - too long, only %zu remaining in this UPDATE",
- length, STREAM_READABLE(peer->curr));
- return bgp_attr_malformed(
- args, BGP_NOTIFY_UPDATE_ATTR_LENG_ERR,
- args->total);
- }
-
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug(
"%s attr Prefix-SID sub-type=%u is not supported, skipped",

View File

@ -1,34 +0,0 @@
From cfd04dcb3e689754a72507d086ba3b9709fc5ed8 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Wed, 5 Apr 2023 14:57:05 -0400
Subject: [PATCH] bgpd: Limit flowspec to no attribute means a implicit
withdrawal
All other parsing functions done from bgp_nlri_parse() assume
no attributes == an implicit withdrawal. Let's move
bgp_nlri_parse_flowspec() into the same alignment.
Reported-by: Matteo Memelli <mmemelli@amazon.it>
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_flowspec.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
index f9debe43cd45..5e1be21402dc 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -98,6 +98,13 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
afi = packet->afi;
safi = packet->safi;
+ /*
+ * All other AFI/SAFI's treat no attribute as a implicit
+ * withdraw. Flowspec should as well.
+ */
+ if (!attr)
+ withdraw = 1;
+
if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) {
flog_err(EC_BGP_FLOWSPEC_PACKET,
"BGP flowspec nlri length maximum reached (%u)",

View File

@ -1,267 +0,0 @@
From 2cf7651f0b1b0123dc5568ebad00ac84a9b3c348 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Wed, 2 Feb 2022 13:28:42 -0500
Subject: [PATCH] zebra: Make netlink buffer reads resizeable when needed
Currently when the kernel sends netlink messages to FRR
the buffers to receive this data is of fixed length.
The kernel, with certain configurations, will send
netlink messages that are larger than this fixed length.
This leads to situations where, on startup, zebra gets
really confused about the state of the kernel. Effectively
the current algorithm is this:
read up to buffer in size
while (data to parse)
get netlink message header, look at size
parse if you can
The problem is that there is a 32k buffer we read.
We get the first message that is say 1k in size,
subtract that 1k to 31k left to parse. We then
get the next header and notice that the length
of the message is 33k. Which is obviously larger
than what we read in. FRR has no recover mechanism
nor is there a way to know, a priori, what the maximum
size the kernel will send us.
Modify FRR to look at the kernel message and see if the
buffer is large enough, if not, make it large enough to
read in the message.
This code has to be per netlink socket because of the usage
of pthreads. So add to `struct nlsock` the buffer and current
buffer length. Growing it as necessary.
Fixes: #10404
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
zebra/kernel_netlink.c | 68 +++++++++++++++++++++++++-----------------
zebra/kernel_netlink.h | 2 +-
zebra/zebra_dplane.c | 4 +++
zebra/zebra_ns.h | 3 ++
4 files changed, 49 insertions(+), 28 deletions(-)
diff --git a/zebra/kernel_netlink.h b/zebra/kernel_netlink.h
index ae88f3372b1c..9421ea1c611a 100644
--- a/zebra/kernel_netlink.h
+++ b/zebra/kernel_netlink.h
@@ -96,7 +96,7 @@ extern const char *nl_family_to_str(uint8_t family);
extern const char *nl_rttype_to_str(uint8_t rttype);
extern int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
- const struct nlsock *nl,
+ struct nlsock *nl,
const struct zebra_dplane_info *dp_info,
int count, int startup);
extern int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns, int startup);
diff --git a/zebra/zebra_ns.h b/zebra/zebra_ns.h
index 0519e1d5b33d..7a0ffbc1ee6f 100644
--- a/zebra/zebra_ns.h
+++ b/zebra/zebra_ns.h
@@ -39,6 +39,9 @@ struct nlsock {
int seq;
struct sockaddr_nl snl;
char name[64];
+
+ uint8_t *buf;
+ size_t buflen;
};
#endif
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index b8eaeb1..14a40a9 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -90,8 +90,6 @@
*/
#define NL_DEFAULT_BATCH_SEND_THRESHOLD (15 * NL_PKT_BUF_SIZE)
-#define NL_BATCH_RX_BUFSIZE NL_RCV_PKT_BUF_SIZE
-
static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
{RTM_DELROUTE, "RTM_DELROUTE"},
{RTM_GETROUTE, "RTM_GETROUTE"},
@@ -164,8 +162,6 @@ DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers")
size_t nl_batch_tx_bufsize;
char *nl_batch_tx_buf;
-char nl_batch_rx_buf[NL_BATCH_RX_BUFSIZE];
-
_Atomic uint32_t nl_batch_bufsize = NL_DEFAULT_BATCH_BUFSIZE;
_Atomic uint32_t nl_batch_send_threshold = NL_DEFAULT_BATCH_SEND_THRESHOLD;
@@ -322,6 +318,9 @@ static int netlink_socket(struct nlsock *nl, unsigned long groups,
nl->snl = snl;
nl->sock = sock;
+ nl->buflen = NL_RCV_PKT_BUF_SIZE;
+ nl->buf = XMALLOC(MTYPE_NL_BUF, nl->buflen);
+
return ret;
}
@@ -729,19 +728,29 @@ static ssize_t netlink_send_msg(const struct nlsock *nl, void *buf,
*
* Returns -1 on error, 0 if read would block or the number of bytes received.
*/
-static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,
- void *buf, size_t buflen)
+static int netlink_recv_msg(struct nlsock *nl, struct msghdr *msg)
{
struct iovec iov;
int status;
- iov.iov_base = buf;
- iov.iov_len = buflen;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
+ iov.iov_base = nl->buf;
+ iov.iov_len = nl->buflen;
+ msg->msg_iov = &iov;
+ msg->msg_iovlen = 1;
do {
- status = recvmsg(nl->sock, &msg, 0);
+ int bytes;
+
+ bytes = recv(nl->sock, NULL, 0, MSG_PEEK | MSG_TRUNC);
+
+ if (bytes >= 0 && (size_t)bytes > nl->buflen) {
+ nl->buf = XREALLOC(MTYPE_NL_BUF, nl->buf, bytes);
+ nl->buflen = bytes;
+ iov.iov_base = nl->buf;
+ iov.iov_len = nl->buflen;
+ }
+
+ status = recvmsg(nl->sock, msg, 0);
} while (status == -1 && errno == EINTR);
if (status == -1) {
@@ -761,10 +770,10 @@ static int netlink_recv_msg(const struct nlsock *nl, struct msghdr msg,
return -1;
}
- if (msg.msg_namelen != sizeof(struct sockaddr_nl)) {
+ if (msg->msg_namelen != sizeof(struct sockaddr_nl)) {
flog_err(EC_ZEBRA_NETLINK_LENGTH_ERROR,
"%s sender address length error: length %d", nl->name,
- msg.msg_namelen);
+ msg->msg_namelen);
return -1;
}
@@ -873,8 +882,7 @@ static int netlink_parse_error(const struct nlsock *nl, struct nlmsghdr *h,
* the filter.
*/
int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
- const struct nlsock *nl,
- const struct zebra_dplane_info *zns,
+ struct nlsock *nl, const struct zebra_dplane_info *zns,
int count, int startup)
{
int status;
@@ -883,7 +891,6 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
int read_in = 0;
while (1) {
- char buf[NL_RCV_PKT_BUF_SIZE];
struct sockaddr_nl snl;
struct msghdr msg = {.msg_name = (void *)&snl,
.msg_namelen = sizeof(snl)};
@@ -892,14 +899,14 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
if (count && read_in >= count)
return 0;
- status = netlink_recv_msg(nl, msg, buf, sizeof(buf));
+ status = netlink_recv_msg(nl, &msg);
if (status == -1)
return -1;
else if (status == 0)
break;
read_in++;
- for (h = (struct nlmsghdr *)buf;
+ for (h = (struct nlmsghdr *)nl->buf;
(status >= 0 && NLMSG_OK(h, (unsigned int)status));
h = NLMSG_NEXT(h, status)) {
/* Finish of reading. */
@@ -976,10 +983,10 @@ int netlink_parse_info(int (*filter)(struct nlmsghdr *, ns_id_t, int),
*/
static int
netlink_talk_info(int (*filter)(struct nlmsghdr *, ns_id_t, int startup),
- struct nlmsghdr *n, const struct zebra_dplane_info *dp_info,
+ struct nlmsghdr *n, struct zebra_dplane_info *dp_info,
int startup)
{
- const struct nlsock *nl;
+ struct nlsock *nl;
nl = &(dp_info->nls);
n->nlmsg_seq = nl->seq;
@@ -1067,12 +1074,11 @@ static int nl_batch_read_resp(struct nl_batch *bth)
* message at a time.
*/
while (true) {
- status = netlink_recv_msg(nl, msg, nl_batch_rx_buf,
- sizeof(nl_batch_rx_buf));
+ status = netlink_recv_msg(nl, &msg);
if (status == -1 || status == 0)
return status;
- h = (struct nlmsghdr *)nl_batch_rx_buf;
+ h = (struct nlmsghdr *)nl->buf;
ignore_msg = false;
seq = h->nlmsg_seq;
/*
@@ -1506,11 +1512,15 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
if (zns->netlink.sock >= 0) {
close(zns->netlink.sock);
zns->netlink.sock = -1;
+ XFREE(MTYPE_NL_BUF, zns->netlink.buf);
+ zns->netlink.buflen = 0;
}
if (zns->netlink_cmd.sock >= 0) {
close(zns->netlink_cmd.sock);
zns->netlink_cmd.sock = -1;
+ XFREE(MTYPE_NL_BUF, zns->netlink_cmd.buf);
+ zns->netlink_cmd.buflen = 0;
}
/* During zebra shutdown, we need to leave the dataplane socket
@@ -1520,6 +1530,8 @@ void kernel_terminate(struct zebra_ns *zns, bool complete)
if (zns->netlink_dplane.sock >= 0) {
close(zns->netlink_dplane.sock);
zns->netlink_dplane.sock = -1;
+ XFREE(MTYPE_NL_BUF, zns->netlink_dplane.buf);
+ zns->netlink_dplane.buflen = 0;
}
}
}
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 14a40a9..2b566d4 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -779,7 +779,7 @@ static int netlink_recv_msg(struct nlsock *nl, struct msghdr *msg)
if (IS_ZEBRA_DEBUG_KERNEL_MSGDUMP_RECV) {
zlog_debug("%s: << netlink message dump [recv]", __func__);
- zlog_hexdump(buf, status);
+ zlog_hexdump(nl->buf, status);
}
return status;
diff --git a/zebra/kernel_netlink.c b/zebra/kernel_netlink.c
index 2b566d4..0564a6b 100644
--- a/zebra/kernel_netlink.c
+++ b/zebra/kernel_netlink.c
@@ -1060,7 +1060,7 @@ static int nl_batch_read_resp(struct nl_batch *bth)
struct sockaddr_nl snl;
struct msghdr msg = {};
int status, seq;
- const struct nlsock *nl;
+ struct nlsock *nl;
struct zebra_dplane_ctx *ctx;
bool ignore_msg;

View File

@ -1,4 +1,4 @@
From 7404a914b0cafe046703c8381903a80d3def8f8b Mon Sep 17 00:00:00 2001
From ab362eae68edec12c175d9bc488bcc3f8b73d36f Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Fri, 3 Mar 2023 21:58:33 -0500
Subject: [PATCH] bgpd: Fix use beyond end of stream of labeled unicast parsing
@ -8,12 +8,13 @@ beyond the end of the stream.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
(cherry picked from commit 7404a914b0cafe046703c8381903a80d3def8f8b)
---
bgpd/bgp_label.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 0cad119af101..c4a5277553ba 100644
index 38f34a892702..64d1ff70ca22 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -297,6 +297,9 @@ static int bgp_nlri_get_labels(struct peer *peer, uint8_t *pnt, uint8_t plen,

View File

@ -24,9 +24,9 @@ diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 1473dc772502..75aa2ac7cce6 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -3399,15 +3399,6 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr,
@@ -3086,15 +3086,6 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr)
if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag)
return BGP_ATTR_PARSE_PROCEED;
return BGP_ATTR_PARSE_WITHDRAW;
- /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
- to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
@ -40,7 +40,7 @@ index 1473dc772502..75aa2ac7cce6 100644
if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
type = BGP_ATTR_ORIGIN;
@@ -3426,6 +3417,16 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr,
@@ -3113,6 +3104,16 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr)
&& !CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
type = BGP_ATTR_LOCAL_PREF;
@ -61,19 +61,19 @@ diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index fc347e7a1b4b..d30155e6dba0 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -364,6 +364,7 @@ enum bgp_attr_parse_ret {
*/
@@ -379,6 +379,7 @@ enum bgp_attr_parse_ret {
*/
BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3,
BGP_ATTR_PARSE_EOR = -4,
+ BGP_ATTR_PARSE_MISSING_MANDATORY = -4,
} bgp_attr_parse_ret_t;
+ BGP_ATTR_PARSE_MISSING_MANDATORY = -5,
};
struct bpacket_attr_vec_arr;
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index a7514a26aa64..5dc35157ebf6 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2359,7 +2359,12 @@ static int bgp_update_receive(struct peer_connection *connection,
@@ -1873,7 +1873,12 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
/* Network Layer Reachability Information. */
update_len = end - stream_pnt(s);

View File

@ -73,7 +73,7 @@ diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index cf2dbe65b805..1473dc772502 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -3391,9 +3391,12 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr,
@@ -3079,9 +3079,12 @@ static int bgp_attr_check(struct peer *peer, struct attr *attr)
uint8_t type = 0;
/* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an
@ -86,20 +86,20 @@ index cf2dbe65b805..1473dc772502 100644
- return BGP_ATTR_PARSE_PROCEED;
+ return BGP_ATTR_PARSE_WITHDRAW;
if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
type = BGP_ATTR_ORIGIN;
@@ -3273,7 +3276,13 @@ done:
aspath_unintern(&as4_path);
}
/* "An UPDATE message that contains the MP_UNREACH_NLRI is not required
to carry any other path attributes.", though if MP_REACH_NLRI or NLRI
@@ -3507,7 +3510,13 @@ done:
aspath_unintern(&as4_path);
transit = bgp_attr_get_transit(attr);
- if (ret != BGP_ATTR_PARSE_ERROR) {
+ /* If we received an UPDATE with mandatory attributes, then
+ * the unrecognized transitive optional attribute of that
+ * path MUST be passed. Otherwise, it's an error, and from
+ * security perspective it might be very harmful if we continue
+ * here with the unrecognized attributes.
+ */
+ * the unrecognized transitive optional attribute of that
+ * path MUST be passed. Otherwise, it's an error, and from
+ * security perspective it might be very harmful if we continue
+ * here with the unrecognized attributes.
+ */
+ if (ret == BGP_ATTR_PARSE_PROCEED) {
/* Finally intern unknown attribute. */
if (attr->transit)
attr->transit = transit_intern(attr->transit);
if (transit)
bgp_attr_set_transit(attr, transit_intern(transit));

View File

@ -0,0 +1,4 @@
#Type Name ID GECOS Home directory Shell
g frrvty -
u frr - "FRRouting routing suite" /var/run/frr /sbin/nologin
m frr frrvty

View File

@ -1,4 +1,4 @@
/usr/libexec/frr/(.*)? gen_context(system_u:object_r:frr_exec_t,s0)
/usr/libexec/frr/(.*)? gen_context(system_u:object_r:frr_exec_t,s0)
/usr/lib/systemd/system/frr.* gen_context(system_u:object_r:frr_unit_file_t,s0)
@ -22,6 +22,7 @@
/var/lock/subsys/staticd -- gen_context(system_u:object_r:frr_lock_t,s0)
/var/lock/subsys/zebra -- gen_context(system_u:object_r:frr_lock_t,s0)
/var/lock/subsys/vrrpd -- gen_context(system_u:object_r:frr_lock_t,s0)
/var/lock/subsys/pathd -- gen_context(system_u:object_r:frr_lock_t,s0)
/var/run/frr(/.*)? gen_context(system_u:object_r:frr_var_run_t,s0)

View File

@ -162,45 +162,53 @@ interface(`frr_admin',`
')
########################################
#
# Interface compatibility blocks
#
# The following definitions ensure compatibility with distribution policy
# versions that do not contain given interfaces (epel, or older Fedora
# releases).
# Each block tests for existence of given interface and defines it if needed.
#
######################################
## <summary>
## Read ifconfig_var_run_t files and link files
## Watch ifconfig_var_run_t directories
## </summary>
## <param name="domain">
## <summary>
## Domain allowed access.
## </summary>
## <summary>
## Domain allowed access.
## </summary>
## </param>
#
ifndef(`sysnet_read_ifconfig_run',`
interface(`sysnet_read_ifconfig_run',`
gen_require(`
type ifconfig_var_run_t;
')
ifndef(`sysnet_watch_ifconfig_run',`
interface(`sysnet_watch_ifconfig_run',`
gen_require(`
type ifconfig_var_run_t;
')
manage_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
list_dirs_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
read_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
read_lnk_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
')
watch_dirs_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
')
')
########################################
## <summary>
## Read unconfined_t files and dirs
## Read ifconfig_var_run_t files and link files
## </summary>
## <param name="domain">
## <summary>
## <summary>
## Domain allowed access.
## </summary>
## </summary>
## </param>
#
ifndef(`unconfined_read_files',`
interface(`unconfined_read_files',`
gen_require(`
type unconfined_t;
')
ifndef(`sysnet_read_ifconfig_run',`
interface(`sysnet_read_ifconfig_run',`
gen_require(`
type ifconfig_var_run_t;
')
allow $1 unconfined_t:file read_file_perms;
allow $1 unconfined_t:dir list_dir_perms;
')
list_dirs_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
read_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
read_lnk_files_pattern($1, ifconfig_var_run_t, ifconfig_var_run_t)
')
')

View File

@ -31,9 +31,9 @@ files_pid_file(frr_var_run_t)
#
# frr local policy
#
allow frr_t self:capability { fowner fsetid chown dac_override dac_read_search kill net_bind_service net_raw setgid setuid net_admin sys_admin };
allow frr_t self:capability { chown dac_override dac_read_search kill net_bind_service net_raw setgid setuid net_admin sys_admin };
allow frr_t self:netlink_route_socket rw_netlink_socket_perms;
allow frr_t self:packet_socket create;
allow frr_t self:packet_socket create_socket_perms;
allow frr_t self:process { setcap setpgid };
allow frr_t self:rawip_socket create_socket_perms;
allow frr_t self:tcp_socket { connect connected_stream_socket_perms };
@ -93,25 +93,23 @@ corenet_tcp_bind_zebra_port(frr_t)
domain_use_interactive_fds(frr_t)
fs_read_nsfs_files(frr_t)
fs_search_cgroup_dirs(frr_t)
sysnet_exec_ifconfig(frr_t)
sysnet_read_ifconfig_run(frr_t)
sysnet_watch_ifconfig_run(frr_t)
ipsec_domtrans_mgmt(frr_t)
userdom_read_admin_home_files(frr_t)
init_signal(frr_t)
init_signal_script(frr_t)
init_signull_script(frr_t)
unconfined_server_signull(frr_t)
allow frr_t unconfined_service_t:process signal;
optional_policy(`
logging_send_syslog_msg(frr_t)
')
optional_policy(`
unconfined_read_files(frr_t)
')
optional_policy(`
modutils_exec_kmod(frr_t)
modutils_getattr_module_deps(frr_t)

View File

@ -0,0 +1,16 @@
#!/bin/sh
#this script is used to remove babled and ldpd from the tar sources
#Usage: sh remove-babeld-ldpd.sh <VERSION>
#Example: sh remove-babeld-ldpd.sh 7.3.1 - this is for frr-7.3.1.tar.gz file
VERSION=$1
TAR=frr-${VERSION}.tar.gz
DIR=frr-${VERSION}
echo ${VERSION}
echo ${TAR}
echo ${DIR}
tar -xzf ${TAR}
rm -rf ${DIR}/babeld ${DIR}/ldpd
tar -czf ${TAR} ${DIR}

View File

@ -1,72 +1,94 @@
%global frrversion 7.5.1
%global frr_libdir /usr/libexec/frr
%global frr_libdir %{_libexecdir}/frr
%global _hardened_build 1
%define _legacy_common_support 1
%global selinuxtype targeted
%bcond_without selinux
Name: frr
Version: 7.5.1
Release: 22%{?checkout}%{?dist}
Version: 8.3.1
Release: 11%{?checkout}%{?dist}.2.alma.1
Summary: Routing daemon
License: GPLv2+
URL: http://www.frrouting.org
Source0: https://github.com/FRRouting/frr/releases/download/%{name}-%{frrversion}/%{name}-%{frrversion}.tar.gz
Source0: https://github.com/FRRouting/frr/releases/download/%{name}-%{version}/%{name}-%{version}.tar.gz
Source1: %{name}-tmpfiles.conf
Source2: frr.fc
Source3: frr.te
Source4: frr.if
BuildRequires: perl-generators
BuildRequires: gcc
BuildRequires: net-snmp-devel
BuildRequires: texinfo libcap-devel autoconf automake libtool patch groff
BuildRequires: readline readline-devel ncurses ncurses-devel
BuildRequires: git pam-devel c-ares-devel
BuildRequires: json-c-devel bison >= 2.7 flex perl-XML-LibXML
BuildRequires: python3-devel python3-sphinx python3-pytest
BuildRequires: systemd systemd-devel
BuildRequires: libyang-devel >= 1.0.184
Requires: net-snmp ncurses
Requires(post): systemd /sbin/install-info
Requires(preun): systemd /sbin/install-info
Source2: frr-sysusers.conf
Source3: frr.fc
Source4: frr.te
Source5: frr.if
Source6: remove-babeld-ldpd.sh
BuildRequires: autoconf
BuildRequires: automake
BuildRequires: bison >= 2.7
BuildRequires: c-ares-devel
BuildRequires: flex
BuildRequires: gcc
BuildRequires: gcc-c++
BuildRequires: git-core
BuildRequires: groff
BuildRequires: json-c-devel
BuildRequires: libcap-devel
BuildRequires: libtool
BuildRequires: libyang-devel >= 2.0.0
BuildRequires: make
BuildRequires: ncurses
BuildRequires: ncurses-devel
BuildRequires: net-snmp-devel
BuildRequires: pam-devel
BuildRequires: patch
BuildRequires: perl-XML-LibXML
BuildRequires: perl-generators
BuildRequires: python3-devel
BuildRequires: python3-pytest
BuildRequires: python3-sphinx
BuildRequires: readline-devel
BuildRequires: systemd-devel
BuildRequires: systemd-rpm-macros
BuildRequires: texinfo
Requires: net-snmp
Requires: ncurses
Requires(post): systemd
Requires(post): /sbin/install-info
Requires(post): hostname
Requires(preun): systemd
Requires(preun): /sbin/install-info
Requires(postun): systemd
Requires: iproute
Requires: initscripts
%if 0%{?with_selinux}
Requires: (%{name}-selinux = %{version}-%{release} if selinux-policy-%{selinuxtype})
%endif
Conflicts: quagga
Provides: routingdaemon = %{version}-%{release}
Obsoletes: frr-sysvinit quagga frr-contrib
Patch0000: 0000-remove-babeld-and-ldpd.patch
Patch0001: 0001-use-python3.patch
Patch0002: 0002-enable-openssl.patch
Patch0003: 0003-disable-eigrp-crypto.patch
Patch0004: 0004-fips-mode.patch
Patch0006: 0006-CVE-2020-12831.patch
Patch0007: 0007-frrinit.patch
Patch0008: 0008-designated-router.patch
Patch0009: 0009-routemap.patch
Patch0010: 0010-moving-executables.patch
Patch0011: 0011-reload-bfd-profile.patch
Patch0012: 0012-graceful-restart.patch
Patch0013: 0013-CVE-2022-37032.patch
Patch0014: 0014-bfd-profile-crash.patch
Patch0015: 0015-max-ttl-reload.patch
Patch0016: 0016-CVE-2023-38802.patch
Patch0017: 0017-fix-crash-in-plist-update.patch
Patch0018: 0018-CVE-2023-38406.patch
Patch0019: 0019-CVE-2023-38407.patch
Patch0020: 0020-CVE-2023-47234.patch
Patch0021: 0021-CVE-2023-47235.patch
Patch0022: 0022-route-map-event.patch
Patch0023: 0023-CVE-2023-46752.patch
Patch0024: 0024-CVE-2023-46753.patch
Patch0025: 0025-CVE-2023-31490.patch
Patch0026: 0026-CVE-2023-41909.patch
Patch0027: 0027-dynamic-netlink-buffer.patch
Patch0005: 0005-ospf-api.patch
Patch0006: 0006-graceful-restart.patch
Patch0007: 0007-cve-2022-37032.patch
Patch0008: 0008-frr-non-root-user.patch
Patch0009: 0009-CVE-2022-36440-40302.patch
Patch0010: 0010-CVE-2022-43681.patch
Patch0011: 0011-CVE-2022-40318.patch
Patch0012: 0012-bfd-not-working-in-vrf.patch
# Patches were taken from upstream and modified to apply cleanly:
# https://gitlab.com/redhat/centos-stream/rpms/frr/-/commit/0b762a19a765d1a7e7f8e0e7caac1706f7ca02d1
Patch0013: CVE-2023-38802.patch
# https://github.com/FRRouting/frr/commit/767aaa3a80489bfc4ff097f932fc347e3db25b89
Patch0014: bgpd-Do-not-explicitly-print-MAXTTL.patch
# https://github.com/FRRouting/frr/commit/6814f2e0138a6ea5e1f83bdd9085d9a77999900b
Patch0015: CVE-2023-47235.patch
# https://github.com/FRRouting/frr/commit/c37119df45bbf4ef713bc10475af2ee06e12f3bf
Patch0016: CVE-2023-47234.patch
# https://github.com/FRRouting/frr/pull/12884/commits/0b999c886e241c52bd1f7ef0066700e4b618ebb3
Patch0017: CVE-2023-38406.patch
# https://github.com/FRRouting/frr/pull/12956/commits/ab362eae68edec12c175d9bc488bcc3f8b73d36f
Patch0018: CVE-2023-38407.patch
%description
FRRouting is free software that manages TCP/IP based routing protocols. It takes
@ -79,11 +101,11 @@ FRRouting is a fork of Quagga.
%if 0%{?with_selinux}
%package selinux
Summary: Selinux policy for FRR
BuildArch: noarch
Requires: selinux-policy-%{selinuxtype}
Requires(post): selinux-policy-%{selinuxtype}
BuildRequires: selinux-policy-devel
Summary: Selinux policy for FRR
BuildArch: noarch
Requires: selinux-policy-%{selinuxtype}
Requires(post): selinux-policy-%{selinuxtype}
BuildRequires: selinux-policy-devel
%{?selinux_requires}
%description selinux
@ -93,9 +115,8 @@ SELinux policy modules for FRR package
%prep
%autosetup -S git
#SELinux
mkdir selinux
cp -p %{SOURCE2} %{SOURCE3} %{SOURCE4} selinux
cp -p %{SOURCE3} %{SOURCE4} %{SOURCE5} selinux
%build
autoreconf -ivf
@ -106,11 +127,11 @@ autoreconf -ivf
--libdir=%{_libdir}/frr \
--libexecdir=%{_libexecdir}/frr \
--localstatedir=%{_localstatedir}/run/frr \
--enable-snmp=agentx \
--enable-multipath=64 \
--enable-vtysh=yes \
--enable-ospfclient=no \
--enable-ospfapi=no \
--disable-ospfclient \
--disable-ospfapi \
--enable-snmp=agentx \
--enable-user=frr \
--enable-group=frr \
--enable-vty-group=frrvty \
@ -130,7 +151,6 @@ pushd doc
make info
popd
#SELinux policy
%if 0%{?with_selinux}
make -C selinux -f %{_datadir}/selinux/devel/Makefile %{name}.pp
bzip2 -9 selinux/%{name}.pp
@ -150,39 +170,36 @@ mkdir -p %{buildroot}%{_tmpfilesdir}
rm -rf %{buildroot}/usr/share/info/dir
install -p -m 644 %{SOURCE1} %{buildroot}%{_tmpfilesdir}/%{name}.conf
install -p -m 644 %{_builddir}/%{name}-%{frrversion}/tools/etc/frr/daemons %{buildroot}/etc/frr/daemons
install -p -m 644 %{_builddir}/%{name}-%{frrversion}/tools/frr.service %{buildroot}%{_unitdir}/frr.service
install -p -m 755 %{_builddir}/%{name}-%{frrversion}/tools/frrinit.sh %{buildroot}%{frr_libdir}/frr
install -p -m 755 %{_builddir}/%{name}-%{frrversion}/tools/frrcommon.sh %{buildroot}%{frr_libdir}/frrcommon.sh
install -p -m 755 %{_builddir}/%{name}-%{frrversion}/tools/watchfrr.sh %{buildroot}%{frr_libdir}/watchfrr.sh
install -p -m 644 tools/etc/frr/daemons %{buildroot}/etc/frr/daemons
install -p -m 644 tools/frr.service %{buildroot}%{_unitdir}/frr.service
install -p -m 755 tools/frrinit.sh %{buildroot}%{frr_libdir}/frr
install -p -m 755 tools/frrcommon.sh %{buildroot}%{frr_libdir}/frrcommon.sh
install -p -m 755 tools/watchfrr.sh %{buildroot}%{frr_libdir}/watchfrr.sh
install -p -m 644 %{_builddir}/%{name}-%{frrversion}/redhat/frr.logrotate %{buildroot}/etc/logrotate.d/frr
install -p -m 644 %{_builddir}/%{name}-%{frrversion}/redhat/frr.pam %{buildroot}/etc/pam.d/frr
install -p -m 644 redhat/frr.logrotate %{buildroot}/etc/logrotate.d/frr
install -p -m 644 redhat/frr.pam %{buildroot}/etc/pam.d/frr
install -d -m 775 %{buildroot}/run/frr
install -p -D -m 0644 %{SOURCE2} ${RPM_BUILD_ROOT}/%{_sysusersdir}/frr.conf
%if 0%{?with_selinux}
install -D -m 644 selinux/%{name}.pp.bz2 \
%{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{name}.pp.bz2
%{buildroot}%{_datadir}/selinux/packages/%{selinuxtype}/%{name}.pp.bz2
install -D -m 644 selinux/%{name}.if %{buildroot}%{_datadir}/selinux/devel/include/distributed/%{name}.if
%endif
rm %{buildroot}%{_libdir}/frr/*.la
rm %{buildroot}%{_libdir}/frr/modules/*.la
# Delete libtool archives
find %{buildroot} -type f -name "*.la" -delete -print
#Upstream does not maintain a stable API, these headers from -devel subpackage are no longer needed
rm %{buildroot}%{_libdir}/frr/*.so
rm -r %{buildroot}%{_includedir}/frr/
%pre
getent group fttvty >/dev/null 2>&1 || groupadd -r frrvty >/dev/null 2>&1 || :
getent group frr >/dev/null 2>&1 || groupadd -r frr >/dev/null 2>&1 || :
getent passwd frr >/dev/null 2>&1 || useradd -M -r -g frr -s /sbin/nologin \
-c "FRRouting suite" -d %{_localstatedir}/run/frr frr || :
usermod -aG frrvty frr
%sysusers_create_compat %{SOURCE2}
exit 0
%post
#Because we move files to /usr/libexec, we need to reload .service files as well
/usr/bin/systemctl daemon-reload
%systemd_post frr.service
if [ -f %{_infodir}/%{name}.inf* ]; then
@ -190,39 +207,37 @@ if [ -f %{_infodir}/%{name}.inf* ]; then
fi
# Create dummy files if they don't exist so basic functions can be used.
if [ ! -e %{_sysconfdir}/frr/zebra.conf ]; then
echo "hostname `hostname`" > %{_sysconfdir}/frr/zebra.conf
chown frr:frr %{_sysconfdir}/frr/zebra.conf
chmod 640 %{_sysconfdir}/frr/zebra.conf
# Only create frr.conf when first installing, otherwise it can change
# the behavior of the package
if [ $1 -eq 1 ]; then
if [ ! -e %{_sysconfdir}/frr/frr.conf ]; then
echo "hostname `hostname`" > %{_sysconfdir}/frr/frr.conf
chown frr:frr %{_sysconfdir}/frr/frr.conf
chmod 640 %{_sysconfdir}/frr/frr.conf
fi
fi
#still used by vtysh, this way no error is produced when using vtysh
if [ ! -e %{_sysconfdir}/frr/vtysh.conf ]; then
echo 'no service integrated-vtysh-config' > %{_sysconfdir}/frr/vtysh.conf
touch %{_sysconfdir}/frr/vtysh.conf
chmod 640 %{_sysconfdir}/frr/vtysh.conf
chown frr:frrvty %{_sysconfdir}/frr/vtysh.conf
fi
#Making sure that the old format of config file still works
#Checking whether .rpmnew conf file is present - in that case I want to change the old config
if [ -e %{_sysconfdir}/frr/daemons.rpmnew ]; then
sed -i s'/watchfrr_/#watchfrr_/g' %{_sysconfdir}/frr/daemons
sed -i s'/zebra=/#zebra=/g' %{_sysconfdir}/frr/daemons
fi
%postun
%systemd_postun_with_restart frr.service
#only when removing the package
if [ $1 -ge 0 ]; then
%preun
%systemd_preun frr.service
#only when removing frr
if [ $1 -eq 0 ]; then
if [ -f %{_infodir}/%{name}.inf* ]; then
install-info --delete %{_infodir}/frr.info %{_infodir}/dir || :
fi
fi
%preun
%systemd_preun frr.service
#SELinux
%if 0%{?with_selinux}
%pre selinux
%selinux_relabel_pre -s %{selinuxtype}
@ -232,8 +247,8 @@ fi
%selinux_relabel_post -s %{selinuxtype}
#/var/tmp and /var/run need to be relabeled as well if FRR is running before upgrade
if [ $1 == 2 ]; then
%{_sbindir}/restorecon -R /var/tmp/frr &> /dev/null
%{_sbindir}/restorecon -R /var/run/frr &> /dev/null
%{_sbindir}/restorecon -R /var/tmp/frr &> /dev/null
%{_sbindir}/restorecon -R /var/run/frr &> /dev/null
fi
%postun selinux
@ -241,7 +256,6 @@ if [ $1 -eq 0 ]; then
%selinux_modules_uninstall -s %{selinuxtype} %{name}
%selinux_relabel_post -s %{selinuxtype}
fi
%endif
%check
@ -250,16 +264,8 @@ make check PYTHON=%{__python3}
%files
%defattr(-,root,root)
%license COPYING
%doc zebra/zebra.conf.sample
%doc isisd/isisd.conf.sample
%doc ripd/ripd.conf.sample
%doc bgpd/bgpd.conf.sample*
%doc ospfd/ospfd.conf.sample
%doc ospf6d/ospf6d.conf.sample
%doc ripngd/ripngd.conf.sample
%doc pimd/pimd.conf.sample
%doc doc/mpls
%dir %attr(740,frr,frr) %{_sysconfdir}/frr
%dir %attr(750,frr,frr) %{_sysconfdir}/frr
%dir %attr(755,frr,frr) /var/log/frr
%dir %attr(755,frr,frr) /run/frr
%{_infodir}/*info*
@ -269,7 +275,7 @@ make check PYTHON=%{__python3}
%{_bindir}/*
%dir %{_libdir}/frr
%{_libdir}/frr/*.so.*
%dir %{_libdir}/frr/modules/
%dir %{_libdir}/frr/modules
%{_libdir}/frr/modules/*
%config(noreplace) %attr(644,root,root) /etc/logrotate.d/frr
%config(noreplace) %attr(644,frr,frr) /etc/frr/daemons
@ -278,6 +284,7 @@ make check PYTHON=%{__python3}
%dir /usr/share/yang
/usr/share/yang/*.yang
%{_tmpfilesdir}/%{name}.conf
%{_sysusersdir}/frr.conf
%if 0%{?with_selinux}
%files selinux
@ -287,137 +294,172 @@ make check PYTHON=%{__python3}
%endif
%changelog
* Wed Feb 07 2024 Michal Ruprich <mruprich@redhat.com> - 7.5.1-22
- Resolves: RHEL-22303 - Zebra not fetching host routes
* Thu Jan 25 2024 Eduard Abdullin <eabdullin@almalinux.org> - 8.3.1-11.2.alma.1
- bgpd: Flowspec overflow issue
- bgpd: Fix use beyond end of stream of labeled unicast parsing
- bgpd: Ignore handling NLRIs if we received MP_UNREACH_NLRI
- bgpd: Treat EOR as withdrawn to avoid unwanted handling of
malformed attrs
* Wed Feb 07 2024 Michal Ruprich <mruprich@redhat.com> - 7.5.1-21
- Resolves: RHEL-2216 - NULL pointer dereference
* Wed Dec 13 2023 Eduard Abdullin <eabdullin@almalinux.org> - 8.3.1-11.1.alma.1
- bgpd: Do not explicitly print MAXTTL value for ebgp-multihop
vty output
* Wed Feb 07 2024 Michal Ruprich <mruprich@redhat.com> - 7.5.1-20
- Resolves: RHEL-4797 - missing length check in bgp_attr_psid_sub() can lead do DoS
* Tue Nov 07 2023 Eduard Abdullin <eabdullin@almalinux.org> - 8.3.1-11.alma.1
- Related: #2216912 - adding sys_admin to capabilities
* Mon Feb 05 2024 Michal Ruprich <mruprich@redhat.com> - 7.5.1-19
- Resolves: RHEL-14824 - crafted BGP UPDATE message leading to a crash
* Thu Aug 10 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-10
- Related: #2216912 - adding sys_admin to capabilities
* Mon Feb 05 2024 Michal Ruprich <mruprich@redhat.com> - 7.5.1-18
- Resolves: RHEL-14821 - mishandled malformed data leading to a crash
* Tue Aug 08 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-9
- Resolves: #2215346 - frr policy does not allow the execution of /usr/sbin/ipsec
* Tue Dec 19 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-17
- Resolves: RHEL-6583 - Routes are not refreshed after changing the inbound route rules from deny to permit
* Mon Aug 07 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-8
- Resolves: #2216912 - SELinux is preventing FRR-Zebra to access to network namespaces
* Tue Dec 19 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-16
- Resolves: RHEL-15916 - Flowspec overflow in bgpd/bgp_flowspec.c
- Resolves: RHEL-15919 - Out of bounds read in bgpd/bgp_label.c
- Resolves: RHEL-15869 - crash from specially crafted MP_UNREACH_NLRI-containing BGP UPDATE message
- Resolves: RHEL-15868 - crash from malformed EOR-containing BGP UPDATE message
* Wed Jun 07 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-7
- Resolves: #2168855 - BFD not working through VRF
* Thu Oct 19 2023 Andreas Karis <akaris@redhat.com> - 7.5.1-15
- Resolves: RHEL-12039 - crash in plist update
* Tue May 23 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-6
- Resolves: #2184870 - Reachable assertion in peek_for_as4_capability function
- Resolves: #2196795 - denial of service by crafting a BGP OPEN message with an option of type 0xff
- Resolves: #2196796 - denial of service by crafting a BGP OPEN message with an option of type 0xff
- Resolves: #2196794 - out-of-bounds read exists in the BGP daemon of FRRouting
* Fri Oct 13 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-14
- Resolves: RHEL-6617 - Incorrect handling of a error in parsing of an invalid section of a BGP update can de-peer a router
* Mon Nov 28 2022 Michal Ruprich <mruprich@redhat.com> - 8.3.1-5
- Resolves: #2147522 - It is not possible to run FRR as a non-root user
* Tue Oct 10 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-13
- Resolves: RHEL-2263 - eBGP multihop peer flapping due to delta miscalculation of new configuration
* Thu Nov 24 2022 Michal Ruprich <mruprich@redhat.com> - 8.3.1-4
- Resolves: #2144500 - AVC error when reloading FRR with provided reload script
* Wed Aug 23 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-12
- Resolves: #2216911 - Adding missing sys_admin SELinux call
* Wed Oct 19 2022 Michal Ruprich <mruprich@redhat.com> - 8.3.1-3
- Related: #2129743 - Adding missing rules for vtysh and other daemons
* Mon Aug 21 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-11
- Related: #2216911 - Adding unconfined_t type to access namespaces
* Mon Oct 17 2022 Michal Ruprich <mruprich@redhat.com> - 8.3.1-2
- Resolves: #2128738 - out-of-bounds read in the BGP daemon may lead to information disclosure or denial of service
* Thu Aug 17 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-10
- Related: #2226803 - Adding patch
* Thu Oct 13 2022 Michal Ruprich <mruprich@redhat.com> - 8.3.1-1
- Resolves: #2129731 - Rebase FRR to the latest version
- Resolves: #2129743 - Add targeted SELinux policy for FRR
- Resolves: #2127494 - BGP incorrectly withdraws routes on graceful restart capable routers
* Wed Aug 16 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-9
- Resolves: #2226803 - BFD crash in FRR running in MetalLB
* Tue Jun 14 2022 Michal Ruprich - 8.2.2-4
- Resolves: #2095404 - frr use systemd-sysusers
* Fri Aug 11 2023 Michal Ruprich <mruprich@redhat.com> - 7.5.1-8
- Resolves: #2216911 - SELinux is preventing FRR-Zebra to access to network namespaces
* Tue May 24 2022 Michal Ruprich <mruprich@redhat.com> - 8.2.2-3
- Resolves: #2081304 - Enhanced TMT testing for centos-stream
* Wed Nov 30 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-7
- Resolves: #2128737 - out-of-bounds read in the BGP daemon may lead to information disclosure or denial of service
* Mon May 02 2022 Michal Ruprich <mruprich@redhat.com> - 8.2.2-2
- Resolves: #2069571 - the dynamic routing setup does not work any more
* Tue Nov 29 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-6
- Resolves: #1939516 - frr service cannot reload itself, due to executing in the wrong SELinux context
* Mon May 02 2022 Michal Ruprich <mruprich@redhat.com> - 8.2.2-1
- Resolves: #2069563 - Rebase frr to version 8.2.2
* Mon Nov 14 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-5
- Resolves: #2127140 - Frr is unable to push routes to the system routing table
* Tue Nov 16 2021 Michal Ruprich <mruprich@redhat.com> - 8.0-5
- Resolves: #2023318 - Rebuilding for the new json-c library
* Mon Nov 14 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-4
- Resolves: #1948422 - BGP incorrectly withdraws routes on graceful restart capable routers
* Wed Sep 01 2021 Michal Ruprich <mruprich@redhat.com> - 8.0-4
- Resolves: #1997603 - ospfd not running with ospf opaque-lsa option used
* Thu Aug 25 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-3
- Resolves: #2054160 - FRR reloader does not disable BFD when unsetting BFD profile
* Mon Aug 16 2021 Michal Ruprich <mruprich@redhat.com> - 8.0-3
- Related: #1990858 - Fixing prefix-list duplication check
* Wed Aug 24 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-2
- Resolves: #1941765 - AVCs while running frr tests on RHEL 8.4.0 Beta-1.2
- Resolves: #1714984 - SELinux policy (daemons) changes required for package
* Thu Aug 12 2021 Michal Ruprich <mruprich@redhat.com> - 8.0-2
- Related: #1990858 - Frr needs higher version of libyang
* Wed May 11 2022 Michal Ruprich <mruprich@redhat.com> - 7.5.1-1
- Resolves: #2018451 - Rebase of frr to version 7.5.1
- Resolves: #1975361 - the dynamic routing setup does not work any more
* Tue Aug 10 2021 Michal Ruprich <mruprich@redhat.com> - 8.0-1
- Resolves: #1990858 - Possible rebase of frr to version 8.0
* Wed Jan 05 2022 Michal Ruprich <mruprich@redhat.com> - 7.5-11
- Resolves: #2034328 - Bfdd crash in metallb CI
* Mon Aug 09 2021 Mohan Boddu <mboddu@redhat.com> - 7.5.1-7
- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
Related: rhbz#1991688
* Tue Jan 04 2022 Michal Ruprich <mruprich@redhat.com> - 7.5-10
- Resolves: #2020878 - frr ospfd show ip ospf interface does not show designated router info
* Wed Jul 21 2021 Michal Ruprich <mruprich@redhat.com> - 7.5.1-6
- Resolves: #1983967 - ospfd crashes in route_node_delete with assertion fail
* Fri Dec 10 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-9
- Resolves: #2029958 - FRR reloader generating invalid BFD configurations, exits with error
* Wed Jun 16 2021 Mohan Boddu <mboddu@redhat.com> - 7.5.1-5
- Rebuilt for RHEL 9 BETA for openssl 3.0
Related: rhbz#1971065
* Tue Nov 16 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-8
- Resolves: #2021819 - Rebuilding for the new json-c
* Fri Jun 04 2021 Michal Ruprich <mruprich@redhat.com> - 7.5.1-4
- Resolves: #1958155 - Upgrading frr unconditionally creates /etc/frr/frr.conf, breaking existing configuration
* Thu Sep 30 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-7
- Related: #1917269 - Wrong value in gating file
* Fri Apr 23 2021 Michal Ruprich <mruprich@redhat.com> - 7.5.1-3
- Resolves: #1939456 - /etc/frr permissions are bogus
- Resolves: #1951303 - FTBFS in CentOS Stream
* Fri Sep 17 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-6
- Related: #1917269 - Incomplete patch, adding gating rules
* Thu Apr 15 2021 Mohan Boddu <mboddu@redhat.com> - 7.5.1-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
* Thu Sep 16 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-5
- Resolves: #1979426 - Unable to configure OSPF in multi-instance mode
- Resolves: #1917269 - vtysh running-config output not showing bgp ttl-security hops option
* Tue Mar 16 2021 Michal Ruprich <mruprich@redhat.com> - 7.5.1-1
- New version 7.5.1
- Enabling grpc, adding hostname for post scriptlet
- Moving files to libexec due to selinux issues
* Tue Jan 12 2021 root - 7.5-4
- Related: #1889323 - Fixing start-up with old config file
* Tue Feb 16 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-3
- Fixing FTBS - icc options are confusing the new gcc
* Mon Jan 11 2021 root - 7.5-3
- Related: #1889323 - Reverting to non-integrated cofiguration
* Tue Jan 26 2021 Fedora Release Engineering <releng@fedoraproject.org> - 7.5-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
* Thu Jan 07 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-2
- Related: #1889323 - Obsoleting frr-contrib
* Fri Jan 01 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-1
- New version 7.5
* Thu Jan 07 2021 Michal Ruprich <mruprich@redhat.com> - 7.5-1
- Resolves: #1889323 - [RFE] Rebase FRR to 7.5
* Mon Sep 21 2020 Michal Ruprich <mruprich@redhat.com> - 7.4-1
- New version 7.4
* Thu Aug 20 2020 Michal Ruprich <mruprich@redhat.com> - 7.0-10
- Resolves: #1867793 - FRR does not conform to the source port range specified in RFC5881
* Thu Aug 27 2020 Josef Řídký <jridky@redhat.com> - 7.3.1-4
- Rebuilt for new net-snmp release
* Thu Aug 20 2020 Michal Ruprich <mruprich@redhat.com> - 7.0-9
- Resolves: #1852476 - default permission issue eases information leaks
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 7.3.1-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild
* Tue May 05 2020 Michal Ruprich <mruprich@redhat.com> - 7.0-8
- Resolves: #1819319 - frr fails to start start if the initscripts package is missing
* Thu Jun 18 2020 Michal Ruprich <mruprich@redhat.com> - 7.3.1-1
- New version 7.3.1
- Fixes a couple of bugs(#1832259, #1835039, #1830815, #1830808, #1830806, #1830800, #1830798, #1814773)
* Mon May 04 2020 Michal Ruprich <mruprich@redhat.com> - 7.0-7
- Resolves: #1758544 - IGMPv3 queries may lead to DoS
* Tue May 19 2020 Michal Ruprich <mruprich@redhat.com> - 7.3-6
- Removing texi2html, it is not available in Rawhide anymore
* Tue Mar 10 2020 Michal Ruprich <mruprich@redhat.com> - 7.0-6
- Resolves: #1776342 - frr has missing dependency on iproute
* Mon May 18 2020 Michal Ruprich <mruprich@redhat.com> - 7.3-5
- Rebuild for new version of libyang
* Tue Sep 03 2019 Michal Ruprich <mruprich@redhat.com> - 7.0-5
- Resolves: #1719465 - Removal of component Frr or its crypto
* Tue Apr 21 2020 Björn Esser <besser82@fedoraproject.org> - 7.3-4
- Rebuild (json-c)
* Wed Jun 19 2019 Michal Ruprich <mruprich@redhat.com> - 7.0-4
- Related: #1657029 - frr-contrib is back, it is breaking the rpmdeplint test
* Mon Apr 13 2020 Björn Esser <besser82@fedoraproject.org> - 7.3-3
- Update json-c-0.14 patch with a solution from upstream
* Wed Jun 19 2019 Michal Ruprich <mruprich@redhat.com> - 7.0-3
- Related: #1657029 - more cleanup, removed frr-contrib, frrvt changed to frrvty
* Mon Apr 13 2020 Björn Esser <besser82@fedoraproject.org> - 7.3-2
- Add support for upcoming json-c 0.14.0
* Wed Feb 19 2020 Michal Ruprich <mruprich@redhat.com> - 7.3-1
- New version 7.3
* Tue Jan 28 2020 Fedora Release Engineering <releng@fedoraproject.org> - 7.2-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
* Mon Dec 16 2019 Michal Ruprich <mruprich@redhat.com> - 7.2-1
- New version 7.2
* Tue Nov 12 2019 Michal Ruprich <mruprich@redhat.com> - 7.1-5
- Rebuilding for new version of libyang
* Mon Oct 07 2019 Michal Ruprich <mruprich@redhat.com> - 7.1-4
- Adding noreplace to the /etc/frr/daemons file
* Fri Sep 13 2019 Michal Ruprich <mruprich@redhat.com> - 7.1-3
- New way of finding python version during build
- Replacing crypto of all routing daemons with openssl
- Disabling EIGRP crypto because it is broken
- Disabling crypto in FIPS mode
* Thu Jul 25 2019 Fedora Release Engineering <releng@fedoraproject.org> - 7.1-2
- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
* Tue Jun 25 2019 Michal Ruprich <mruprich@redhat.com> - 7.1-1
- New version 7.1
* Wed Jun 19 2019 Michal Ruprich <mruprich@redhat.com> - 7.0-2
- Related: #1657029 - cleaning specfile, adding Requires on libyang-devel
- Initial build
* Wed May 29 2019 Michal Ruprich <mruprich@redhat.com> - 7.0-1
- Resolves: #1657029 - Add FRR as a replacement of Quagga in RHEL 8