]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_vty.c
bgpd: `neighbor X:X::X default-originate` complains about (null)
[mirror_frr.git] / bgpd / bgp_vty.c
index 2aa4e3ecd4ecda1d410083a33e927a868b1ec27a..d05432327d770d5efd52eebc7f5d3cf1e04f111e 100644 (file)
@@ -295,6 +295,7 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
  * afi  -> The parsed afi if it was included in the show command, returned here
  * safi -> The parsed safi if it was included in the show command, returned here
  * bgp  -> Pointer to the bgp data structure we need to fill in.
+ * use_json -> json is configured or not
  *
  * The function returns the correct location in the parse tree for the
  * last token found.
@@ -329,8 +330,17 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                else {
                        *bgp = bgp_lookup_by_name(vrf_name);
                        if (!*bgp) {
-                               if (use_json)
-                                       vty_out(vty, "{}\n");
+                               if (use_json) {
+                                       json_object *json = NULL;
+                                       json = json_object_new_object();
+                                       json_object_string_add(
+                                         json, "warning",
+                                         "View/Vrf is unknown");
+                                       vty_out(vty, "%s\n",
+                                               json_object_to_json_string_ext(json,
+                                                       JSON_C_TO_STRING_PRETTY));
+                                       json_object_free(json);
+                               }
                                else
                                        vty_out(vty, "View/Vrf %s is unknown\n",
                                                vrf_name);
@@ -341,8 +351,17 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
        } else {
                *bgp = bgp_get_default();
                if (!*bgp) {
-                       if (use_json)
-                               vty_out(vty, "{}\n");
+                       if (use_json) {
+                               json_object *json = NULL;
+                               json = json_object_new_object();
+                               json_object_string_add(
+                                       json, "warning",
+                                       "Default BGP instance not found");
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(json,
+                                               JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       }
                        else
                                vty_out(vty,
                                        "Default BGP instance not found\n");
@@ -771,19 +790,23 @@ static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi,
 /* clear soft inbound */
 static void bgp_clear_star_soft_in(struct vty *vty, const char *name)
 {
-       bgp_clear_vty(vty, name, AFI_IP, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_IN, NULL);
-       bgp_clear_vty(vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_IN, NULL);
+       afi_t afi;
+       safi_t safi;
+
+       FOREACH_AFI_SAFI (afi, safi)
+               bgp_clear_vty(vty, name, afi, safi, clear_all,
+                             BGP_CLEAR_SOFT_IN, NULL);
 }
 
 /* clear soft outbound */
 static void bgp_clear_star_soft_out(struct vty *vty, const char *name)
 {
-       bgp_clear_vty(vty, name, AFI_IP, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_OUT, NULL);
-       bgp_clear_vty(vty, name, AFI_IP6, SAFI_UNICAST, clear_all,
-                     BGP_CLEAR_SOFT_OUT, NULL);
+       afi_t afi;
+       safi_t safi;
+
+       FOREACH_AFI_SAFI (afi, safi)
+               bgp_clear_vty(vty, name, afi, safi, clear_all,
+                             BGP_CLEAR_SOFT_OUT, NULL);
 }
 
 
@@ -2055,29 +2078,6 @@ DEFUN (no_bgp_graceful_restart_preserve_fw,
        return CMD_SUCCESS;
 }
 
-static void bgp_redistribute_redo(struct bgp *bgp)
-{
-       afi_t afi;
-       int i;
-       struct list *red_list;
-       struct listnode *node;
-       struct bgp_redist *red;
-
-       for (afi = AFI_IP; afi < AFI_MAX; afi++) {
-               for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
-
-                       red_list = bgp->redist[afi][i];
-                       if (!red_list)
-                               continue;
-
-                       for (ALL_LIST_ELEMENTS_RO(red_list, node, red)) {
-                               bgp_redistribute_resend(bgp, afi, i,
-                                                       red->instance);
-                       }
-               }
-       }
-}
-
 /* "bgp graceful-shutdown" configuration */
 DEFUN (bgp_graceful_shutdown,
        bgp_graceful_shutdown_cmd,
@@ -2648,7 +2648,7 @@ static struct peer_group *listen_range_exists(struct bgp *bgp,
 
 DEFUN (bgp_listen_range,
        bgp_listen_range_cmd,
-       "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD",
+       "bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
        "BGP specific commands\n"
        "Configure BGP dynamic neighbors listen range\n"
        "Configure BGP dynamic neighbors listen range\n"
@@ -2666,7 +2666,7 @@ DEFUN (bgp_listen_range,
        argv_find(argv, argc, "A.B.C.D/M", &idx);
        argv_find(argv, argc, "X:X::X:X/M", &idx);
        char *prefix = argv[idx]->arg;
-       argv_find(argv, argc, "WORD", &idx);
+       argv_find(argv, argc, "PGNAME", &idx);
        char *peergroup = argv[idx]->arg;
 
        /* Convert IP prefix string to struct prefix. */
@@ -2718,7 +2718,7 @@ DEFUN (bgp_listen_range,
 
 DEFUN (no_bgp_listen_range,
        no_bgp_listen_range_cmd,
-       "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group WORD",
+       "no bgp listen range <A.B.C.D/M|X:X::X:X/M> peer-group PGNAME",
        NO_STR
        "BGP specific commands\n"
        "Unconfigure BGP dynamic neighbors listen range\n"
@@ -2841,18 +2841,23 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
                as = strtoul(as_str, NULL, 10);
        }
 
-       /* If peer is peer group, call proper function.  */
+       /* If peer is peer group or interface peer, call proper function. */
        ret = str2sockunion(peer_str, &su);
        if (ret < 0) {
-               /* Check for peer by interface */
+               struct peer *peer;
+
+               /* Check if existing interface peer */
+               peer = peer_lookup_by_conf_if(bgp, peer_str);
+
                ret = peer_remote_as(bgp, NULL, peer_str, &as, as_type, afi,
                                     safi);
-               if (ret < 0) {
+
+               /* if not interface peer, check peer-group settings */
+               if (ret < 0 && !peer) {
                        ret = peer_group_remote_as(bgp, peer_str, &as, as_type);
                        if (ret < 0) {
                                vty_out(vty,
-                                       "%% Create the peer-group or interface first or specify \"interface\" keyword\n");
-                               vty_out(vty, "%% if using an unnumbered interface neighbor\n");
+                                       "%% Create the peer-group or interface first\n");
                                return CMD_WARNING_CONFIG_FAILED;
                        }
                        return CMD_SUCCESS;
@@ -3013,7 +3018,7 @@ static int peer_conf_interface_get(struct vty *vty, const char *conf_if,
 
 DEFUN (neighbor_interface_config,
        neighbor_interface_config_cmd,
-       "neighbor WORD interface [peer-group WORD]",
+       "neighbor WORD interface [peer-group PGNAME]",
        NEIGHBOR_STR
        "Interface name or neighbor tag\n"
        "Enable BGP on interface\n"
@@ -3034,7 +3039,7 @@ DEFUN (neighbor_interface_config,
 
 DEFUN (neighbor_interface_config_v6only,
        neighbor_interface_config_v6only_cmd,
-       "neighbor WORD interface v6only [peer-group WORD]",
+       "neighbor WORD interface v6only [peer-group PGNAME]",
        NEIGHBOR_STR
        "Interface name or neighbor tag\n"
        "Enable BGP on interface\n"
@@ -3179,7 +3184,7 @@ DEFUN (no_neighbor,
 
 DEFUN (no_neighbor_interface_config,
        no_neighbor_interface_config_cmd,
-       "no neighbor WORD interface [v6only] [peer-group WORD] [remote-as <(1-4294967295)|internal|external>]",
+       "no neighbor WORD interface [v6only] [peer-group PGNAME] [remote-as <(1-4294967295)|internal|external>]",
        NO_STR
        NEIGHBOR_STR
        "Interface name\n"
@@ -3251,7 +3256,7 @@ DEFUN (no_neighbor_interface_peer_group_remote_as,
        /* look up for neighbor by interface name config. */
        peer = peer_lookup_by_conf_if(bgp, argv[idx_word]->arg);
        if (peer) {
-               peer_as_change(peer, 0, AS_SPECIFIED);
+               peer_as_change(peer, 0, AS_UNSPECIFIED);
                return CMD_SUCCESS;
        }
 
@@ -3494,7 +3499,7 @@ ALIAS_HIDDEN(no_neighbor_activate, no_neighbor_activate_hidden_cmd,
 
 DEFUN (neighbor_set_peer_group,
        neighbor_set_peer_group_cmd,
-       "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
+       "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
        "Member of the peer-group\n"
@@ -3552,14 +3557,14 @@ DEFUN (neighbor_set_peer_group,
 }
 
 ALIAS_HIDDEN(neighbor_set_peer_group, neighbor_set_peer_group_hidden_cmd,
-            "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
+            "neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
             NEIGHBOR_STR NEIGHBOR_ADDR_STR2
             "Member of the peer-group\n"
             "Peer-group name\n")
 
 DEFUN (no_neighbor_set_peer_group,
        no_neighbor_set_peer_group_cmd,
-       "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
+       "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
        NO_STR
        NEIGHBOR_STR
        NEIGHBOR_ADDR_STR2
@@ -3589,7 +3594,7 @@ DEFUN (no_neighbor_set_peer_group,
 }
 
 ALIAS_HIDDEN(no_neighbor_set_peer_group, no_neighbor_set_peer_group_hidden_cmd,
-            "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group WORD",
+            "no neighbor <A.B.C.D|X:X::X:X|WORD> peer-group PGNAME",
             NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
             "Member of the peer-group\n"
             "Peer-group name\n")
@@ -3957,6 +3962,13 @@ ALIAS_HIDDEN(neighbor_nexthop_self_force,
             "Disable the next hop calculation for this neighbor\n"
             "Set the next hop to self for reflected routes\n")
 
+ALIAS_HIDDEN(neighbor_nexthop_self_force,
+            neighbor_nexthop_self_all_hidden_cmd,
+            "neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self all",
+            NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Disable the next hop calculation for this neighbor\n"
+            "Set the next hop to self for reflected routes\n")
+
 DEFUN (no_neighbor_nexthop_self,
        no_neighbor_nexthop_self_cmd,
        "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self",
@@ -3998,6 +4010,13 @@ ALIAS_HIDDEN(no_neighbor_nexthop_self_force,
             "Disable the next hop calculation for this neighbor\n"
             "Set the next hop to self for reflected routes\n")
 
+ALIAS_HIDDEN(no_neighbor_nexthop_self_force,
+            no_neighbor_nexthop_self_all_hidden_cmd,
+            "no neighbor <A.B.C.D|X:X::X:X|WORD> next-hop-self all",
+            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Disable the next hop calculation for this neighbor\n"
+            "Set the next hop to self for reflected routes\n")
+
 /* neighbor as-override */
 DEFUN (neighbor_as_override,
        neighbor_as_override_cmd,
@@ -4877,14 +4896,15 @@ static int peer_default_originate_set_vty(struct vty *vty, const char *peer_str,
 {
        int ret;
        struct peer *peer;
-       struct route_map *route_map;
+       struct route_map *route_map = NULL;
 
        peer = peer_and_group_lookup_vty(vty, peer_str);
        if (!peer)
                return CMD_WARNING_CONFIG_FAILED;
 
        if (set) {
-               route_map = route_map_lookup_warn_noexist(vty, rmap);
+               if (rmap)
+                       route_map = route_map_lookup_warn_noexist(vty, rmap);
                ret = peer_default_originate_set(peer, afi, safi,
                                                 rmap, route_map);
        } else
@@ -7163,7 +7183,7 @@ DEFUN_NOSH (address_family_vpnv6,
        vty->node = BGP_VPNV6_NODE;
        return CMD_SUCCESS;
 }
-#endif
+#endif /* KEEP_OLD_VPN_COMMANDS */
 
 DEFUN_NOSH (address_family_evpn,
        address_family_evpn_cmd,
@@ -7268,7 +7288,7 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
 /* one clear bgp command to rule them all */
 DEFUN (clear_ip_bgp_all,
        clear_ip_bgp_all_cmd,
-       "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> [<soft [<in|out>]|in [prefix-filter]|out>]",
+       "clear [ip] bgp [<view|vrf> VIEWVRFNAME] [<ipv4|ipv6|l2vpn> [<unicast|multicast|vpn|labeled-unicast|flowspec|evpn>]] <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group PGNAME> [<soft [<in|out>]|in [prefix-filter]|out>]",
        CLEAR_STR
        IP_STR
        BGP_STR
@@ -7321,7 +7341,7 @@ DEFUN (clear_ip_bgp_all,
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
 
-       /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group WORD> */
+       /* <*|A.B.C.D|X:X::X:X|WORD|(1-4294967295)|external|peer-group PGNAME> */
        if (argv_find(argv, argc, "*", &idx)) {
                clr_sort = clear_all;
        } else if (argv_find(argv, argc, "A.B.C.D", &idx)) {
@@ -7334,7 +7354,7 @@ DEFUN (clear_ip_bgp_all,
                clr_sort = clear_group;
                idx++;
                clr_arg = argv[idx]->arg;
-       } else if (argv_find(argv, argc, "WORD", &idx)) {
+       } else if (argv_find(argv, argc, "PGNAME", &idx)) {
                clr_sort = clear_peer;
                clr_arg = argv[idx]->arg;
        } else if (argv_find(argv, argc, "(1-4294967295)", &idx)) {
@@ -8031,7 +8051,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                        json, "ribMemory",
                                        ents * sizeof(struct bgp_node));
 
-                               ents = listcount(bgp->peer);
+                               ents = bgp->af_peer_count[afi][safi];
                                json_object_int_add(json, "peerCount", ents);
                                json_object_int_add(json, "peerMemory",
                                                    ents * sizeof(struct peer));
@@ -8071,7 +8091,7 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                                                   bgp_node)));
 
                                /* Peer related usage */
-                               ents = listcount(bgp->peer);
+                               ents = bgp->af_peer_count[afi][safi];
                                vty_out(vty, "Peers %ld, using %s of memory\n",
                                        ents,
                                        mtype_memstr(
@@ -8522,7 +8542,7 @@ const char *afi_safi_json(afi_t afi, safi_t safi)
 }
 
 /* Show BGP peer's information. */
-enum show_type { show_all, show_peer };
+enum show_type { show_all, show_peer, show_ipv4_all, show_ipv6_all, show_ipv4_peer, show_ipv6_peer };
 
 static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
                                      afi_t afi, safi_t safi,
@@ -10945,6 +10965,14 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
        struct peer *peer;
        int find = 0;
        bool nbr_output = false;
+       afi_t afi = AFI_MAX;
+       safi_t safi = SAFI_MAX;
+
+       if (type == show_ipv4_peer || type == show_ipv4_all) {
+               afi = AFI_IP;
+       } else if (type == show_ipv6_peer || type == show_ipv6_all) {
+               afi = AFI_IP6;
+       }
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
@@ -10973,17 +11001,54 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                                }
                        }
                        break;
+               case show_ipv4_peer:
+               case show_ipv6_peer:
+                       FOREACH_SAFI (safi) {
+                               if (peer->afc[afi][safi]) {
+                                       if (conf_if) {
+                                               if ((peer->conf_if
+                                                    && !strcmp(peer->conf_if, conf_if))
+                                                   || (peer->hostname
+                                                       && !strcmp(peer->hostname, conf_if))) {
+                                                       find = 1;
+                                                       bgp_show_peer(vty, peer, use_json,
+                                                                     json);
+                                                       break;
+                                               }
+                                       } else {
+                                               if (sockunion_same(&peer->su, su)) {
+                                                       find = 1;
+                                                       bgp_show_peer(vty, peer, use_json,
+                                                                     json);
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+                       break;
+               case show_ipv4_all:
+               case show_ipv6_all:
+                       FOREACH_SAFI (safi) {
+                               if (peer->afc[afi][safi]) {
+                                       bgp_show_peer(vty, peer, use_json, json);
+                                       nbr_output = true;
+                                       break;
+                               }
+                       }
+                       break;
                }
        }
 
-       if (type == show_peer && !find) {
+       if ((type == show_peer || type == show_ipv4_peer ||
+            type == show_ipv6_peer) && !find) {
                if (use_json)
                        json_object_boolean_true_add(json, "bgpNoSuchNeighbor");
                else
                        vty_out(vty, "%% No such neighbor in this view/vrf\n");
        }
 
-       if (type != show_peer && !nbr_output && !use_json)
+       if (type != show_peer && type != show_ipv4_peer &&
+           type != show_ipv6_peer && !nbr_output && !use_json)
                vty_out(vty, "%% No BGP neighbors found\n");
 
        if (use_json) {
@@ -11049,7 +11114,8 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                        : bgp->name);
                }
 
-               if (type == show_peer) {
+               if (type == show_peer || type == show_ipv4_peer ||
+                   type == show_ipv6_peer) {
                        ret = str2sockunion(ip_str, &su);
                        if (ret < 0)
                                bgp_show_neighbor(vty, bgp, type, NULL, ip_str,
@@ -11058,7 +11124,7 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                bgp_show_neighbor(vty, bgp, type, &su, NULL,
                                                  use_json, json);
                } else {
-                       bgp_show_neighbor(vty, bgp, show_all, NULL, NULL,
+                       bgp_show_neighbor(vty, bgp, type, NULL, NULL,
                                          use_json, json);
                }
                json_object_free(json);
@@ -11151,6 +11217,7 @@ DEFUN (show_ip_bgp_neighbors,
        char *vrf = NULL;
        char *sh_arg = NULL;
        enum show_type sh_type;
+       afi_t afi = AFI_MAX;
 
        bool uj = use_json(argc, argv);
 
@@ -11166,13 +11233,29 @@ DEFUN (show_ip_bgp_neighbors,
                vrf = argv[idx + 1]->arg;
 
        idx++;
+
+       if (argv_find(argv, argc, "ipv4", &idx)) {
+               sh_type = show_ipv4_all;
+               afi = AFI_IP;
+       } else if (argv_find(argv, argc, "ipv6", &idx)) {
+               sh_type = show_ipv6_all;
+               afi = AFI_IP6;
+       } else {
+               sh_type = show_all;
+       }
+
        if (argv_find(argv, argc, "A.B.C.D", &idx)
            || argv_find(argv, argc, "X:X::X:X", &idx)
            || argv_find(argv, argc, "WORD", &idx)) {
                sh_type = show_peer;
                sh_arg = argv[idx]->arg;
-       } else
-               sh_type = show_all;
+       }
+
+       if (sh_type == show_peer && afi == AFI_IP) {
+               sh_type = show_ipv4_peer;
+       } else if (sh_type == show_peer && afi == AFI_IP6) {
+               sh_type = show_ipv6_peer;
+       }
 
        return bgp_show_neighbor_vty(vty, vrf, sh_type, sh_arg, uj);
 }
@@ -11267,8 +11350,9 @@ DEFUN (show_ip_bgp_attr_info,
        return CMD_SUCCESS;
 }
 
-static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
-                                  safi_t safi, bool use_json)
+static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
+                                  afi_t afi, safi_t safi,
+                                  bool use_json, json_object *json)
 {
        struct bgp *bgp;
        struct listnode *node;
@@ -11277,13 +11361,10 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
        char *ecom_str;
        vpn_policy_direction_t dir;
 
-       if (use_json) {
-               json_object *json = NULL;
+       if (json) {
                json_object *json_import_vrfs = NULL;
                json_object *json_export_vrfs = NULL;
 
-               json = json_object_new_object();
-
                bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
 
                if (!bgp) {
@@ -11354,11 +11435,12 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
                        XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
                }
 
-               vty_out(vty, "%s\n",
-                       json_object_to_json_string_ext(json,
+               if (use_json) {
+                       vty_out(vty, "%s\n",
+                               json_object_to_json_string_ext(json,
                                                      JSON_C_TO_STRING_PRETTY));
-               json_object_free(json);
-
+                       json_object_free(json);
+               }
        } else {
                bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
 
@@ -11422,6 +11504,54 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
        return CMD_SUCCESS;
 }
 
+static int bgp_show_all_instance_route_leak_vty(struct vty *vty, afi_t afi,
+                                               safi_t safi, bool use_json)
+{
+       struct listnode *node, *nnode;
+       struct bgp *bgp;
+       char *vrf_name = NULL;
+       json_object *json = NULL;
+       json_object *json_vrf = NULL;
+       json_object *json_vrfs = NULL;
+
+       if (use_json) {
+               json = json_object_new_object();
+               json_vrfs = json_object_new_object();
+       }
+
+       for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+
+               if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT)
+                       vrf_name = bgp->name;
+
+               if (use_json) {
+                       json_vrf = json_object_new_object();
+               } else {
+                       vty_out(vty, "\nInstance %s:\n",
+                               (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                               ? VRF_DEFAULT_NAME : bgp->name);
+               }
+               bgp_show_route_leak_vty(vty, vrf_name, afi, safi, 0, json_vrf);
+               if (use_json) {
+                       if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                               json_object_object_add(json_vrfs,
+                                               VRF_DEFAULT_NAME, json_vrf);
+                       else
+                               json_object_object_add(json_vrfs, vrf_name,
+                                                      json_vrf);
+               }
+       }
+
+       if (use_json) {
+               json_object_object_add(json, "vrfs", json_vrfs);
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(json,
+                                               JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
+
+       return CMD_SUCCESS;
+}
+
 /* "show [ip] bgp route-leak" command.  */
 DEFUN (show_ip_bgp_route_leak,
        show_ip_bgp_route_leak_cmd,
@@ -11441,6 +11571,7 @@ DEFUN (show_ip_bgp_route_leak,
 
        bool uj = use_json(argc, argv);
        int idx = 0;
+       json_object *json = NULL;
 
        /* show [ip] bgp */
        if (argv_find(argv, argc, "ip", &idx)) {
@@ -11470,7 +11601,13 @@ DEFUN (show_ip_bgp_route_leak,
                return CMD_WARNING;
        }
 
-       return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj);
+       if (vrf && strmatch(vrf, "all"))
+               return bgp_show_all_instance_route_leak_vty(vty, afi, safi, uj);
+
+       if (uj)
+               json = json_object_new_object();
+
+       return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj, json);
 }
 
 static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
@@ -13131,22 +13268,48 @@ void bgp_vty_init(void)
        /* "neighbor next-hop-self force" commands. */
        install_element(BGP_NODE, &neighbor_nexthop_self_force_hidden_cmd);
        install_element(BGP_NODE, &no_neighbor_nexthop_self_force_hidden_cmd);
+       install_element(BGP_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_NODE, &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV4_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV4_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV4_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV4_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV4M_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV4M_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV4M_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV4M_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV4L_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV4L_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV4L_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV4L_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV6_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV6_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV6_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV6_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV6M_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV6M_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV6M_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV6M_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_IPV6L_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_IPV6L_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_IPV6L_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_IPV6L_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_VPNV4_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_VPNV4_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_VPNV4_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_VPNV4_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
        install_element(BGP_VPNV6_NODE, &neighbor_nexthop_self_force_cmd);
        install_element(BGP_VPNV6_NODE, &no_neighbor_nexthop_self_force_cmd);
+       install_element(BGP_VPNV6_NODE, &neighbor_nexthop_self_all_hidden_cmd);
+       install_element(BGP_VPNV6_NODE,
+                       &no_neighbor_nexthop_self_all_hidden_cmd);
 
        /* "neighbor as-override" commands. */
        install_element(BGP_NODE, &neighbor_as_override_hidden_cmd);
@@ -14456,8 +14619,7 @@ static int lcommunity_list_set_vty(struct vty *vty, int argc,
 
        /* Free temporary community list string allocated by
           argv_concat().  */
-       if (str)
-               XFREE(MTYPE_TMP, str);
+       XFREE(MTYPE_TMP, str);
 
        if (ret < 0) {
                community_list_perror(vty, ret);
@@ -14508,8 +14670,7 @@ static int lcommunity_list_unset_vty(struct vty *vty, int argc,
 
        /* Free temporary community list string allocated by
           argv_concat().  */
-       if (str)
-               XFREE(MTYPE_TMP, str);
+       XFREE(MTYPE_TMP, str);
 
        if (ret < 0) {
                community_list_perror(vty, ret);
@@ -14834,14 +14995,16 @@ static void lcommunity_list_show(struct vty *vty, struct community_list *list)
                if (entry == list->head) {
                        if (all_digit(list->name))
                                vty_out(vty, "Large community %s list %s\n",
-                                       entry->style == EXTCOMMUNITY_LIST_STANDARD
+                                       entry->style ==
+                                               LARGE_COMMUNITY_LIST_STANDARD
                                                ? "standard"
                                                : "(expanded) access",
                                        list->name);
                        else
                                vty_out(vty,
                                        "Named large community %s list %s\n",
-                                       entry->style == EXTCOMMUNITY_LIST_STANDARD
+                                       entry->style ==
+                                               LARGE_COMMUNITY_LIST_STANDARD
                                                ? "standard"
                                                : "expanded",
                                        list->name);