]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
Merge pull request #5257 from ton31337/fix/update_rib_on_bgp_distance_changes
[mirror_frr.git] / bgpd / bgp_route.c
index 2ef0aaaaf6e9108892ef106af79c064968b8734a..4fb4faebc2f14d34a18358d27b9096db3ebfae58 100644 (file)
@@ -196,7 +196,8 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
 
        e = *extra;
        if (e->damp_info)
-               bgp_damp_info_free(e->damp_info, 0);
+               bgp_damp_info_free(e->damp_info, 0, e->damp_info->afi,
+                                  e->damp_info->safi);
 
        e->damp_info = NULL;
        if (e->parent) {
@@ -1243,7 +1244,7 @@ static int bgp_cluster_filter(struct peer *peer, struct attr *attr)
 static int bgp_input_modifier(struct peer *peer, struct prefix *p,
                              struct attr *attr, afi_t afi, safi_t safi,
                              const char *rmap_name, mpls_label_t *label,
-                             uint32_t num_labels)
+                             uint32_t num_labels, struct bgp_node *rn)
 {
        struct bgp_filter *filter;
        struct bgp_path_info rmap_path = { 0 };
@@ -1278,6 +1279,8 @@ static int bgp_input_modifier(struct peer *peer, struct prefix *p,
                rmap_path.peer = peer;
                rmap_path.attr = attr;
                rmap_path.extra = &extra;
+               rmap_path.net = rn;
+
                extra.num_labels = num_labels;
                if (label && num_labels && num_labels <= BGP_MAX_LABELS)
                        memcpy(extra.label, label,
@@ -1794,6 +1797,7 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
                memset(&rmap_path, 0, sizeof(struct bgp_path_info));
                rmap_path.peer = peer;
                rmap_path.attr = attr;
+               rmap_path.net = rn;
 
                if (pi->extra) {
                        memcpy(&dummy_rmap_path_extra, pi->extra,
@@ -1941,19 +1945,19 @@ int subgroup_announce_check(struct bgp_node *rn, struct bgp_path_info *pi,
                                        __func__, family2str(family));
                        subgroup_announce_reset_nhop(family, attr);
                }
+       }
 
-               /* If IPv6/MP and nexthop does not have any override and happens
-                * to
-                * be a link-local address, reset it so that we don't pass along
-                * the
-                * source's link-local IPv6 address to recipients who may not be
-                * on
-                * the same interface.
-                */
-               if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
-                       if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
-                               subgroup_announce_reset_nhop(AF_INET6, attr);
-               }
+       /* If IPv6/MP and nexthop does not have any override and happens
+        * to
+        * be a link-local address, reset it so that we don't pass along
+        * the
+        * source's link-local IPv6 address to recipients who may not be
+        * on
+        * the same interface.
+        */
+       if (p->family == AF_INET6 || peer_cap_enhe(peer, afi, safi)) {
+               if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+                       subgroup_announce_reset_nhop(AF_INET6, attr);
        }
 
        return 1;
@@ -3037,6 +3041,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
        int connected = 0;
        int do_loop_check = 1;
        int has_valid_label = 0;
+       afi_t nh_afi;
 #if ENABLE_BGP_VNC
        int vnc_implicit_withdraw = 0;
 #endif
@@ -3152,7 +3157,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
         * intern
         * the attr (which takes over the memory references) */
        if (bgp_input_modifier(peer, p, &new_attr, afi, safi, NULL,
-               label, num_labels) == RMAP_DENY) {
+               label, num_labels, rn) == RMAP_DENY) {
                peer->stat_pfx_filter++;
                reason = "route-map;";
                bgp_attr_flush(&new_attr);
@@ -3432,8 +3437,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
 
                /* Nexthop reachability check - for unicast and
                 * labeled-unicast.. */
-               if ((afi == AFI_IP || afi == AFI_IP6)
-                   && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
+               if (((afi == AFI_IP || afi == AFI_IP6)
+                   && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
+                   || (safi == SAFI_EVPN &&
+                       bgp_evpn_is_prefix_nht_supported(p))) {
                        if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
                            && !CHECK_FLAG(peer->flags,
                                           PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -3448,8 +3455,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                        if (pi->extra && pi->extra->bgp_orig)
                                bgp_nexthop = pi->extra->bgp_orig;
 
-                       if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, pi,
-                                                   NULL, connected)
+                       nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
+
+                       if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi,
+                                                   pi, NULL, connected)
                            || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
                                bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);
                        else {
@@ -3497,7 +3506,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                 * updating
                 * the attributes for the route in the VNI(s).
                 */
-               if (safi == SAFI_EVPN && !same_attr)
+               if (safi == SAFI_EVPN && !same_attr &&
+                   CHECK_FLAG(pi->flags, BGP_PATH_VALID))
                        bgp_evpn_import_route(bgp, afi, safi, p, pi);
 
                /* Process change. */
@@ -3570,8 +3580,9 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                                     evpn == NULL ? NULL : &evpn->gw_ip);
        }
        /* Nexthop reachability check. */
-       if ((afi == AFI_IP || afi == AFI_IP6)
-           && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) {
+       if (((afi == AFI_IP || afi == AFI_IP6)
+           && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST))
+           || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {
                if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1
                    && !CHECK_FLAG(peer->flags,
                                   PEER_FLAG_DISABLE_CONNECTED_CHECK)
@@ -3580,7 +3591,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                else
                        connected = 0;
 
-               if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, connected)
+               nh_afi = BGP_ATTR_NH_AFI(afi, new->attr);
+
+               if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL,
+                                           connected)
                    || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))
                        bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);
                else {
@@ -3631,7 +3645,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,
                return -1;
 
        /* If this is an EVPN route, process for import. */
-       if (safi == SAFI_EVPN)
+       if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))
                bgp_evpn_import_route(bgp, afi, safi, p, new);
 
        hook_call(bgp_process, bgp, afi, safi, rn, peer, false);
@@ -7883,7 +7897,7 @@ void route_vty_out_overlay(struct vty *vty, struct prefix *p,
 
 /* dampening route */
 static void damp_route_vty_out(struct vty *vty, struct prefix *p,
-                              struct bgp_path_info *path, int display,
+                              struct bgp_path_info *path, int display, afi_t afi,
                               safi_t safi, bool use_json, json_object *json)
 {
        struct attr *attr;
@@ -7914,13 +7928,13 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p,
        }
 
        if (use_json)
-               bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN,
-                                       use_json, json);
+               bgp_damp_reuse_time_vty(vty, path, timebuf, BGP_UPTIME_LEN, afi,
+                                       safi, use_json, json);
        else
                vty_out(vty, "%s ",
                        bgp_damp_reuse_time_vty(vty, path, timebuf,
-                                               BGP_UPTIME_LEN, use_json,
-                                               json));
+                                               BGP_UPTIME_LEN, afi, safi,
+                                               use_json, json));
 
        /* Print attribute */
        attr = path->attr;
@@ -7947,7 +7961,7 @@ static void damp_route_vty_out(struct vty *vty, struct prefix *p,
 
 /* flap route */
 static void flap_route_vty_out(struct vty *vty, struct prefix *p,
-                              struct bgp_path_info *path, int display,
+                              struct bgp_path_info *path, int display, afi_t afi,
                               safi_t safi, bool use_json, json_object *json)
 {
        struct attr *attr;
@@ -8006,12 +8020,13 @@ static void flap_route_vty_out(struct vty *vty, struct prefix *p,
            && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY)) {
                if (use_json)
                        bgp_damp_reuse_time_vty(vty, path, timebuf,
-                                               BGP_UPTIME_LEN, use_json, json);
+                                               BGP_UPTIME_LEN, afi, safi,
+                                               use_json, json);
                else
                        vty_out(vty, "%s ",
                                bgp_damp_reuse_time_vty(vty, path, timebuf,
-                                                       BGP_UPTIME_LEN,
-                                                       use_json, json));
+                                                       BGP_UPTIME_LEN, afi,
+                                                       safi, use_json, json));
        } else {
                if (!use_json)
                        vty_out(vty, "%*s ", 8, " ");
@@ -8879,7 +8894,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
        }
 
        if (path->extra && path->extra->damp_info)
-               bgp_damp_info_vty(vty, path, json_path);
+               bgp_damp_info_vty(vty, path, afi, safi, json_path);
 
        /* Remote Label */
        if (path->extra && bgp_is_valid_label(&path->extra->label[0])
@@ -9292,11 +9307,11 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                        }
                        if (type == bgp_show_type_dampend_paths
                            || type == bgp_show_type_damp_neighbor)
-                               damp_route_vty_out(vty, &rn->p, pi, display,
+                               damp_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
                                                   safi, use_json, json_paths);
                        else if (type == bgp_show_type_flap_statistics
                                 || type == bgp_show_type_flap_neighbor)
-                               flap_route_vty_out(vty, &rn->p, pi, display,
+                               flap_route_vty_out(vty, &rn->p, pi, display, AFI_IP,
                                                   safi, use_json, json_paths);
                        else
                                route_vty_out(vty, &rn->p, pi, display, safi,
@@ -10548,7 +10563,7 @@ static int bgp_show_prefix_longer(struct vty *vty, struct bgp *bgp,
        }
 
        ret = bgp_show(vty, bgp, afi, safi, type, p, 0);
-       prefix_free(p);
+       prefix_free(&p);
        return ret;
 }
 
@@ -11109,7 +11124,7 @@ DEFUN (show_bgp_l2vpn_evpn_route_prefix,
                argv_find(argv, argc, "X:X::X:X", &idx))
                network = argv[idx]->arg;
        else if (argv_find(argv, argc, "A.B.C.D/M", &idx) ||
-               argv_find(argv, argc, "A.B.C.D/M", &idx)) {
+               argv_find(argv, argc, "X:X::X:X/M", &idx)) {
                network = argv[idx]->arg;
                prefix_check = 1;
        } else {
@@ -11297,7 +11312,8 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
 
                                /* Filter prefix using route-map */
                                ret = bgp_input_modifier(peer, &rn->p, &attr,
-                                               afi, safi, rmap_name, NULL, 0);
+                                               afi, safi, rmap_name, NULL, 0,
+                                               NULL);
 
                                if (type == bgp_show_adj_route_filtered &&
                                        !route_filtered && ret != RMAP_DENY) {
@@ -12238,7 +12254,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                                                pi_temp = pi->next;
                                                bgp_damp_info_free(
                                                        pi->extra->damp_info,
-                                                       1);
+                                                       1, afi, safi);
                                                pi = pi_temp;
                                        } else
                                                pi = pi->next;
@@ -12258,7 +12274,7 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
                                                pi_temp = pi->next;
                                                bgp_damp_info_free(
                                                        pi->extra->damp_info,
-                                                       1);
+                                                       1, afi, safi);
                                                pi = pi_temp;
                                        } else
                                                pi = pi->next;
@@ -12280,7 +12296,7 @@ DEFUN (clear_ip_bgp_dampening,
        BGP_STR
        "Clear route flap dampening information\n")
 {
-       bgp_damp_info_clean();
+       bgp_damp_info_clean(AFI_IP, SAFI_UNICAST);
        return CMD_SUCCESS;
 }