]> git.puffer.fish Git - mirror/frr.git/commitdiff
ldpd: add more filtering options in some "show" commands 1267/head
authorRenato Westphal <renato@opensourcerouting.org>
Thu, 28 Sep 2017 22:42:46 +0000 (19:42 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Fri, 29 Sep 2017 00:51:05 +0000 (21:51 -0300)
Being able to filter the output of some "show" commands is super useful
when troubleshooting large MPLS networks.

Examples:

% show mpls ldp ipv4 binding 10.0.0.48/29 longer-prefixes neighbor 192.168.0.5
AF   Destination          Nexthop         Local Label Remote Label  In Use
ipv4 10.0.0.48/30         192.168.0.5     24          26                no
ipv4 10.0.0.52/30         192.168.0.5     25          27                no

% show mpls ldp ipv4 binding 10.0.0.48/29 longer-prefixes neighbor 192.168.0.5 detail json
{
  "10.0.0.48\/30":{
    "localLabel":"24",
    "advertisedTo":[
      {
        "neighborId":"192.168.0.5"
      }
    ],
    "remoteLabels":[
      {
        "neighborId":"192.168.0.5",
        "label":"26",
        "inUse":0
      }
    ]
  },
  "10.0.0.52\/30":{
    "localLabel":"25",
    "advertisedTo":[
      {
        "neighborId":"192.168.0.5"
      }
    ],
    "remoteLabels":[
      {
        "neighborId":"192.168.0.5",
        "label":"27",
        "inUse":0
      }
    ]
  }
}

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ldpd/ldp_vty.h
ldpd/ldp_vty_cmds.c
ldpd/ldp_vty_exec.c

index 3d2072f1e51c8098c712ac98a6c347c91dfaa5ee..d73bafe158e18131ac6f1839c18d9e96c0552544 100644 (file)
@@ -69,13 +69,16 @@ int  ldp_vty_l2vpn_pw_pwid(struct vty *, const char *, long);
 int     ldp_vty_l2vpn_pw_pwstatus(struct vty *, const char *);
 int     ldp_vty_clear_nbr(struct vty *, const char *);
 int     ldp_vty_debug(struct vty *, const char *, const char *, const char *, const char *);
-int     ldp_vty_show_binding(struct vty *, const char *, const char *, const char *);
+int     ldp_vty_show_binding(struct vty *, const char *, const char *, int,
+           const char *, unsigned long, unsigned long, const char *, const char *);
 int     ldp_vty_show_discovery(struct vty *, const char *, const char *, const char *);
 int     ldp_vty_show_interface(struct vty *, const char *, const char *);
 int     ldp_vty_show_capabilities(struct vty *, const char *);
-int     ldp_vty_show_neighbor(struct vty *, int, const char *, const char *);
-int     ldp_vty_show_atom_binding(struct vty *, const char *);
-int     ldp_vty_show_atom_vc(struct vty *, const char *);
+int     ldp_vty_show_neighbor(struct vty *, const char *, int, const char *, const char *);
+int     ldp_vty_show_atom_binding(struct vty *, const char *, unsigned long,
+           unsigned long, const char *);
+int     ldp_vty_show_atom_vc(struct vty *, const char *, const char *,
+           const char *, const char *);
 int     ldp_vty_show_debugging(struct vty *);
 
 void    ldp_vty_init(void);
index cd92958d4c8fa2bd38ebbee71b56b60d4db5caa8..3d8b4306c01bdb0e89dc27404df8155b4111c745 100644 (file)
@@ -581,17 +581,38 @@ DEFPY  (ldp_debug_mpls_ldp_messages_sent,
 
 DEFPY  (ldp_show_mpls_ldp_binding,
        ldp_show_mpls_ldp_binding_cmd,
-       "show mpls ldp [<ipv4|ipv6>]$af binding [detail]$detail [json]$json",
+       "show mpls ldp [<ipv4|ipv6>]$af binding\
+         [<A.B.C.D/M|X:X::X:X/M>$prefix [longer-prefixes$longer_prefixes]]\
+         [{\
+           neighbor A.B.C.D$nbr\
+           |local-label (0-1048575)$local_label\
+           |remote-label (0-1048575)$remote_label\
+         }]\
+        [detail]$detail [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "IPv4 Address Family\n"
        "IPv6 Address Family\n"
        "Label Information Base (LIB) information\n"
+       "Destination prefix (IPv4)\n"
+       "Destination prefix (IPv6)\n"
+       "Include longer matches\n"
+       "Display labels from LDP neighbor\n"
+       "Neighbor LSR-ID\n"
+       "Match locally assigned label values\n"
+       "Locally assigned label value\n"
+       "Match remotely assigned label values\n"
+       "Remotely assigned label value\n"
        "Show detailed information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_binding(vty, af, detail, json));
+       if (!local_label_str)
+               local_label = NO_LABEL;
+       if (!remote_label_str)
+               remote_label = NO_LABEL;
+       return (ldp_vty_show_binding(vty, af, prefix_str, !!longer_prefixes,
+           nbr_str, local_label, remote_label, detail, json));
 }
 
 DEFPY  (ldp_show_mpls_ldp_discovery,
@@ -637,52 +658,81 @@ DEFPY  (ldp_show_mpls_ldp_capabilities,
 
 DEFPY  (ldp_show_mpls_ldp_neighbor,
        ldp_show_mpls_ldp_neighbor_cmd,
-       "show mpls ldp neighbor [detail]$detail [json]$json",
+       "show mpls ldp neighbor [A.B.C.D]$lsr_id [detail]$detail [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "Neighbor information\n"
+       "Neighbor LSR-ID\n"
        "Show detailed information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_neighbor(vty, 0, detail, json));
+       return (ldp_vty_show_neighbor(vty, lsr_id_str, 0, detail, json));
 }
 
 DEFPY  (ldp_show_mpls_ldp_neighbor_capabilities,
        ldp_show_mpls_ldp_neighbor_capabilities_cmd,
-       "show mpls ldp neighbor capabilities [json]$json",
+       "show mpls ldp neighbor [A.B.C.D]$lsr_id capabilities [json]$json",
        "Show running system information\n"
        "MPLS information\n"
        "Label Distribution Protocol\n"
        "Neighbor information\n"
+       "Neighbor LSR-ID\n"
        "Display neighbor capability information\n"
        JSON_STR)
 {
-       return (ldp_vty_show_neighbor(vty, 1, NULL, json));
+       return (ldp_vty_show_neighbor(vty, lsr_id_str, 1, NULL, json));
 }
 
 DEFPY  (ldp_show_l2vpn_atom_binding,
        ldp_show_l2vpn_atom_binding_cmd,
-       "show l2vpn atom binding [json]$json",
+       "show l2vpn atom binding\
+         [{\
+           A.B.C.D$peer\
+           |local-label (16-1048575)$local_label\
+           |remote-label (16-1048575)$remote_label\
+         }]\
+        [json]$json",
        "Show running system information\n"
        "Show information about Layer2 VPN\n"
        "Show Any Transport over MPLS information\n"
        "Show AToM label binding information\n"
+       "Destination address of the VC\n"
+       "Match locally assigned label values\n"
+       "Locally assigned label value\n"
+       "Match remotely assigned label values\n"
+       "Remotely assigned label value\n"
        JSON_STR)
 {
-       return (ldp_vty_show_atom_binding(vty, json));
+       if (!local_label_str)
+               local_label = NO_LABEL;
+       if (!remote_label_str)
+               remote_label = NO_LABEL;
+       return (ldp_vty_show_atom_binding(vty, peer_str, local_label,
+           remote_label, json));
 }
 
 DEFPY  (ldp_show_l2vpn_atom_vc,
        ldp_show_l2vpn_atom_vc_cmd,
-       "show l2vpn atom vc [json]$json",
+       "show l2vpn atom vc\
+         [{\
+           A.B.C.D$peer\
+           |interface IFNAME$ifname\
+           |vc-id (1-4294967295)$vcid\
+         }]\
+        [json]$json",
        "Show running system information\n"
        "Show information about Layer2 VPN\n"
        "Show Any Transport over MPLS information\n"
        "Show AToM virtual circuit information\n"
+       "Destination address of the VC\n"
+       "Local interface of the pseudowire\n"
+       "Interface's name\n"
+       "VC ID\n"
+       "VC ID\n"
        JSON_STR)
 {
-       return (ldp_vty_show_atom_vc(vty, json));
+       return (ldp_vty_show_atom_vc(vty, peer_str, ifname, vcid_str, json));
 }
 
 DEFUN_NOSH (ldp_show_debugging_mpls_ldp,
index ad5e79c721be0e39bdd16502bfd9e037669f320c..459947c0421bb3d544700c4d08594804a998a0fb 100644 (file)
@@ -44,9 +44,28 @@ struct show_params {
        int             family;
        union ldpd_addr addr;
        uint8_t         prefixlen;
-       int             capabilities;
        int             detail;
        int             json;
+       union {
+               struct {
+                       struct in_addr lsr_id;
+                       int capabilities;
+               } neighbor;
+               struct {
+                       struct prefix prefix;
+                       int longer_prefixes;
+                       struct in_addr neighbor;
+                       uint32_t local_label;
+                       uint32_t remote_label;
+               } lib;
+               struct {
+                       struct in_addr peer;
+                       uint32_t local_label;
+                       uint32_t remote_label;
+                       char ifname[IFNAMSIZ];
+                       uint32_t vcid;
+               } l2vpn;
+       };
 };
 
 #define LDPBUFSIZ      65535
@@ -1005,6 +1024,12 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
+               rt = imsg->data;
+
+               if (params->lib.remote_label != NO_LABEL &&
+                   params->lib.remote_label != rt->remote_label)
+                       return (0);
+               /* FALLTHROUGH */
        case IMSG_CTL_SHOW_LIB_RCVD:
                rt = imsg->data;
 
@@ -1012,9 +1037,6 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
                    !rt->no_downstream)
                        break;
 
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       break;
-
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
 
@@ -1039,7 +1061,7 @@ static int
 show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
 {
        struct ctl_rt   *rt = NULL;
-       char             dstnet[BUFSIZ];
+       static char      dstnet[BUFSIZ];
        static int       upstream, downstream;
        size_t           buflen;
        static char      sent_buffer[LDPBUFSIZ];
@@ -1047,38 +1069,25 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
-       case IMSG_CTL_SHOW_LIB_SENT:
-       case IMSG_CTL_SHOW_LIB_RCVD:
-       case IMSG_CTL_SHOW_LIB_END:
                rt = imsg->data;
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       return (0);
-               break;
-       default:
-               break;
-       }
 
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_LIB_BEGIN:
                upstream = 0;
                downstream = 0;
                sent_buffer[0] = '\0';
                rcvd_buffer[0] = '\0';
-
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
-
-               vty_out (vty, "%s\n", dstnet);
-               vty_out (vty, "%-8sLocal binding: label: %s\n", "",
-                   log_label(rt->local_label));
                break;
        case IMSG_CTL_SHOW_LIB_SENT:
+               rt = imsg->data;
+
                upstream = 1;
                buflen = strlen(sent_buffer);
                snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
                    "%12s%s:0\n", "", inet_ntoa(rt->nexthop));
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
+               rt = imsg->data;
                downstream = 1;
                buflen = strlen(rcvd_buffer);
                snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
@@ -1087,6 +1096,14 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
                    rt->in_use ? " (in use)" : "");
                break;
        case IMSG_CTL_SHOW_LIB_END:
+               rt = imsg->data;
+
+               if (params->lib.remote_label != NO_LABEL &&
+                   !downstream)
+                       break;
+               vty_out(vty, "%s\n", dstnet);
+               vty_out(vty, "%-8sLocal binding: label: %s\n", "",
+                   log_label(rt->local_label));
                if (upstream) {
                        vty_out (vty, "%-8sAdvertised to:\n", "");
                        vty_out(vty, "%s", sent_buffer);
@@ -1170,19 +1187,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
-       case IMSG_CTL_SHOW_LIB_SENT:
-       case IMSG_CTL_SHOW_LIB_RCVD:
-       case IMSG_CTL_SHOW_LIB_END:
                rt = imsg->data;
-               if (params->family != AF_UNSPEC && params->family != rt->af)
-                       return (0);
-               break;
-       default:
-               break;
-       }
 
-       switch (imsg->hdr.type) {
-       case IMSG_CTL_SHOW_LIB_BEGIN:
                snprintf(dstnet, sizeof(dstnet), "%s/%d",
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
 
@@ -1201,12 +1207,16 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
                json_object_object_add(json, dstnet, json_lib_entry);
                break;
        case IMSG_CTL_SHOW_LIB_SENT:
+               rt = imsg->data;
+
                json_adv_label = json_object_new_object();
                json_object_string_add(json_adv_label, "neighborId",
                    inet_ntoa(rt->nexthop));
                json_object_array_add(json_adv_labels, json_adv_label);
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
+               rt = imsg->data;
+
                json_remote_label = json_object_new_object();
                json_object_string_add(json_remote_label, "neighborId",
                    inet_ntoa(rt->nexthop));
@@ -1410,88 +1420,272 @@ ldp_vty_connect(struct imsgbuf *ibuf)
 }
 
 static int
-ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg,
     struct show_params *params, json_object *json)
 {
        int      ret;
 
-       switch (cmd) {
-       case SHOW_IFACE:
+       if (params->json)
+               ret = show_interface_msg_json(imsg, params, json);
+       else
+               ret = show_interface_msg(vty, imsg, params);
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       int      ret;
+
+       if (params->detail) {
                if (params->json)
-                       ret = show_interface_msg_json(imsg, params, json);
+                       ret = show_discovery_detail_msg_json(imsg, params,
+                           json);
                else
-                       ret = show_interface_msg(vty, imsg, params);
-               break;
-       case SHOW_DISC:
-               if (params->detail) {
-                       if (params->json)
-                               ret = show_discovery_detail_msg_json(imsg,
-                                   params, json);
-                       else
-                               ret = show_discovery_detail_msg(vty, imsg,
-                                   params);
-               } else {
-                       if (params->json)
-                               ret = show_discovery_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_discovery_msg(vty, imsg, params);
+                       ret = show_discovery_detail_msg(vty, imsg, params);
+       } else {
+               if (params->json)
+                       ret = show_discovery_msg_json(imsg, params, json);
+               else
+                       ret = show_discovery_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       static bool      filtered = false;
+       struct ctl_nbr  *nbr;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_NBR:
+               filtered = false;
+               nbr = imsg->data;
+
+               if (params->neighbor.lsr_id.s_addr != INADDR_ANY &&
+                   params->neighbor.lsr_id.s_addr != nbr->id.s_addr) {
+                       filtered = true;
+                       return (0);
                }
                break;
-       case SHOW_NBR:
-               if (params->capabilities) {
-                       if (params->json)
-                               ret = show_nbr_capabilities_msg_json(imsg,
-                                   params, json);
-                       else
-                               ret = show_nbr_capabilities_msg(vty, imsg,
-                                   params);
-               } else if (params->detail) {
-                       if (params->json)
-                               ret = show_nbr_detail_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_nbr_detail_msg(vty, imsg, params);
-               } else {
-                       if (params->json)
-                               ret = show_nbr_msg_json(imsg, params, json);
-                       else
-                               ret = show_nbr_msg(vty, imsg, params);
-               }
+       case IMSG_CTL_SHOW_NBR_DISC:
+       case IMSG_CTL_SHOW_NBR_END:
+               if (filtered)
+                       return (0);
                break;
-       case SHOW_LIB:
-               if (params->detail) {
-                       if (params->json)
-                               ret = show_lib_detail_msg_json(imsg, params,
-                                   json);
-                       else
-                               ret = show_lib_detail_msg(vty, imsg, params);
-               } else {
-                       if (params->json)
-                               ret = show_lib_msg_json(imsg, params, json);
-                       else
-                               ret = show_lib_msg(vty, imsg, params);
-               }
+       default:
                break;
-       case SHOW_L2VPN_PW:
+       }
+
+       if (params->neighbor.capabilities) {
+               if (params->json)
+                       ret = show_nbr_capabilities_msg_json(imsg, params,
+                           json);
+               else
+                       ret = show_nbr_capabilities_msg(vty, imsg, params);
+       } else if (params->detail) {
+               if (params->json)
+                       ret = show_nbr_detail_msg_json(imsg, params, json);
+               else
+                       ret = show_nbr_detail_msg(vty, imsg, params);
+       } else {
                if (params->json)
-                       ret = show_l2vpn_pw_msg_json(imsg, params, json);
+                       ret = show_nbr_msg_json(imsg, params, json);
                else
-                       ret = show_l2vpn_pw_msg(vty, imsg, params);
+                       ret = show_nbr_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       static bool      filtered = false;
+       struct ctl_rt   *rt;
+       struct prefix    prefix;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_BEGIN:
+               filtered = false;
                break;
-       case SHOW_L2VPN_BINDING:
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+       case IMSG_CTL_SHOW_LIB_END:
+               if (filtered)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_BEGIN:
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+       case IMSG_CTL_SHOW_LIB_END:
+               rt = imsg->data;
+
+               if (params->family != AF_UNSPEC && params->family != rt->af) {
+                       filtered = true;
+                       return (0);
+               }
+
+               prefix.family = rt->af;
+               prefix.prefixlen = rt->prefixlen;
+               memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val));
+               if (params->lib.prefix.family != AF_UNSPEC) {
+                       if (!params->lib.longer_prefixes &&
+                           !prefix_same(&params->lib.prefix, &prefix)) {
+                               filtered = true;
+                               return (0);
+                       } else if (params->lib.longer_prefixes &&
+                           !prefix_match(&params->lib.prefix, &prefix)) {
+                               filtered = true;
+                               return (0);
+                       }
+               }
+
+               if (params->lib.local_label != NO_LABEL &&
+                   params->lib.local_label != rt->local_label) {
+                       filtered = true;
+                       return (0);
+               }
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_SENT:
+       case IMSG_CTL_SHOW_LIB_RCVD:
+               if (params->lib.neighbor.s_addr != INADDR_ANY &&
+                   params->lib.neighbor.s_addr != rt->nexthop.s_addr)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_LIB_RCVD:
+               if (params->lib.remote_label != NO_LABEL &&
+                   params->lib.remote_label != rt->remote_label)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       if (params->detail) {
                if (params->json)
-                       ret = show_l2vpn_binding_msg_json(imsg, params, json);
+                       ret = show_lib_detail_msg_json(imsg, params, json);
                else
-                       ret = show_l2vpn_binding_msg(vty, imsg, params);
+                       ret = show_lib_detail_msg(vty, imsg, params);
+       } else {
+               if (params->json)
+                       ret = show_lib_msg_json(imsg, params, json);
+               else
+                       ret = show_lib_msg(vty, imsg, params);
+       }
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       struct ctl_pw   *pw;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_L2VPN_PW:
+               pw = imsg->data;
+               if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+                   params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+                       return (0);
+               if (params->l2vpn.ifname[0] != '\0' &&
+                   strcmp(params->l2vpn.ifname, pw->ifname))
+                       return (0);
+               if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid)
+                       return (0);
                break;
        default:
-               return (0);
+               break;
        }
 
+       if (params->json)
+               ret = show_l2vpn_pw_msg_json(imsg, params, json);
+       else
+               ret = show_l2vpn_pw_msg(vty, imsg, params);
+
+       return (ret);
+}
+
+static int
+ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg,
+    struct show_params *params, json_object *json)
+{
+       struct ctl_pw   *pw;
+       int              ret;
+
+       switch (imsg->hdr.type) {
+       case IMSG_CTL_SHOW_L2VPN_BINDING:
+               pw = imsg->data;
+               if (params->l2vpn.peer.s_addr != INADDR_ANY &&
+                   params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
+                       return (0);
+               if (params->l2vpn.local_label != NO_LABEL &&
+                   params->l2vpn.local_label != pw->local_label)
+                       return (0);
+               if (params->l2vpn.remote_label != NO_LABEL &&
+                   params->l2vpn.remote_label != pw->remote_label)
+                       return (0);
+               break;
+       default:
+               break;
+       }
+
+       if (params->json)
+               ret = show_l2vpn_binding_msg_json(imsg, params, json);
+       else
+               ret = show_l2vpn_binding_msg(vty, imsg, params);
+
        return (ret);
 }
 
+static int
+ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
+    struct show_params *params, json_object *json)
+{
+       switch (cmd) {
+       case SHOW_IFACE:
+               return (ldp_vty_dispatch_iface(vty, imsg, params, json));
+       case SHOW_DISC:
+               return (ldp_vty_dispatch_disc(vty, imsg, params, json));
+       case SHOW_NBR:
+               return (ldp_vty_dispatch_nbr(vty, imsg, params, json));
+       case SHOW_LIB:
+               return (ldp_vty_dispatch_lib(vty, imsg, params, json));
+       case SHOW_L2VPN_PW:
+               return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json));
+       case SHOW_L2VPN_BINDING:
+               return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params,
+                   json));
+       default:
+               return (0);
+       }
+}
+
 static int
 ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
     struct show_params *params)
@@ -1565,7 +1759,9 @@ ldp_vty_get_af(const char *str, int *af)
 }
 
 int
-ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, const char *json)
+ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix,
+    int longer_prefixes, const char *neighbor, unsigned long local_label,
+    unsigned long remote_label, const char *detail, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1581,6 +1777,18 @@ ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *detail, co
        params.family = af;
        params.detail = (detail) ? 1 : 0;
        params.json = (json) ? 1 : 0;
+       if (prefix) {
+               (void)str2prefix(prefix, &params.lib.prefix);
+               params.lib.longer_prefixes = longer_prefixes;
+       }
+       if (neighbor &&
+           (inet_pton(AF_INET, neighbor, &params.lib.neighbor) != 1 ||
+            bad_addr_v4(params.lib.neighbor))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       params.lib.local_label = local_label;
+       params.lib.remote_label = remote_label;
 
        if (!params.detail && !params.json)
                vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
@@ -1703,7 +1911,8 @@ ldp_vty_show_capabilities(struct vty *vty, const char *json)
 }
 
 int
-ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, const char *json)
+ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities,
+    const char *detail, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1712,11 +1921,17 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
                return (CMD_WARNING);
 
        memset(&params, 0, sizeof(params));
-       params.capabilities = capabilities;
        params.detail = (detail) ? 1 : 0;
        params.json = (json) ? 1 : 0;
+       params.neighbor.capabilities = capabilities;
+       if (lsr_id &&
+           (inet_pton(AF_INET, lsr_id, &params.neighbor.lsr_id) != 1 ||
+            bad_addr_v4(params.neighbor.lsr_id))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
 
-       if (params.capabilities)
+       if (params.neighbor.capabilities)
                params.detail = 1;
 
        if (!params.detail && !params.json)
@@ -1728,7 +1943,8 @@ ldp_vty_show_neighbor(struct vty *vty, int capabilities, const char *detail, con
 }
 
 int
-ldp_vty_show_atom_binding(struct vty *vty, const char *json)
+ldp_vty_show_atom_binding(struct vty *vty, const char *peer,
+    unsigned long local_label, unsigned long remote_label, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1738,13 +1954,22 @@ ldp_vty_show_atom_binding(struct vty *vty, const char *json)
 
        memset(&params, 0, sizeof(params));
        params.json = (json) ? 1 : 0;
+       if (peer &&
+           (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+            bad_addr_v4(params.l2vpn.peer))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       params.l2vpn.local_label = local_label;
+       params.l2vpn.remote_label = remote_label;
 
        imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
        return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
 }
 
 int
-ldp_vty_show_atom_vc(struct vty *vty, const char *json)
+ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname,
+    const char *vcid, const char *json)
 {
        struct imsgbuf           ibuf;
        struct show_params       params;
@@ -1754,6 +1979,17 @@ ldp_vty_show_atom_vc(struct vty *vty, const char *json)
 
        memset(&params, 0, sizeof(params));
        params.json = (json) ? 1 : 0;
+       if (peer &&
+           (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
+            bad_addr_v4(params.l2vpn.peer))) {
+               vty_out (vty, "%% Malformed address\n");
+               return (CMD_SUCCESS);
+       }
+       if (ifname)
+               strlcpy(params.l2vpn.ifname, ifname,
+                   sizeof(params.l2vpn.ifname));
+       if (vcid)
+               params.l2vpn.vcid = atoi(vcid);
 
        if (!params.json) {
                /* header */