]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_evpn.c
Merge pull request #5844 from qlyoung/fix-zebra-gr-unnecessary-malloc
[mirror_frr.git] / bgpd / bgp_evpn.c
index 48b714c7df4cdab8294fc3329cd2089511c671b1..206680c403fba25d82af8ba5d2446e1ff7a83156 100644 (file)
@@ -49,6 +49,7 @@
 #include "bgpd/bgp_nexthop.h"
 #include "bgpd/bgp_addpath.h"
 #include "bgpd/bgp_mac.h"
+#include "bgpd/bgp_vty.h"
 
 /*
  * Definitions and external declarations.
@@ -1571,7 +1572,7 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
         * present, else treat as locally originated.
         */
        if (src_attr)
-               bgp_attr_dup(&attr, src_attr);
+               attr = *src_attr;
        else {
                memset(&attr, 0, sizeof(struct attr));
                bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
@@ -2525,13 +2526,13 @@ static int handle_tunnel_ip_change(struct bgp *bgp, struct bgpevpn *vpn,
 
 static struct bgp_path_info *
 bgp_create_evpn_bgp_path_info(struct bgp_path_info *parent_pi,
-                             struct bgp_node *rn)
+                             struct bgp_node *rn, struct attr *attr)
 {
        struct attr *attr_new;
        struct bgp_path_info *pi;
 
        /* Add (or update) attribute to hash. */
-       attr_new = bgp_attr_intern(parent_pi->attr);
+       attr_new = bgp_attr_intern(attr);
 
        /* Create new route with its attribute. */
        pi = info_make(parent_pi->type, BGP_ROUTE_IMPORTED, 0, parent_pi->peer,
@@ -2661,7 +2662,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
         * address for the rest of the code to flow through. In the case of IPv4,
         * make sure to set the flag for next hop attribute.
         */
-       bgp_attr_dup(&attr, parent_pi->attr);
+       attr = *parent_pi->attr;
        if (afi == AFI_IP6)
                evpn_convert_nexthop_to_ipv6(&attr);
        else
@@ -2674,7 +2675,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                        break;
 
        if (!pi)
-               pi = bgp_create_evpn_bgp_path_info(parent_pi, rn);
+               pi = bgp_create_evpn_bgp_path_info(parent_pi, rn, &attr);
        else {
                if (attrhash_cmp(pi->attr, &attr)
                    && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
@@ -2703,6 +2704,8 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                pi->attr = attr_new;
                pi->uptime = bgp_clock();
        }
+       /* as it is an importation, change nexthop */
+       bgp_path_info_set_flag(rn, pi, BGP_PATH_ANNC_NH_SELF);
 
        bgp_aggregate_increment(bgp_vrf, &rn->p, pi, afi, safi);
 
@@ -2741,7 +2744,8 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
 
        if (!pi) {
                /* Create an info */
-               (void)bgp_create_evpn_bgp_path_info(parent_pi, rn);
+               (void)bgp_create_evpn_bgp_path_info(parent_pi, rn,
+                                                   parent_pi->attr);
        } else {
                if (attrhash_cmp(pi->attr, parent_pi->attr)
                    && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
@@ -4188,6 +4192,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
        uint32_t eth_tag;
        mpls_label_t label; /* holds the VNI as in the packet */
        int ret;
+       afi_t gw_afi;
+       bool is_valid_update = false;
 
        /* Type-5 route should be 34 or 58 bytes:
         * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16),
@@ -4246,12 +4252,14 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
                pfx += 4;
                memcpy(&evpn.gw_ip.ipv4, pfx, 4);
                pfx += 4;
+               gw_afi = AF_INET;
        } else {
                SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
                memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, 16);
                pfx += 16;
                memcpy(&evpn.gw_ip.ipv6, pfx, 16);
                pfx += 16;
+               gw_afi = AF_INET6;
        }
 
        /* Get the VNI (in MPLS label field). Stored as bytes here. */
@@ -4264,8 +4272,18 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
         * field
         */
 
+       if (attr) {
+               is_valid_update = true;
+               if (is_zero_mac(&attr->rmac) && is_zero_esi(&evpn.eth_s_id) &&
+                   is_zero_gw_ip(&evpn.gw_ip, gw_afi))
+                       is_valid_update = false;
+
+               if (is_mcast_mac(&attr->rmac) || is_bcast_mac(&attr->rmac))
+                       is_valid_update = false;
+       }
+
        /* Process the route. */
-       if (attr)
+       if (is_valid_update)
                ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
                                 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
                                 &prd, &label, 1, 0, &evpn);
@@ -5099,7 +5117,8 @@ int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
                        if (pnt + BGP_ADDPATH_ID_LEN > lim)
                                return BGP_NLRI_PARSE_ERROR_PACKET_OVERFLOW;
 
-                       addpath_id = ntohl(*((uint32_t *)pnt));
+                       memcpy(&addpath_id, pnt, BGP_ADDPATH_ID_LEN);
+                       addpath_id = ntohl(addpath_id);
                        pnt += BGP_ADDPATH_ID_LEN;
                }
 
@@ -5709,9 +5728,10 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id,
 
                int ret = 0;
 
-               ret = bgp_get(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
-                             vrf_id == VRF_DEFAULT ? BGP_INSTANCE_TYPE_DEFAULT
-                                                   : BGP_INSTANCE_TYPE_VRF);
+               ret = bgp_get_vty(&bgp_vrf, &as, vrf_id_to_name(vrf_id),
+                                 vrf_id == VRF_DEFAULT
+                                 ? BGP_INSTANCE_TYPE_DEFAULT
+                                 : BGP_INSTANCE_TYPE_VRF);
                switch (ret) {
                case BGP_ERR_AS_MISMATCH:
                        flog_err(EC_BGP_EVPN_AS_MISMATCH,