From 575f68e73c947bc00f8c206e13eb81fa8127fa6d Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Sun, 23 Jul 2023 20:30:47 -0400 Subject: [PATCH] bgpd: The last_reset_cause in the peer structure is too large The last_reset_cause is a plain old BGP_MAX_PACKET_SIZE buffer that is really enlarging the peer data structure. Let's just copy the stream that failed and only allocate how ever much the packet size actually was. While it's likely that we have a reset reason, the packet typically is not going to be 65k in size. Let's save space. Signed-off-by: Donald Sharp (cherry picked from commit 73b66bed83a38eea37371c6bbb0655c72c903293) --- bgpd/bgp_packet.c | 5 +++-- bgpd/bgp_vty.c | 8 ++++---- bgpd/bgpd.c | 2 ++ bgpd/bgpd.h | 3 +-- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 9469a0778f..bd17a2eec8 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -956,8 +956,9 @@ static void bgp_notify_send_internal(struct peer *peer, uint8_t code, if (use_curr && peer->curr) { size_t packetsize = stream_get_endp(peer->curr); assert(packetsize <= peer->max_packet_size); - memcpy(peer->last_reset_cause, peer->curr->data, packetsize); - peer->last_reset_cause_size = packetsize; + if (peer->last_reset_cause) + stream_free(peer->last_reset_cause); + peer->last_reset_cause = stream_dup(peer->curr); } /* For debug */ diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index f50dd563e1..ab5eff8d07 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -14853,15 +14853,15 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json, BGP_UPTIME_LEN, 0, NULL)); bgp_show_peer_reset(vty, p, NULL, false); - if (p->last_reset_cause_size) { - msg = p->last_reset_cause; + if (p->last_reset_cause) { + msg = p->last_reset_cause->data; vty_out(vty, " Message received that caused BGP to send a NOTIFICATION:\n "); - for (i = 1; i <= p->last_reset_cause_size; + for (i = 1; i <= p->last_reset_cause->size; i++) { vty_out(vty, "%02X", *msg++); - if (i != p->last_reset_cause_size) { + if (i != p->last_reset_cause->size) { if (i % 16 == 0) { vty_out(vty, "\n "); } else if (i % 4 == 0) { diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 86bded14bb..aea7f6f65c 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -1190,6 +1190,8 @@ static void peer_free(struct peer *peer) bgp_unlock(peer->bgp); + stream_free(peer->last_reset_cause); + memset(peer, 0, sizeof(struct peer)); XFREE(MTYPE_BGP_PEER, peer); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 5e443ca5c9..833312754a 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -1706,8 +1706,7 @@ struct peer { * a new value to the last_reset reason */ - uint16_t last_reset_cause_size; - uint8_t last_reset_cause[BGP_MAX_PACKET_SIZE]; + struct stream *last_reset_cause; /* The kind of route-map Flags.*/ uint16_t rmap_type; -- 2.39.5