]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: attr evpn attributes should be modified before interning attr
authorPhilippe Guibert <philippe.guibert@6wind.com>
Tue, 31 Jan 2023 08:27:01 +0000 (09:27 +0100)
committerPhilippe Guibert <philippe.guibert@6wind.com>
Fri, 24 Feb 2023 07:16:36 +0000 (08:16 +0100)
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 <philippe.guibert@6wind.com>
bgpd/bgp_evpn.c

index a8560ab53922c388eca49f9ae47a396e2e8ca930..11e38aa0337ea598019610f1d1cc09e385b40107 100644 (file)
@@ -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))