]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
Merge pull request #12558 from donaldsharp/bgp_static_route_mem_leak
[mirror_frr.git] / bgpd / bgp_route.c
index d1316dbc4f4edc34a93cf4a1f2b9ae19996d4ea5..f4b01ab2727c7dab91b42d28c870f164e34a2029 100644 (file)
@@ -8679,6 +8679,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
        afi_t afi;
        route_map_result_t ret;
        struct bgp_redist *red;
+       struct interface *ifp;
 
        /* Make default attribute. */
        bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE);
@@ -8728,6 +8729,11 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
        }
        attr.nh_type = nhtype;
        attr.nh_ifindex = ifindex;
+       ifp = if_lookup_by_index(ifindex, bgp->vrf_id);
+       if (ifp && if_is_operative(ifp))
+               SET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
+       else
+               UNSET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);
 
        attr.med = metric;
        attr.distance = distance;
@@ -9414,9 +9420,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                                                       "link-local");
 
                                if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global,
-                                                  &attr->mp_nexthop_local)
-                                    != 0)
-                                   && !attr->mp_nexthop_prefer_global)
+                                                  &attr->mp_nexthop_local) !=
+                                    0) &&
+                                   !CHECK_FLAG(attr->nh_flag,
+                                               BGP_ATTR_NH_MP_PREFER_GLOBAL))
                                        json_object_boolean_true_add(
                                                json_nexthop_ll, "used");
                                else
@@ -9428,10 +9435,11 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                } else {
                        /* Display LL if LL/Global both in table unless
                         * prefer-global is set */
-                       if (((attr->mp_nexthop_len
-                             == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL)
-                            && !attr->mp_nexthop_prefer_global)
-                           || (path->peer->conf_if)) {
+                       if (((attr->mp_nexthop_len ==
+                             BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) &&
+                            !CHECK_FLAG(attr->nh_flag,
+                                        BGP_ATTR_NH_MP_PREFER_GLOBAL)) ||
+                           (path->peer->conf_if)) {
                                if (path->peer->conf_if) {
                                        len = vty_out(vty, "%s",
                                                      path->peer->conf_if);
@@ -10693,7 +10701,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
                        json_object_boolean_true_add(json_nexthop_ll,
                                                     "accessible");
 
-                       if (!attr->mp_nexthop_prefer_global)
+                       if (!CHECK_FLAG(attr->nh_flag,
+                                       BGP_ATTR_NH_MP_PREFER_GLOBAL))
                                json_object_boolean_true_add(json_nexthop_ll,
                                                             "used");
                        else
@@ -10703,7 +10712,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
                        vty_out(vty, "    (%s) %s\n",
                                inet_ntop(AF_INET6, &attr->mp_nexthop_local,
                                          buf, INET6_ADDRSTRLEN),
-                               attr->mp_nexthop_prefer_global
+                               CHECK_FLAG(attr->nh_flag,
+                                          BGP_ATTR_NH_MP_PREFER_GLOBAL)
                                        ? "(prefer-global)"
                                        : "(used)");
                }
@@ -11252,6 +11262,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
        bool use_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
        bool wide = CHECK_FLAG(show_flags, BGP_SHOW_OPT_WIDE);
        bool all = CHECK_FLAG(show_flags, BGP_SHOW_OPT_AFI_ALL);
+       bool detail_json = CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
+       bool detail_routes = CHECK_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
 
        if (output_cum && *output_cum != 0)
                header = false;
@@ -11285,8 +11297,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
        }
 
        /* Check for 'json detail', where we need header output once per dest */
-       if (use_json && CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL) &&
-           type != bgp_show_type_dampend_paths &&
+       if (use_json && detail_json && type != bgp_show_type_dampend_paths &&
            type != bgp_show_type_damp_neighbor &&
            type != bgp_show_type_flap_statistics &&
            type != bgp_show_type_flap_neighbor)
@@ -11549,17 +11560,19 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                vty_out(vty, "Default local pref %u, ",
                                        bgp->default_local_pref);
                                vty_out(vty, "local AS %u\n", bgp->as);
-                               vty_out(vty, BGP_SHOW_SCODE_HEADER);
-                               vty_out(vty, BGP_SHOW_NCODE_HEADER);
-                               vty_out(vty, BGP_SHOW_OCODE_HEADER);
-                               vty_out(vty, BGP_SHOW_RPKI_HEADER);
+                               if (!detail_routes) {
+                                       vty_out(vty, BGP_SHOW_SCODE_HEADER);
+                                       vty_out(vty, BGP_SHOW_NCODE_HEADER);
+                                       vty_out(vty, BGP_SHOW_OCODE_HEADER);
+                                       vty_out(vty, BGP_SHOW_RPKI_HEADER);
+                               }
                                if (type == bgp_show_type_dampend_paths
                                    || type == bgp_show_type_damp_neighbor)
                                        vty_out(vty, BGP_SHOW_DAMP_HEADER);
                                else if (type == bgp_show_type_flap_statistics
                                         || type == bgp_show_type_flap_neighbor)
                                        vty_out(vty, BGP_SHOW_FLAP_HEADER);
-                               else
+                               else if (!detail_routes)
                                        vty_out(vty, (wide ? BGP_SHOW_HEADER_WIDE
                                                           : BGP_SHOW_HEADER));
                                header = false;
@@ -11602,16 +11615,30 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                                   AFI_IP, safi, use_json,
                                                   json_paths);
                        else {
-                               if (CHECK_FLAG(show_flags, BGP_SHOW_OPT_DETAIL))
+                               if (detail_routes || detail_json) {
+                                       const struct prefix_rd *prd = NULL;
+
+                                       if (dest->pdest)
+                                               prd = bgp_rd_from_dest(
+                                                       dest->pdest, safi);
+
+                                       if (!use_json)
+                                               route_vty_out_detail_header(
+                                                       vty, bgp, dest,
+                                                       bgp_dest_get_prefix(
+                                                               dest),
+                                                       prd, table->afi, safi,
+                                                       NULL);
+
                                        route_vty_out_detail(
-                                               vty, bgp, dest,
-                                               bgp_dest_get_prefix(dest), pi,
+                                               vty, bgp, dest, dest_p, pi,
                                                family2afi(dest_p->family),
                                                safi, RPKI_NOT_BEING_USED,
                                                json_paths);
-                               else
+                               } else {
                                        route_vty_out(vty, dest_p, pi, display,
                                                      safi, json_paths, wide);
+                               }
                        }
                        display++;
                }
@@ -11693,7 +11720,8 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
 
 int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
                      struct bgp_table *table, struct prefix_rd *prd_match,
-                     enum bgp_show_type type, void *output_arg, bool use_json)
+                     enum bgp_show_type type, void *output_arg,
+                     uint16_t show_flags)
 {
        struct bgp_dest *dest, *next;
        unsigned long output_cum = 0;
@@ -11701,13 +11729,10 @@ int bgp_show_table_rd(struct vty *vty, struct bgp *bgp, safi_t safi,
        unsigned long json_header_depth = 0;
        struct bgp_table *itable;
        bool show_msg;
-       uint16_t show_flags = 0;
+       bool use_json = !!CHECK_FLAG(show_flags, BGP_SHOW_OPT_JSON);
 
        show_msg = (!use_json && type == bgp_show_type_normal);
 
-       if (use_json)
-               SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
-
        for (dest = bgp_table_top(table); dest; dest = next) {
                const struct prefix *dest_p = bgp_dest_get_prefix(dest);
 
@@ -11773,7 +11798,7 @@ static int bgp_show(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
        /* use MPLS and ENCAP specific shows until they are merged */
        if (safi == SAFI_MPLS_VPN) {
                return bgp_show_table_rd(vty, bgp, safi, table, NULL, type,
-                                        output_arg, use_json);
+                                        output_arg, show_flags);
        }
 
        if (safi == SAFI_FLOWSPEC && type == bgp_show_type_detail) {
@@ -12655,7 +12680,8 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
           |A.B.C.D/M longer-prefixes\
           |X:X::X:X/M longer-prefixes\
          |optimal-route-reflection [WORD$orr_group_name]\
-          ] [json$uj [detail$detail] | wide$wide]",
+          |detail-routes$detail_routes\
+          ] [json$uj [detail$detail_json] | wide$wide]",
       SHOW_STR IP_STR BGP_STR BGP_INSTANCE_HELP_STR BGP_AFI_HELP_STR
              BGP_SAFI_WITH_LABEL_HELP_STR
       "Display the entries for all address families\n"
@@ -12705,6 +12731,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
       "Display route and more specific routes\n"
       "Display Optimal Route Reflection RR Clients\n"
       "ORR Group name\n"
+      "Display detailed version of all routes\n"
       JSON_STR
       "Display detailed version of JSON output\n"
       "Increase table width for longer prefixes\n")
@@ -12728,8 +12755,11 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
                SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
        }
 
-       if (detail)
-               SET_FLAG(show_flags, BGP_SHOW_OPT_DETAIL);
+       if (detail_json)
+               SET_FLAG(show_flags, BGP_SHOW_OPT_JSON_DETAIL);
+
+       if (detail_routes)
+               SET_FLAG(show_flags, BGP_SHOW_OPT_ROUTES_DETAIL);
 
        /* [<ipv4|ipv6> [all]] */
        if (all) {
@@ -14706,7 +14736,7 @@ DEFUN (show_ip_bgp_flowspec_routes_detailed,
        struct bgp *bgp = NULL;
        int idx = 0;
        bool uj = use_json(argc, argv);
-       uint16_t show_flags = BGP_SHOW_OPT_DETAIL;
+       uint16_t show_flags = BGP_SHOW_OPT_ROUTES_DETAIL;
 
        if (uj) {
                argc--;