From: Philippe Guibert Date: Tue, 31 Jan 2023 08:27:01 +0000 (+0100) Subject: bgpd: attr evpn attributes should be modified before interning attr X-Git-Tag: base_9.0~320^2~1 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=7171949de55066f6f73ec7ced19a6b0cb96872a8;p=matthieu%2Ffrr.git bgpd: attr evpn attributes should be modified before interning attr As remind, the attr attribute is a structure that contains the attributes for a given BGP update. In order to avoid too much memory consumption, the attr structure is stored in a hash table. As consequence, other BGP updates may reuse the same attr. The storage in the hash table is done when calling bgp_attr_intern(), and a key is calculated based on all the attributes values of the structure. In BGP EVPN, when modifying the attributes of the attr structure after having interned it, this means that some BGP updates will want to use the old reference, whereas a new attr value is used. Because in BGP EVPN, the modifications are done on a per BGP update basis, a new attr entry specific to that BGP update should be created. This is why a local_attr structure is done, modified, then later interned. Signed-off-by: Philippe Guibert --- diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index a8560ab539..11e38aa033 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -1837,6 +1837,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, struct bgp_path_info *tmp_pi; struct bgp_path_info *local_pi; struct attr *attr_new; + struct attr local_attr; mpls_label_t label[BGP_MAX_LABELS]; uint32_t num_labels = 1; int route_change = 1; @@ -1870,13 +1871,15 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, add_mac_mobility_to_attr(seq, attr); if (!local_pi) { - /* Add (or update) attribute to hash. */ - attr_new = bgp_attr_intern(attr); + local_attr = *attr; /* Extract MAC mobility sequence number, if any. */ - attr_new->mm_seqnum = - bgp_attr_mac_mobility_seqnum(attr_new, &sticky); - attr_new->sticky = sticky; + local_attr.mm_seqnum = + bgp_attr_mac_mobility_seqnum(&local_attr, &sticky); + local_attr.sticky = sticky; + + /* Add (or update) attribute to hash. */ + attr_new = bgp_attr_intern(&local_attr); /* Create new route with its attribute. */ tmp_pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0, @@ -1952,14 +1955,16 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn, /* The attribute has changed. */ /* Add (or update) attribute to hash. */ - attr_new = bgp_attr_intern(attr); + local_attr = *attr; bgp_path_info_set_flag(dest, tmp_pi, BGP_PATH_ATTR_CHANGED); /* Extract MAC mobility sequence number, if any. */ - attr_new->mm_seqnum = - bgp_attr_mac_mobility_seqnum(attr_new, &sticky); - attr_new->sticky = sticky; + local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum( + &local_attr, &sticky); + local_attr.sticky = sticky; + + attr_new = bgp_attr_intern(&local_attr); /* Restore route, if needed. */ if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED))