]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_vty.c
bgpd: Make `struct bgp_addr` a private data structure
[mirror_frr.git] / bgpd / bgp_vty.c
index 69e3de3b2a2eb123f1bcea8d515f17b2147a644f..58f23fd2f4338d16f1c12f07def034bfa32464d9 100644 (file)
@@ -45,6 +45,7 @@
 #include "bgpd/bgp_lcommunity.h"
 #include "bgpd/bgp_damp.h"
 #include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_nexthop.h"
 #include "bgpd/bgp_open.h"
@@ -300,7 +301,7 @@ int argv_find_and_parse_safi(struct cmd_token **argv, int argc, int *index,
 int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
                                        struct cmd_token **argv, int argc,
                                        int *idx, afi_t *afi, safi_t *safi,
-                                       struct bgp **bgp)
+                                       struct bgp **bgp, bool use_json)
 {
        char *vrf_name = NULL;
 
@@ -311,18 +312,24 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
        if (argv_find(argv, argc, "ip", idx))
                *afi = AFI_IP;
 
-       if (argv_find(argv, argc, "view", idx)
-           || argv_find(argv, argc, "vrf", idx)) {
+       if (argv_find(argv, argc, "view", idx))
                vrf_name = argv[*idx + 1]->arg;
-
+       else if (argv_find(argv, argc, "vrf", idx)) {
+               vrf_name = argv[*idx + 1]->arg;
+               if (strmatch(vrf_name, VRF_DEFAULT_NAME))
+                       vrf_name = NULL;
+       }
+       if (vrf_name) {
                if (strmatch(vrf_name, "all"))
                        *bgp = NULL;
                else {
                        *bgp = bgp_lookup_by_name(vrf_name);
                        if (!*bgp) {
-                               vty_out(vty,
-                                       "View/Vrf specified is unknown: %s\n",
-                                       vrf_name);
+                               if (use_json)
+                                       vty_out(vty, "{}\n");
+                               else
+                                       vty_out(vty, "View/Vrf %s is unknown\n",
+                                               vrf_name);
                                *idx = 0;
                                return 0;
                        }
@@ -330,7 +337,11 @@ int bgp_vty_find_and_parse_afi_safi_bgp(struct vty *vty,
        } else {
                *bgp = bgp_get_default();
                if (!*bgp) {
-                       vty_out(vty, "Unable to find default BGP instance\n");
+                       if (use_json)
+                               vty_out(vty, "{}\n");
+                       else
+                               vty_out(vty,
+                                       "Default BGP instance not found\n");
                        *idx = 0;
                        return 0;
                }
@@ -802,7 +813,7 @@ DEFUN_HIDDEN (no_bgp_multiple_instance,
 
        vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
        vty_out(vty, "if you are using this please let the developers know\n");
-       zlog_warn("Deprecated option: `bgp multiple-instance` being used");
+       zlog_info("Deprecated option: `bgp multiple-instance` being used");
        ret = bgp_option_unset(BGP_OPT_MULTIPLE_INSTANCE);
        if (ret < 0) {
                vty_out(vty, "%% There are more than two BGP instances\n");
@@ -827,7 +838,7 @@ DEFUN_HIDDEN (bgp_config_type,
        if (argv_find(argv, argc, "cisco", &idx)) {
                vty_out(vty, "This config option is deprecated, and is scheduled for removal.\n");
                vty_out(vty, "if you are using this please let the developers know!\n");
-               zlog_warn("Deprecated option: `bgp config-type cisco` being used");
+               zlog_info("Deprecated option: `bgp config-type cisco` being used");
                bgp_option_set(BGP_OPT_CONFIG_CISCO);
        } else
                bgp_option_unset(BGP_OPT_CONFIG_CISCO);
@@ -909,9 +920,12 @@ DEFUN_NOSH (router_bgp,
                if (argc > 3) {
                        name = argv[idx_vrf]->arg;
 
-                       if (!strcmp(argv[idx_view_vrf]->text, "vrf"))
-                               inst_type = BGP_INSTANCE_TYPE_VRF;
-                       else if (!strcmp(argv[idx_view_vrf]->text, "view"))
+                       if (!strcmp(argv[idx_view_vrf]->text, "vrf")) {
+                               if (strmatch(name, VRF_DEFAULT_NAME))
+                                       name = NULL;
+                               else
+                                       inst_type = BGP_INSTANCE_TYPE_VRF;
+                       } else if (!strcmp(argv[idx_view_vrf]->text, "view"))
                                inst_type = BGP_INSTANCE_TYPE_VIEW;
                }
 
@@ -2018,7 +2032,7 @@ DEFUN (no_bgp_fast_external_failover,
 }
 
 /* "bgp enforce-first-as" configuration. */
-#if CONFDATE > 20180517
+#if CONFDATE > 20190517
 CPP_NOTICE("bgpd: remove deprecated '[no] bgp enforce-first-as' commands")
 #endif
 
@@ -7143,13 +7157,17 @@ DEFUN (clear_ip_bgp_all,
        if (argv_find(argv, argc, "ip", &idx))
                afi = AFI_IP;
 
-       /* [<view|vrf> VIEWVRFNAME] */
-       if (argv_find(argv, argc, "view", &idx)
-           || argv_find(argv, argc, "vrf", &idx)) {
+       /* [<vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               idx += 2;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       } else if (argv_find(argv, argc, "view", &idx)) {
+               /* [<view> VIEWVRFNAME] */
                vrf = argv[idx + 1]->arg;
                idx += 2;
        }
-
        /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi))
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -7214,8 +7232,16 @@ DEFUN (clear_ip_bgp_prefix,
        int idx = 0;
 
        /* [<view|vrf> VIEWVRFNAME] */
-       if (argv_find(argv, argc, "VIEWVRFNAME", &idx))
-               vrf = argv[idx]->arg;
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               idx += 2;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       } else if (argv_find(argv, argc, "view", &idx)) {
+               /* [<view> VIEWVRFNAME] */
+               vrf = argv[idx + 1]->arg;
+               idx += 2;
+       }
 
        prefix = argv[argc - 1]->arg;
 
@@ -7257,16 +7283,23 @@ DEFUN (clear_bgp_instance_ipv6_safi_prefix,
        "Clear bestpath and re-advertise\n"
        "IPv6 prefix\n")
 {
-       int idx_word = 3;
        int idx_safi = 0;
+       int idx_vrfview = 0;
        int idx_ipv6_prefix = 0;
        safi_t safi = SAFI_UNICAST;
        char *prefix = argv_find(argv, argc, "X:X::X:X/M", &idx_ipv6_prefix) ?
                argv[idx_ipv6_prefix]->arg : NULL;
-       /* [<view|vrf> VIEWVRFNAME] */
-       char *vrfview = argv_find(argv, argc, "VIEWVRFNAME", &idx_word) ?
-               argv[idx_word]->arg : NULL;
+       char *vrfview = NULL;
 
+       /* [<view|vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx_vrfview)) {
+               vrfview = argv[idx_vrfview + 1]->arg;
+               if (vrfview && strmatch(vrfview, VRF_DEFAULT_NAME))
+                       vrfview = NULL;
+       } else if (argv_find(argv, argc, "view", &idx_vrfview)) {
+               /* [<view> VIEWVRFNAME] */
+               vrfview = argv[idx_vrfview + 1]->arg;
+       }
        argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
 
        return bgp_clear_prefix(
@@ -7316,7 +7349,7 @@ DEFUN (show_bgp_vrfs,
        struct list *inst = bm->bgp;
        struct listnode *node;
        struct bgp *bgp;
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
        json_object *json = NULL;
        json_object *json_vrfs = NULL;
        int count = 0;
@@ -7334,7 +7367,7 @@ DEFUN (show_bgp_vrfs,
        for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) {
                const char *name, *type;
                struct peer *peer;
-               struct listnode *node, *nnode;
+               struct listnode *node2, *nnode2;
                int peers_cfg, peers_estb;
                json_object *json_vrf = NULL;
 
@@ -7354,7 +7387,7 @@ DEFUN (show_bgp_vrfs,
                        json_vrf = json_object_new_object();
 
 
-               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+               for (ALL_LIST_ELEMENTS(bgp->peer, node2, nnode2, peer)) {
                        if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
                                continue;
                        peers_cfg++;
@@ -7418,14 +7451,6 @@ DEFUN (show_bgp_vrfs,
        return CMD_SUCCESS;
 }
 
-static void show_address_entry(struct hash_backet *backet, void *args)
-{
-       struct vty *vty = (struct vty *)args;
-       struct bgp_addr *addr = (struct bgp_addr *)backet->data;
-
-       vty_out(vty, "addr: %s, count: %d\n", inet_ntoa(addr->addr),
-               addr->refcnt);
-}
 
 static void show_tip_entry(struct hash_backet *backet, void *args)
 {
@@ -7439,9 +7464,7 @@ static void show_tip_entry(struct hash_backet *backet, void *args)
 static void bgp_show_martian_nexthops(struct vty *vty, struct bgp *bgp)
 {
        vty_out(vty, "self nexthop database:\n");
-       hash_iterate(bgp->address_hash,
-                    (void (*)(struct hash_backet *, void *))show_address_entry,
-                    vty);
+       bgp_nexthop_show_address_hash(vty, bgp);
 
        vty_out(vty, "Tunnel-ip database:\n");
        hash_iterate(bgp->tip_hash,
@@ -7457,10 +7480,18 @@ DEFUN(show_bgp_martian_nexthop_db, show_bgp_martian_nexthop_db_cmd,
 {
        struct bgp *bgp = NULL;
        int idx = 0;
-
-       if (argv_find(argv, argc, "view", &idx)
-           || argv_find(argv, argc, "vrf", &idx))
-               bgp = bgp_lookup_by_name(argv[idx + 1]->arg);
+       char *name = NULL;
+
+       /* [<vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               name = argv[idx + 1]->arg;
+               if (name && strmatch(name, VRF_DEFAULT_NAME))
+                       name = NULL;
+       } else if (argv_find(argv, argc, "view", &idx))
+               /* [<view> VIEWVRFNAME] */
+               name = argv[idx + 1]->arg;
+       if (name)
+               bgp = bgp_lookup_by_name(name);
        else
                bgp = bgp_get_default();
 
@@ -7637,7 +7668,7 @@ static void bgp_show_bestpath_json(struct bgp *bgp, json_object *json)
 
 /* Show BGP peer's summary information. */
 static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
-                           uint8_t use_json, json_object *json)
+                           bool use_json, json_object *json)
 {
        struct peer *peer;
        struct listnode *node, *nnode;
@@ -8054,14 +8085,14 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
 }
 
 static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
-                                     int safi, uint8_t use_json,
+                                     int safi, bool use_json,
                                      json_object *json)
 {
        int is_first = 1;
        int afi_wildcard = (afi == AFI_MAX);
        int safi_wildcard = (safi == SAFI_MAX);
        int is_wildcard = (afi_wildcard || safi_wildcard);
-       bool json_output = false;
+       bool nbr_output = false;
 
        if (use_json && is_wildcard)
                vty_out(vty, "{\n");
@@ -8072,7 +8103,7 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
                        safi = 1; /* SAFI_UNICAST */
                while (safi < SAFI_MAX) {
                        if (bgp_afi_safi_peer_exists(bgp, afi, safi)) {
-                               json_output = true;
+                               nbr_output = true;
                                if (is_wildcard) {
                                        /*
                                         * So limit output to those afi/safi
@@ -8111,22 +8142,28 @@ static void bgp_show_summary_afi_safi(struct vty *vty, struct bgp *bgp, int afi,
 
        if (use_json && is_wildcard)
                vty_out(vty, "}\n");
-       else if (use_json && !json_output)
-               vty_out(vty, "{}\n");
+       else if (!nbr_output) {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% No BGP neighbors found\n");
+       }
 }
 
 static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
-                                              safi_t safi, uint8_t use_json)
+                                              safi_t safi, bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        json_object *json = NULL;
        int is_first = 1;
+       bool nbr_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               nbr_output = true;
                if (use_json) {
                        json = json_object_new_object();
 
@@ -8150,10 +8187,12 @@ static void bgp_show_all_instances_summary_vty(struct vty *vty, afi_t afi,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!nbr_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
-                        safi_t safi, uint8_t use_json)
+                        safi_t safi, bool use_json)
 {
        struct bgp *bgp;
 
@@ -8170,7 +8209,7 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
                                        vty_out(vty, "{}\n");
                                else
                                        vty_out(vty,
-                                               "%% No such BGP instance exist\n");
+                                               "%% BGP instance not found\n");
                                return CMD_WARNING;
                        }
 
@@ -8184,6 +8223,13 @@ int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
 
        if (bgp)
                bgp_show_summary_afi_safi(vty, bgp, afi, safi, use_json, NULL);
+       else {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% BGP instance not found\n");
+               return CMD_WARNING;
+       }
 
        return CMD_SUCCESS;
 }
@@ -8210,16 +8256,20 @@ DEFUN (show_ip_bgp_summary,
        /* show [ip] bgp */
        if (argv_find(argv, argc, "ip", &idx))
                afi = AFI_IP;
-       /* [<view|vrf> VIEWVRFNAME] */
-       if (argv_find(argv, argc, "view", &idx)
-           || argv_find(argv, argc, "vrf", &idx))
-               vrf = argv[++idx]->arg;
+       /* [<vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       } else if (argv_find(argv, argc, "view", &idx))
+               /* [<view> VIEWVRFNAME] */
+               vrf = argv[idx + 1]->arg;
        /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
        }
 
-       int uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        return bgp_show_summary_vty(vty, vrf, afi, safi, uj);
 }
@@ -8301,7 +8351,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
                                      afi_t afi, safi_t safi,
                                      uint16_t adv_smcap, uint16_t adv_rmcap,
                                      uint16_t rcv_smcap, uint16_t rcv_rmcap,
-                                     uint8_t use_json, json_object *json_pref)
+                                     bool use_json, json_object *json_pref)
 {
        /* Send-Mode */
        if (CHECK_FLAG(p->af_cap[afi][safi], adv_smcap)
@@ -8361,7 +8411,7 @@ static void bgp_show_peer_afi_orf_cap(struct vty *vty, struct peer *p,
 }
 
 static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
-                             safi_t safi, uint8_t use_json,
+                             safi_t safi, bool use_json,
                              json_object *json_neigh)
 {
        struct bgp_filter *filter;
@@ -8936,7 +8986,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
        }
 }
 
-static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
+static void bgp_show_peer(struct vty *vty, struct peer *p, bool use_json,
                          json_object *json)
 {
        struct bgp *bgp;
@@ -10683,12 +10733,13 @@ static void bgp_show_peer(struct vty *vty, struct peer *p, uint8_t use_json,
 
 static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                             enum show_type type, union sockunion *su,
-                            const char *conf_if, uint8_t use_json,
+                            const char *conf_if, bool use_json,
                             json_object *json)
 {
        struct listnode *node, *nnode;
        struct peer *peer;
        int find = 0;
+       bool nbr_output = false;
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
                if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
@@ -10697,6 +10748,7 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                switch (type) {
                case show_all:
                        bgp_show_peer(vty, peer, use_json, json);
+                       nbr_output = true;
                        break;
                case show_peer:
                        if (conf_if) {
@@ -10726,6 +10778,9 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
                        vty_out(vty, "%% No such neighbor in this view/vrf\n");
        }
 
+       if (type != show_peer && !nbr_output && !use_json)
+               vty_out(vty, "%% No BGP neighbors found\n");
+
        if (use_json) {
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
                                             json, JSON_C_TO_STRING_PRETTY));
@@ -10740,21 +10795,24 @@ static int bgp_show_neighbor(struct vty *vty, struct bgp *bgp,
 static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
                                                 enum show_type type,
                                                 const char *ip_str,
-                                                uint8_t use_json)
+                                                bool use_json)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
        union sockunion su;
        json_object *json = NULL;
        int ret, is_first = 1;
+       bool nbr_output = false;
 
        if (use_json)
                vty_out(vty, "{\n");
 
        for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               nbr_output = true;
                if (use_json) {
                        if (!(json = json_object_new_object())) {
-                               zlog_err(
+                               flog_err(
+                                       EC_BGP_JSON_MEM_ERROR,
                                        "Unable to allocate memory for JSON object");
                                vty_out(vty,
                                        "{\"error\": {\"message:\": \"Unable to allocate memory for JSON object\"}}}\n");
@@ -10803,11 +10861,13 @@ static void bgp_show_all_instances_neighbors_vty(struct vty *vty,
 
        if (use_json)
                vty_out(vty, "}\n");
+       else if (!nbr_output)
+               vty_out(vty, "%% BGP instance not found\n");
 }
 
 static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                 enum show_type type, const char *ip_str,
-                                uint8_t use_json)
+                                bool use_json)
 {
        int ret;
        struct bgp *bgp;
@@ -10824,8 +10884,6 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                        if (!bgp) {
                                if (use_json) {
                                        json = json_object_new_object();
-                                       json_object_boolean_true_add(
-                                               json, "bgpNoSuchInstance");
                                        vty_out(vty, "%s\n",
                                                json_object_to_json_string_ext(
                                                        json,
@@ -10833,7 +10891,7 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                        json_object_free(json);
                                } else
                                        vty_out(vty,
-                                               "%% No such BGP instance exist\n");
+                                               "%% BGP instance not found\n");
 
                                return CMD_WARNING;
                        }
@@ -10857,6 +10915,11 @@ static int bgp_show_neighbor_vty(struct vty *vty, const char *name,
                                          json);
                }
                json_object_free(json);
+       } else {
+               if (use_json)
+                       vty_out(vty, "{}\n");
+               else
+                       vty_out(vty, "%% BGP instance not found\n");
        }
 
        return CMD_SUCCESS;
@@ -10882,12 +10945,17 @@ DEFUN (show_ip_bgp_neighbors,
        char *sh_arg = NULL;
        enum show_type sh_type;
 
-       uint8_t uj = use_json(argc, argv);
+       bool uj = use_json(argc, argv);
 
        int idx = 0;
 
-       if (argv_find(argv, argc, "view", &idx)
-           || argv_find(argv, argc, "vrf", &idx))
+       /* [<vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       } else if (argv_find(argv, argc, "view", &idx))
+               /* [<view> VIEWVRFNAME] */
                vrf = argv[idx + 1]->arg;
 
        idx++;
@@ -10992,8 +11060,8 @@ 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)
+static int bgp_show_route_leak_vty(struct vty *vty, const char *name, afi_t afi,
+                                  safi_t safi, bool use_json)
 {
        struct bgp *bgp;
        struct listnode *node;
@@ -11002,64 +11070,146 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
        char *ecom_str;
        vpn_policy_direction_t dir;
 
-       if (name) {
-               bgp = bgp_lookup_by_name(name);
+       if (use_json) {
+               json_object *json = NULL;
+               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) {
-                       vty_out(vty, "%% No such BGP instance exist\n");
+                       vty_out(vty, "%s\n",
+                               json_object_to_json_string_ext(
+                                       json,
+                                       JSON_C_TO_STRING_PRETTY));
+                       json_object_free(json);
+
                        return CMD_WARNING;
                }
+
+               /* Provide context for the block */
+               json_object_string_add(json, "vrf", name ? name : "default");
+               json_object_string_add(json, "afiSafi",
+                                      afi_safi_print(afi, safi));
+
+               if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+                               BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
+                       json_object_string_add(json, "importFromVrfs", "none");
+                       json_object_string_add(json, "importRts", "none");
+               } else {
+                       json_import_vrfs = json_object_new_array();
+
+                       for (ALL_LIST_ELEMENTS_RO(
+                                               bgp->vpn_policy[afi].import_vrf,
+                                               node, vname))
+                               json_object_array_add(json_import_vrfs,
+                                               json_object_new_string(vname));
+
+                       dir = BGP_VPN_POLICY_DIR_FROMVPN;
+                       ecom_str = ecommunity_ecom2str(
+                                       bgp->vpn_policy[afi].rtlist[dir],
+                                       ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                       json_object_object_add(json, "importFromVrfs",
+                                              json_import_vrfs);
+                       json_object_string_add(json, "importRts", ecom_str);
+
+                       XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+               }
+
+               if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+                               BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
+                       json_object_string_add(json, "exportToVrfs", "none");
+                       json_object_string_add(json, "routeDistinguisher",
+                                              "none");
+                       json_object_string_add(json, "exportRts", "none");
+               } else {
+                       json_export_vrfs = json_object_new_array();
+
+                       for (ALL_LIST_ELEMENTS_RO(
+                                               bgp->vpn_policy[afi].export_vrf,
+                                               node, vname))
+                               json_object_array_add(json_export_vrfs,
+                                               json_object_new_string(vname));
+                       json_object_object_add(json, "exportToVrfs",
+                                              json_export_vrfs);
+                       json_object_string_add(json, "routeDistinguisher",
+                                  prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
+                                                buf1, RD_ADDRSTRLEN));
+
+                       dir = BGP_VPN_POLICY_DIR_TOVPN;
+                       ecom_str = ecommunity_ecom2str(
+                                              bgp->vpn_policy[afi].rtlist[dir],
+                                              ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                       json_object_string_add(json, "exportRts", ecom_str);
+
+                       XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
+               }
+
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(json,
+                                                     JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+
        } else {
-               bgp = bgp_get_default();
+               bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
+
                if (!bgp) {
-                       vty_out(vty,
-                               "%% Default BGP instance does not exist\n");
+                       vty_out(vty, "%% No such BGP instance exist\n");
                        return CMD_WARNING;
                }
-       }
 
-       if (!CHECK_FLAG(bgp->af_flags[afi][safi],
-                       BGP_CONFIG_VRF_TO_VRF_IMPORT)) {
-               vty_out(vty,
-                       "This VRF is not importing %s routes from any other VRF\n",
-                       afi_safi_print(afi, safi));
-       } else {
-               vty_out(vty,
-                       "This VRF is importing %s routes from the following VRFs:\n",
-                       afi_safi_print(afi, safi));
-               for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
-                                         vname)) {
-                       vty_out(vty, "  %s\n", vname);
+               if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+                               BGP_CONFIG_VRF_TO_VRF_IMPORT))
+                       vty_out(vty,
+                    "This VRF is not importing %s routes from any other VRF\n",
+                     afi_safi_print(afi, safi));
+               else {
+                       vty_out(vty,
+                  "This VRF is importing %s routes from the following VRFs:\n",
+                   afi_safi_print(afi, safi));
+
+                       for (ALL_LIST_ELEMENTS_RO(
+                                               bgp->vpn_policy[afi].import_vrf,
+                                               node, vname))
+                               vty_out(vty, "  %s\n", vname);
+
+                       dir = BGP_VPN_POLICY_DIR_FROMVPN;
+                       ecom_str = ecommunity_ecom2str(
+                                              bgp->vpn_policy[afi].rtlist[dir],
+                                              ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                       vty_out(vty, "Import RT(s): %s\n", ecom_str);
+
+                       XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
                }
-               dir = BGP_VPN_POLICY_DIR_FROMVPN;
-               ecom_str = ecommunity_ecom2str(
-                               bgp->vpn_policy[afi].rtlist[dir],
-                               ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
-               vty_out(vty, "Import RT(s): %s\n", ecom_str);
-               XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
-       }
 
-       if (!CHECK_FLAG(bgp->af_flags[afi][safi],
-                       BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
-               vty_out(vty,
-                       "This VRF is not exporting %s routes to any other VRF\n",
+               if (!CHECK_FLAG(bgp->af_flags[afi][safi],
+                               BGP_CONFIG_VRF_TO_VRF_EXPORT))
+                       vty_out(vty,
+                      "This VRF is not exporting %s routes to any other VRF\n",
                        afi_safi_print(afi, safi));
-       } else {
-               vty_out(vty,
-                       "This VRF is exporting %s routes to the following VRFs:\n",
+               else {
+                       vty_out(vty,
+                      "This VRF is exporting %s routes to the following VRFs:\n",
                        afi_safi_print(afi, safi));
-               for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].export_vrf, node,
-                                         vname)) {
-                       vty_out(vty, "  %s\n", vname);
+
+                       for (ALL_LIST_ELEMENTS_RO(
+                                               bgp->vpn_policy[afi].export_vrf,
+                                               node, vname))
+                               vty_out(vty, "  %s\n", vname);
+
+                       vty_out(vty, "RD: %s\n",
+                               prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
+                                             buf1, RD_ADDRSTRLEN));
+
+                       dir = BGP_VPN_POLICY_DIR_TOVPN;
+                       ecom_str = ecommunity_ecom2str(
+                                       bgp->vpn_policy[afi].rtlist[dir],
+                                       ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+                       vty_out(vty, "Export RT: %s\n", ecom_str);
+                       XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
                }
-               vty_out(vty, "RD: %s\n",
-                       prefix_rd2str(&bgp->vpn_policy[afi].tovpn_rd,
-                                     buf1, RD_ADDRSTRLEN));
-               dir = BGP_VPN_POLICY_DIR_TOVPN;
-               ecom_str = ecommunity_ecom2str(
-                               bgp->vpn_policy[afi].rtlist[dir],
-                               ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
-               vty_out(vty, "Emport RT: %s\n", ecom_str);
-               XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
        }
 
        return CMD_SUCCESS;
@@ -11067,20 +11217,22 @@ static int bgp_show_route_leak_vty(struct vty *vty, const char *name,
 
 /* "show [ip] bgp route-leak" command.  */
 DEFUN (show_ip_bgp_route_leak,
-       show_ip_bgp_route_leak_cmd,
-       "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] route-leak",
-       SHOW_STR
-       IP_STR
-       BGP_STR
-       BGP_INSTANCE_HELP_STR
-       BGP_AFI_HELP_STR
-       BGP_SAFI_HELP_STR
-       "Route leaking information\n")
+       show_ip_bgp_route_leak_cmd,
+       "show [ip] bgp [<view|vrf> VIEWVRFNAME] ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] route-leak  [json]",
+       SHOW_STR
+       IP_STR
+       BGP_STR
+       BGP_INSTANCE_HELP_STR
+       BGP_AFI_HELP_STR
+       BGP_SAFI_HELP_STR
+       "Route leaking information\n"
+       JSON_STR)
 {
        char *vrf = NULL;
        afi_t afi = AFI_MAX;
        safi_t safi = SAFI_MAX;
 
+       bool uj = use_json(argc, argv);
        int idx = 0;
 
        /* show [ip] bgp */
@@ -11095,8 +11247,11 @@ DEFUN (show_ip_bgp_route_leak,
                return CMD_WARNING;
        }
 
-       if (argv_find(argv, argc, "vrf", &idx))
-               vrf = argv[++idx]->arg;
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       }
        /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -11108,7 +11263,7 @@ DEFUN (show_ip_bgp_route_leak,
                return CMD_WARNING;
        }
 
-       return bgp_show_route_leak_vty(vty, vrf, afi, safi);
+       return bgp_show_route_leak_vty(vty, vrf, afi, safi, uj);
 }
 
 static void bgp_show_all_instances_updgrps_vty(struct vty *vty, afi_t afi,
@@ -11169,10 +11324,14 @@ DEFUN (show_ip_bgp_updgrps,
        /* show [ip] bgp */
        if (argv_find(argv, argc, "ip", &idx))
                afi = AFI_IP;
-       /* [<view|vrf> VIEWVRFNAME] */
-       if (argv_find(argv, argc, "view", &idx)
-           || argv_find(argv, argc, "vrf", &idx))
-               vrf = argv[++idx]->arg;
+       /* [<vrf> VIEWVRFNAME] */
+       if (argv_find(argv, argc, "vrf", &idx)) {
+               vrf = argv[idx + 1]->arg;
+               if (vrf && strmatch(vrf, VRF_DEFAULT_NAME))
+                       vrf = NULL;
+       } else if (argv_find(argv, argc, "view", &idx))
+               /* [<view> VIEWVRFNAME] */
+               vrf = argv[idx + 1]->arg;
        /* ["BGP_AFI_CMD_STR" ["BGP_SAFI_CMD_STR"]] */
        if (argv_find_and_parse_afi(argv, argc, &idx, &afi)) {
                argv_find_and_parse_safi(argv, argc, &idx, &safi);
@@ -11398,7 +11557,7 @@ static int bgp_show_peer_group_vty(struct vty *vty, const char *name,
        bgp = name ? bgp_lookup_by_name(name) : bgp_get_default();
 
        if (!bgp) {
-               vty_out(vty, "%% No such BGP instance exists\n");
+               vty_out(vty, "%% BGP instance not found\n");
                return CMD_WARNING;
        }