Skip to content

Commit 6e076ba

Browse files
committed
bgpd: Fix for ain->attr corruption during path update
1. Consider a established L2VPN EVPN BGP peer with soft-reconfiguartion inbound configured 2. When the interface of this directly connected BGP peer is shutdown, bgp_soft_reconfig_table_update() is called, which memsets the evpn buffer and calls bgp_update() with received attributes stored in ain table(ain->attr). In bgp_update(), evpn_overlay attribute in ain->attr (which is an interned attr) was modified by doing a memcpy 3. Above action causes 2 attributes in the attrhash (which were previously different) to match! 4. Later during fsm change event of the peer, bgp_adj_in_remove() is called to clean up the ain->attr. But, because 2 attrs in attrhash match, it causes BGP to assert in bgp_attr_unintern() Signed-off-by: Pooja Jagadeesh Doijode <[email protected]>
1 parent 74aad5a commit 6e076ba

File tree

1 file changed

+23
-7
lines changed

1 file changed

+23
-7
lines changed

bgpd/bgp_route.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4065,17 +4065,24 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
40654065
if (has_valid_label)
40664066
assert(label != NULL);
40674067

4068-
/* Update overlay index of the attribute */
4069-
if (afi == AFI_L2VPN && evpn)
4070-
memcpy(&attr->evpn_overlay, evpn,
4071-
sizeof(struct bgp_route_evpn));
40724068

40734069
/* When peer's soft reconfiguration enabled. Record input packet in
40744070
Adj-RIBs-In. */
4075-
if (!soft_reconfig
4076-
&& CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG)
4077-
&& peer != bgp->peer_self)
4071+
if (!soft_reconfig &&
4072+
CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_SOFT_RECONFIG) &&
4073+
peer != bgp->peer_self) {
4074+
/*
4075+
* If the trigger is not from soft_reconfig and if
4076+
* PEER_FLAG_SOFT_RECONFIG is enabled for the peer, then attr
4077+
* will not be interned. In which case, it is ok to update the
4078+
* attr->evpn_overlay, so that, this can be stored in adj_in.
4079+
*/
4080+
if ((afi == AFI_L2VPN) && evpn) {
4081+
memcpy(&attr->evpn_overlay, evpn,
4082+
sizeof(struct bgp_route_evpn));
4083+
}
40784084
bgp_adj_in_set(dest, peer, attr, addpath_id);
4085+
}
40794086

40804087
/* Update permitted loop count */
40814088
if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_ALLOWAS_IN))
@@ -4203,6 +4210,15 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
42034210
}
42044211

42054212
new_attr = *attr;
4213+
/*
4214+
* If bgp_update is called with soft_reconfig set then
4215+
* attr is interned. In this case, do not overwrite the
4216+
* attr->evpn_overlay with evpn directly. Instead memcpy
4217+
* evpn to new_atr.evpn_overlay before it is interned.
4218+
*/
4219+
if (soft_reconfig && (afi == AFI_L2VPN) && evpn)
4220+
memcpy(&new_attr.evpn_overlay, evpn,
4221+
sizeof(struct bgp_route_evpn));
42064222

42074223
/* Apply incoming route-map.
42084224
* NB: new_attr may now contain newly allocated values from route-map

0 commit comments

Comments
 (0)