Compare commits

..

No commits in common. 'c9-beta' and 'c9' have entirely different histories.
c9-beta ... c9

@ -1 +1 @@
5f46099a744058de374dbbf5240d1c4292a143f2 SOURCES/frr-8.5.3.tar.gz 467835eb73a6018948fd667663ce68282cf6d16b SOURCES/frr-8.3.1.tar.gz

2
.gitignore vendored

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

@ -28,13 +28,13 @@ index 5be3264..33abc1d 100644
nhrpd/Makefile \ nhrpd/Makefile \
ospf6d/Makefile \ ospf6d/Makefile \
diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons
index 8aa0887..c92dcca 100644 index f6d512b..6d4831d 100644
--- a/tools/etc/frr/daemons --- a/tools/etc/frr/daemons
+++ b/tools/etc/frr/daemons +++ b/tools/etc/frr/daemons
@@ -22,10 +22,8 @@ ripngd=no @@ -21,10 +21,8 @@ ripd=no
ripngd=no
isisd=no isisd=no
pimd=no pimd=no
pim6d=no
-ldpd=no -ldpd=no
nhrpd=no nhrpd=no
eigrpd=no eigrpd=no
@ -42,10 +42,10 @@ index 8aa0887..c92dcca 100644
sharpd=no sharpd=no
pbrd=no pbrd=no
bfdd=no bfdd=no
@@ -48,10 +46,8 @@ ripngd_options=" -A ::1" @@ -45,10 +43,8 @@ ripd_options=" -A 127.0.0.1"
ripngd_options=" -A ::1"
isisd_options=" -A 127.0.0.1" isisd_options=" -A 127.0.0.1"
pimd_options=" -A 127.0.0.1" pimd_options=" -A 127.0.0.1"
pim6d_options=" -A ::1"
-ldpd_options=" -A 127.0.0.1" -ldpd_options=" -A 127.0.0.1"
nhrpd_options=" -A 127.0.0.1" nhrpd_options=" -A 127.0.0.1"
eigrpd_options=" -A 127.0.0.1" eigrpd_options=" -A 127.0.0.1"

@ -111,5 +111,5 @@ index 53ae5b4..930307f 100644
#include <openssl/hmac.h> #include <openssl/hmac.h>
+#include <openssl/fips.h> +#include <openssl/fips.h>
#endif #endif
#include "openbsd-tree.h" #include "openbsd-tree.h"

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

@ -0,0 +1,78 @@
From 12f9f8472d0f8cfc026352906b8e5342df2846cc Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Tue, 27 Sep 2022 17:30:16 +0300
Subject: [PATCH] bgpd: Do not send Deconfig/Shutdown message when restarting
We might disable sending unconfig/shutdown notifications when
Graceful-Restart is enabled and negotiated.
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgpd.c | 35 ++++++++++++++++++++++++++---------
1 file changed, 26 insertions(+), 9 deletions(-)
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 749e46ebe9d..ae1308db423 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -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)
{
+ if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%pBP configured Graceful-Restart, skipping unconfig notification",
+ peer);
+ return;
+ }
+
if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
bgp_notify_send(peer, BGP_NOTIFY_CEASE,
BGP_NOTIFY_CEASE_PEER_UNCONFIG);
}
+static void peer_notify_shutdown(struct peer *peer)
+{
+ if (BGP_PEER_GRACEFUL_RESTART_CAPABLE(peer)) {
+ if (bgp_debug_neighbor_events(peer))
+ zlog_debug(
+ "%pBP configured Graceful-Restart, skipping shutdown notification",
+ peer);
+ return;
+ }
+
+ if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
+ bgp_notify_send(peer, BGP_NOTIFY_CEASE,
+ BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
+}
+
void peer_group_notify_unconfig(struct peer_group *group)
{
struct peer *peer, *other;
@@ -3676,11 +3699,8 @@ int bgp_delete(struct bgp *bgp)
}
/* Inform peers we're going down. */
- for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer)) {
- if (BGP_IS_VALID_STATE_FOR_NOTIF(peer->status))
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_ADMIN_SHUTDOWN);
- }
+ for (ALL_LIST_ELEMENTS(bgp->peer, node, next, peer))
+ peer_notify_shutdown(peer);
/* Delete static routes (networks). */
bgp_static_delete(bgp);
@@ -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_established(peer) || peer->status == OpenSent
- || peer->status == OpenConfirm)
- bgp_notify_send(peer, BGP_NOTIFY_CEASE,
- BGP_NOTIFY_CEASE_PEER_UNCONFIG);
+ peer_notify_unconfig(peer);
BGP_TIMER_OFF(bm->t_rmap_update);

@ -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 = -5,
};
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]) {

@ -0,0 +1,32 @@
From ff6db1027f8f36df657ff2e5ea167773752537ed Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Thu, 21 Jul 2022 08:11:58 -0400
Subject: [PATCH] bgpd: Make sure hdr length is at a minimum of what is
expected
Ensure that if the capability length specified is enough data.
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
bgpd/bgp_packet.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index dbf6c0b2e99..45752a8ab6d 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -2620,6 +2620,14 @@ static int bgp_capability_msg_parse(struct peer *peer, uint8_t *pnt,
"%s CAPABILITY has action: %d, code: %u, length %u",
peer->host, action, hdr->code, hdr->length);
+ if (hdr->length < sizeof(struct capability_mp_data)) {
+ zlog_info(
+ "%pBP Capability structure is not properly filled out, expected at least %zu bytes but header length specified is %d",
+ peer, sizeof(struct capability_mp_data),
+ hdr->length);
+ return BGP_Stop;
+ }
+
/* Capability length check. */
if ((pnt + hdr->length + 3) > end) {
zlog_info("%s Capability length error", peer->host);

@ -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,
enum bgp_attr_parse_ret 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];
@@ -3785,7 +3787,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr,
}
/* Check all mandatory well-known attributes are present */
- ret = bgp_attr_check(peer, attr);
+ ret = bgp_attr_check(peer, attr, length);
if (ret < 0)
goto done;

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

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

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

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

@ -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",

@ -0,0 +1,129 @@
From 46817adab03802355c3cce7b753c7a735bdcc5ae 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>
(cherry picked from commit bcb6b58d9530173df41d3a3cbc4c600ee0b4b186)
---
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 058fae23cbd..1c0803cfd8e 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);

@ -0,0 +1,93 @@
From 767aaa3a80489bfc4ff097f932fc347e3db25b89 Mon Sep 17 00:00:00 2001
From: Donatas Abraitis <donatas@opensourcerouting.org>
Date: Mon, 21 Aug 2023 00:01:42 +0300
Subject: [PATCH] bgpd: Do not explicitly print MAXTTL value for ebgp-multihop
vty output
1. Create /etc/frr/frr.conf
```
frr version 7.5
frr defaults traditional
hostname centos8.localdomain
no ip forwarding
no ipv6 forwarding
service integrated-vtysh-config
line vty
router bgp 4250001000
neighbor 192.168.122.207 remote-as 65512
neighbor 192.168.122.207 ebgp-multihop
```
2. Start FRR
`# systemctl start frr
`
3. Show running configuration. Note that FRR explicitly set and shows the default TTL (225)
```
Building configuration...
Current configuration:
!
frr version 7.5
frr defaults traditional
hostname centos8.localdomain
no ip forwarding
no ipv6 forwarding
service integrated-vtysh-config
!
router bgp 4250001000
neighbor 192.168.122.207 remote-as 65512
neighbor 192.168.122.207 ebgp-multihop 255
!
line vty
!
end
```
4. Copy initial frr.conf to frr.conf.new (no changes)
`# cp /etc/frr/frr.conf /root/frr.conf.new
`
5. Run frr-reload.sh:
```
$ /usr/lib/frr/frr-reload.py --test /root/frr.conf.new
2023-08-20 20:15:48,050 INFO: Called via "Namespace(bindir='/usr/bin', confdir='/etc/frr', daemon='', debug=False, filename='/root/frr.conf.new', input=None, log_level='info', overwrite=False, pathspace=None, reload=False, rundir='/var/run/frr', stdout=False, test=True, vty_socket=None)"
2023-08-20 20:15:48,050 INFO: Loading Config object from file /root/frr.conf.new
2023-08-20 20:15:48,124 INFO: Loading Config object from vtysh show running
Lines To Delete
===============
router bgp 4250001000
no neighbor 192.168.122.207 ebgp-multihop 255
Lines To Add
============
router bgp 4250001000
neighbor 192.168.122.207 ebgp-multihop
```
Closes https://github.com/FRRouting/frr/issues/14242
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
---
bgpd/bgp_vty.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index be0fe4283747..c9a9255f3392 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -17735,8 +17735,12 @@ static void bgp_config_write_peer_global(struct vty *vty, struct bgp *bgp,
&& !(peer->gtsm_hops != BGP_GTSM_HOPS_DISABLED
&& peer->ttl == MAXTTL)) {
if (!peer_group_active(peer) || g_peer->ttl != peer->ttl) {
- vty_out(vty, " neighbor %s ebgp-multihop %d\n", addr,
- peer->ttl);
+ if (peer->ttl != MAXTTL)
+ vty_out(vty, " neighbor %s ebgp-multihop %d\n",
+ addr, peer->ttl);
+ else
+ vty_out(vty, " neighbor %s ebgp-multihop\n",
+ addr);
}
}

@ -80,7 +80,7 @@ index a5f065a..cdf0734 100644
/* Network Layer Reachability Information. */ /* Network Layer Reachability Information. */
update_len = end - stream_pnt(s); update_len = end - stream_pnt(s);
- if (update_len && attribute_len) { - if (update_len) {
+ /* If we received MP_UNREACH_NLRI attribute, but also NLRIs, then + /* If we received MP_UNREACH_NLRI attribute, but also NLRIs, then
+ * NLRIs should be handled as a new data. Though, if we received + * NLRIs should be handled as a new data. Though, if we received
+ * NLRIs without mandatory attributes, they should be ignored. + * NLRIs without mandatory attributes, they should be ignored.

@ -0,0 +1,34 @@
From 0b999c886e241c52bd1f7ef0066700e4b618ebb3 Mon Sep 17 00:00:00 2001
From: Donald Sharp <sharpd@nvidia.com>
Date: Thu, 23 Feb 2023 13:29:32 -0500
Subject: [PATCH] bgpd: Flowspec overflow issue
According to the flowspec RFC 8955 a flowspec nlri is <length, <nlri data>>
Specifying 0 as a length makes BGP get all warm on the inside. Which
in this case is not a good thing at all. Prevent warmth, stay cold
on the inside.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
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 8d5ca5e77779..f9debe43cd45 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -127,6 +127,13 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
psize);
return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
}
+
+ if (psize == 0) {
+ flog_err(EC_BGP_FLOWSPEC_PACKET,
+ "Flowspec NLRI length 0 which makes no sense");
+ return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
+ }
+
if (bgp_fs_nlri_validate(pnt, psize, afi) < 0) {
flog_err(
EC_BGP_FLOWSPEC_PACKET,

@ -0,0 +1,54 @@
From 7404a914b0cafe046703c8381903a80d3def8f8b 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
Fixes a couple crashes associated with attempting to read
beyond the end of the stream.
Reported-by: Iggy Frankovic <iggyfran@amazon.com>
Signed-off-by: Donald Sharp <sharpd@nvidia.com>
---
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
--- 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,
uint8_t llen = 0;
uint8_t label_depth = 0;
+ if (plen < BGP_LABEL_BYTES)
+ return 0;
+
for (; data < lim; data += BGP_LABEL_BYTES) {
memcpy(label, data, BGP_LABEL_BYTES);
llen += BGP_LABEL_BYTES;
@@ -359,6 +362,9 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
addpath_id = ntohl(addpath_id);
pnt += BGP_ADDPATH_ID_LEN;
+
+ if (pnt >= lim)
+ return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
}
/* Fetch prefix length. */
@@ -377,6 +383,15 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
/* Fill in the labels */
llen = bgp_nlri_get_labels(peer, pnt, psize, &label);
+ if (llen == 0) {
+ flog_err(
+ EC_BGP_UPDATE_RCV,
+ "%s [Error] Update packet error (wrong label length 0)",
+ peer->host);
+ bgp_notify_send(peer, BGP_NOTIFY_UPDATE_ERR,
+ BGP_NOTIFY_UPDATE_INVAL_NETWORK);
+ return BGP_NLRI_PARSE_ERROR_LABEL_LENGTH;
+ }
p.prefixlen = prefixlen - BSIZE(llen);
/* There needs to be at least one label */

@ -6,8 +6,8 @@
%bcond_without selinux %bcond_without selinux
Name: frr Name: frr
Version: 8.5.3 Version: 8.3.1
Release: 4%{?checkout}%{?dist} Release: 11%{?checkout}%{?dist}.2
Summary: Routing daemon Summary: Routing daemon
License: GPLv2+ License: GPLv2+
URL: http://www.frrouting.org URL: http://www.frrouting.org
@ -67,10 +67,20 @@ Patch0000: 0000-remove-babeld-and-ldpd.patch
Patch0002: 0002-enable-openssl.patch Patch0002: 0002-enable-openssl.patch
Patch0003: 0003-disable-eigrp-crypto.patch Patch0003: 0003-disable-eigrp-crypto.patch
Patch0004: 0004-fips-mode.patch Patch0004: 0004-fips-mode.patch
Patch0005: 0005-CVE-2023-47235.patch Patch0005: 0005-ospf-api.patch
Patch0006: 0006-CVE-2023-47234.patch Patch0006: 0006-graceful-restart.patch
Patch0007: 0007-CVE-2023-46752.patch Patch0007: 0007-cve-2022-37032.patch
Patch0008: 0008-CVE-2023-46753.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
Patch0013: 0013-CVE-2023-38802.patch
Patch0014: 0014-max-ttl-reload.patch
Patch0015: 0015-CVE-2023-47235.patch
Patch0016: 0016-CVE-2023-47234.patch
Patch0017: 0017-CVE-2023-38406.patch
Patch0018: 0018-CVE-2023-38407.patch
%description %description
FRRouting is free software that manages TCP/IP based routing protocols. It takes FRRouting is free software that manages TCP/IP based routing protocols. It takes
@ -276,24 +286,23 @@ make check PYTHON=%{__python3}
%endif %endif
%changelog %changelog
* Mon Feb 05 2024 Michal Ruprich <mruprich@redhat.com> - 8.5.3-4 * Thu Dec 21 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11.2
- Resolves: RHEL-14825 - crafted BGP UPDATE message leading to a crash - Resolves: RHEL-17480 - Out of bounds read in bgpd/bgp_label.c
* Mon Feb 05 2024 Michal Ruprich <mruprich@redhat.com> - 8.5.3-3 * Thu Dec 21 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11.2
- Resolves: RHEL-14822 - mishandled malformed data leading to a crash - Resolves: RHEL-17474 - Flowspec overflow in bgpd/bgp_flowspec.c
* Mon Dec 18 2023 Michal Ruprich <mruprich@redhat.com> - 8.5.3-2 * Tue Dec 19 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11.2
- Resolves: RHEL-15915 - crash from specially crafted MP_UNREACH_NLRI-containing BGP UPDATE message - Resolves: RHEL-17471 - crash from specially crafted MP_UNREACH_NLRI-containing BGP UPDATE message
- Resolves: RHEL-15918 - crash from malformed EOR-containing BGP UPDATE message
* Thu Nov 23 2023 Michal Ruprich <mruprich@redhat.com> - 8.5.3-1 * Mon Dec 18 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11.2
- Resolves: RHEL-15291 - Rebase FRR to version 8.5.3 in RHEL9 - Resolves: RHEL-17477 - crash from malformed EOR-containing BGP UPDATE message
* Fri Oct 13 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-12 * Wed Oct 11 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11.1
- Resolves: RHEL-3541 - Incorrect handling of a error in parsing of an invalid section of a BGP update can de-peer a router - Resolves: RHEL-11665 - eBGP multihop peer flapping due to delta miscalculation of new configuration
* Thu Sep 21 2023 Carlos Goncalves <cgoncalves@redhat.com> - 8.3.1-11 * Wed Sep 13 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-11
- Resolves: RHEL-2263 - bgpd: Do not explicitly print MAXTTL value for ebgp-multihop vty output - Resolves: #2231001 - Incorrect handling of a error in parsing of an invalid section of a BGP update can de-peer a router
* Thu Aug 10 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-10 * Thu Aug 10 2023 Michal Ruprich <mruprich@redhat.com> - 8.3.1-10
- Related: #2216912 - adding sys_admin to capabilities - Related: #2216912 - adding sys_admin to capabilities

Loading…
Cancel
Save