]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_vty_exec.c
lib: move \n vs. \r\n handling into vty code
[mirror_frr.git] / ldpd / ldp_vty_exec.c
CommitLineData
eac6e3f0
RW
1/*
2 * Copyright (C) 2016 by Open Source Routing.
3 *
180fc2cd
RW
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
eac6e3f0 8 *
180fc2cd 9 * This program is distributed in the hope that it will be useful, but
eac6e3f0
RW
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
180fc2cd
RW
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
17 * MA 02110-1301 USA
eac6e3f0
RW
18 */
19
20#include <zebra.h>
21#include <sys/un.h>
22
23#include "ldpd.h"
24#include "ldpe.h"
25#include "lde.h"
26#include "log.h"
27#include "ldp_vty.h"
e8dbef04 28#include "lib/json.h"
eac6e3f0
RW
29
30#include "command.h"
31#include "vty.h"
32#include "mpls.h"
33
34enum show_command {
35 SHOW_DISC,
36 SHOW_IFACE,
37 SHOW_NBR,
38 SHOW_LIB,
39 SHOW_L2VPN_PW,
40 SHOW_L2VPN_BINDING
41};
42
a5d10512 43struct show_params {
eac6e3f0
RW
44 int family;
45 union ldpd_addr addr;
46 uint8_t prefixlen;
99cfc17f 47 int capabilities;
bc0eb287 48 int detail;
a5d10512 49 int json;
eac6e3f0
RW
50};
51
52#define LDPBUFSIZ 65535
53
54static int show_interface_msg(struct vty *, struct imsg *,
a5d10512
RW
55 struct show_params *);
56static int show_interface_msg_json(struct imsg *,
57 struct show_params *, json_object *);
eac6e3f0 58static int show_discovery_msg(struct vty *, struct imsg *,
a5d10512 59 struct show_params *);
bc0eb287 60static void show_discovery_detail_adj(struct vty *, char *,
a5d10512 61 struct ctl_adj *);
bc0eb287
RW
62static int show_discovery_detail_msg(struct vty *, struct imsg *,
63 struct show_params *);
a5d10512
RW
64static int show_discovery_msg_json(struct imsg *,
65 struct show_params *, json_object *);
bc0eb287
RW
66static void show_discovery_detail_adj_json(json_object *,
67 struct ctl_adj *);
68static int show_discovery_detail_msg_json(struct imsg *,
69 struct show_params *, json_object *);
99cfc17f 70
eac6e3f0 71static int show_nbr_msg(struct vty *, struct imsg *,
a5d10512 72 struct show_params *);
a5d10512
RW
73static int show_nbr_msg_json(struct imsg *, struct show_params *,
74 json_object *);
bc0eb287
RW
75static void show_nbr_detail_adj(struct vty *, char *,
76 struct ctl_adj *);
77static int show_nbr_detail_msg(struct vty *, struct imsg *,
78 struct show_params *);
79static void show_nbr_detail_adj_json(struct ctl_adj *,
80 json_object *);
81static int show_nbr_detail_msg_json(struct imsg *,
82 struct show_params *, json_object *);
0f7b5df9 83static void show_nbr_capabilities(struct vty *, struct ctl_nbr *);
99cfc17f
RW
84static int show_nbr_capabilities_msg(struct vty *, struct imsg *,
85 struct show_params *);
0f7b5df9
RW
86static void show_nbr_capabilities_json(struct ctl_nbr *,
87 json_object *);
99cfc17f
RW
88static int show_nbr_capabilities_msg_json(struct imsg *,
89 struct show_params *, json_object *);
eac6e3f0 90static int show_lib_msg(struct vty *, struct imsg *,
a5d10512 91 struct show_params *);
bc0eb287
RW
92static int show_lib_detail_msg(struct vty *, struct imsg *,
93 struct show_params *);
a5d10512
RW
94static int show_lib_msg_json(struct imsg *, struct show_params *,
95 json_object *);
bc0eb287
RW
96static int show_lib_detail_msg_json(struct imsg *,
97 struct show_params *, json_object *);
a5d10512
RW
98static int show_l2vpn_binding_msg(struct vty *, struct imsg *,
99 struct show_params *);
100static int show_l2vpn_binding_msg_json(struct imsg *,
101 struct show_params *, json_object *);
102static int show_l2vpn_pw_msg(struct vty *, struct imsg *,
103 struct show_params *);
104static int show_l2vpn_pw_msg_json(struct imsg *,
105 struct show_params *, json_object *);
eac6e3f0 106static int ldp_vty_connect(struct imsgbuf *);
a5d10512
RW
107static int ldp_vty_dispatch_msg(struct vty *, struct imsg *,
108 enum show_command, struct show_params *,
109 json_object *);
eac6e3f0 110static int ldp_vty_dispatch(struct vty *, struct imsgbuf *,
a5d10512 111 enum show_command, struct show_params *);
eac6e3f0
RW
112static int ldp_vty_get_af(const char *, int *);
113
114static int
115show_interface_msg(struct vty *vty, struct imsg *imsg,
a5d10512 116 struct show_params *params)
eac6e3f0
RW
117{
118 struct ctl_iface *iface;
119 char timers[BUFSIZ];
120
121 switch (imsg->hdr.type) {
122 case IMSG_CTL_SHOW_INTERFACE:
123 iface = imsg->data;
124
a5d10512 125 if (params->family != AF_UNSPEC && params->family != iface->af)
eac6e3f0
RW
126 break;
127
a5d10512
RW
128 snprintf(timers, sizeof(timers), "%u/%u",
129 iface->hello_interval, iface->hello_holdtime);
130
96ade3ed 131 vty_outln (vty, "%-4s %-11s %-6s %-8s %-12s %3u",
a5d10512
RW
132 af_name(iface->af), iface->name,
133 if_state_name(iface->state), iface->uptime == 0 ?
134 "00:00:00" : log_time(iface->uptime), timers,
96ade3ed 135 iface->adj_cnt);
eac6e3f0
RW
136 break;
137 case IMSG_CTL_END:
e31b6333 138 vty_out (vty, VTYNL);
eac6e3f0
RW
139 return (1);
140 default:
141 break;
142 }
143
144 return (0);
145}
146
a5d10512
RW
147static int
148show_interface_msg_json(struct imsg *imsg, struct show_params *params,
149 json_object *json)
150{
151 struct ctl_iface *iface;
152 json_object *json_iface;
153 char key_name[64];
154
155 switch (imsg->hdr.type) {
156 case IMSG_CTL_SHOW_INTERFACE:
157 iface = imsg->data;
158
159 if (params->family != AF_UNSPEC && params->family != iface->af)
160 break;
161
162 json_iface = json_object_new_object();
163 json_object_string_add(json_iface, "name", iface->name);
164 json_object_string_add(json_iface, "addressFamily",
165 af_name(iface->af));
166 json_object_string_add(json_iface, "state",
167 if_state_name(iface->state));
168 json_object_string_add(json_iface, "upTime",
169 log_time(iface->uptime));
170 json_object_int_add(json_iface, "helloInterval",
171 iface->hello_interval);
172 json_object_int_add(json_iface, "helloHoldtime",
173 iface->hello_holdtime);
174 json_object_int_add(json_iface, "adjacencyCount",
175 iface->adj_cnt);
176
177 sprintf(key_name, "%s: %s", iface->name, af_name(iface->af));
178 json_object_object_add(json, key_name, json_iface);
179 break;
180 case IMSG_CTL_END:
181 return (1);
182 default:
183 break;
184 }
185
186 return (0);
187}
188
bc0eb287
RW
189static int
190show_discovery_msg(struct vty *vty, struct imsg *imsg,
191 struct show_params *params)
192{
193 struct ctl_adj *adj;
194 const char *addr;
195
196 switch (imsg->hdr.type) {
197 case IMSG_CTL_SHOW_DISCOVERY:
198 adj = imsg->data;
199
200 if (params->family != AF_UNSPEC && params->family != adj->af)
201 break;
202
203 vty_out(vty, "%-4s %-15s ", af_name(adj->af),
204 inet_ntoa(adj->id));
205 switch(adj->type) {
206 case HELLO_LINK:
207 vty_out(vty, "%-8s %-15s ", "Link", adj->ifname);
208 break;
209 case HELLO_TARGETED:
210 addr = log_addr(adj->af, &adj->src_addr);
211
212 vty_out(vty, "%-8s %-15s ", "Targeted", addr);
213 if (strlen(addr) > 15)
1318e7c8 214 vty_out(vty, "%s%46s", VTYNL, " ");
bc0eb287
RW
215 break;
216 }
96ade3ed 217 vty_outln (vty, "%9u", adj->holdtime);
bc0eb287
RW
218 break;
219 case IMSG_CTL_END:
e31b6333 220 vty_out (vty, VTYNL);
bc0eb287
RW
221 return (1);
222 default:
223 break;
224 }
225
226 return (0);
227}
228
eac6e3f0 229static void
bc0eb287 230show_discovery_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
eac6e3f0
RW
231{
232 size_t buflen = strlen(buffer);
a5d10512
RW
233
234 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
1318e7c8 235 " LSR Id: %s:0%s", inet_ntoa(adj->id), VTYNL);
0f7b5df9
RW
236 buflen = strlen(buffer);
237 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
238 " Source address: %s%s",
1318e7c8 239 log_addr(adj->af, &adj->src_addr), VTYNL);
0f7b5df9
RW
240 buflen = strlen(buffer);
241 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
242 " Transport address: %s%s",
1318e7c8 243 log_addr(adj->af, &adj->trans_addr), VTYNL);
0f7b5df9
RW
244 buflen = strlen(buffer);
245 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
246 " Hello hold time: %u secs (due in %u secs)%s",
1318e7c8 247 adj->holdtime, adj->holdtime_remaining, VTYNL);
a5d10512
RW
248 buflen = strlen(buffer);
249 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
0f7b5df9 250 " Dual-stack capability TLV: %s%s",
1318e7c8 251 (adj->ds_tlv) ? "yes" : "no", VTYNL);
eac6e3f0
RW
252}
253
254static int
bc0eb287 255show_discovery_detail_msg(struct vty *vty, struct imsg *imsg,
a5d10512 256 struct show_params *params)
eac6e3f0
RW
257{
258 struct ctl_adj *adj;
259 struct ctl_disc_if *iface;
260 struct ctl_disc_tnbr *tnbr;
261 struct in_addr rtr_id;
262 union ldpd_addr *trans_addr;
263 size_t buflen;
264 static char ifaces_buffer[LDPBUFSIZ];
265 static char tnbrs_buffer[LDPBUFSIZ];
266
267 switch (imsg->hdr.type) {
268 case IMSG_CTL_SHOW_DISCOVERY:
269 ifaces_buffer[0] = '\0';
270 tnbrs_buffer[0] = '\0';
271 break;
272 case IMSG_CTL_SHOW_DISC_IFACE:
273 iface = imsg->data;
274
a5d10512
RW
275 if (params->family != AF_UNSPEC &&
276 ((params->family == AF_INET && !iface->active_v4) ||
277 (params->family == AF_INET6 && !iface->active_v6)))
eac6e3f0
RW
278 break;
279
a5d10512
RW
280 buflen = strlen(ifaces_buffer);
281 snprintf(ifaces_buffer + buflen, LDPBUFSIZ - buflen,
282 " %s: %s%s", iface->name, (iface->no_adj) ?
1318e7c8 283 "(no adjacencies)" : "", VTYNL);
a5d10512
RW
284 break;
285 case IMSG_CTL_SHOW_DISC_TNBR:
286 tnbr = imsg->data;
e8dbef04 287
a5d10512
RW
288 if (params->family != AF_UNSPEC && params->family != tnbr->af)
289 break;
e8dbef04 290
a5d10512
RW
291 trans_addr = &(ldp_af_conf_get(ldpd_conf,
292 tnbr->af))->trans_addr;
293 buflen = strlen(tnbrs_buffer);
294 snprintf(tnbrs_buffer + buflen, LDPBUFSIZ - buflen,
295 " %s -> %s: %s%s", log_addr(tnbr->af, trans_addr),
0f7b5df9 296 log_addr(tnbr->af, &tnbr->addr), (tnbr->no_adj) ?
1318e7c8 297 "(no adjacencies)" : "", VTYNL);
a5d10512
RW
298 break;
299 case IMSG_CTL_SHOW_DISC_ADJ:
300 adj = imsg->data;
e8dbef04 301
a5d10512
RW
302 if (params->family != AF_UNSPEC && params->family != adj->af)
303 break;
e8dbef04 304
a5d10512
RW
305 switch(adj->type) {
306 case HELLO_LINK:
bc0eb287 307 show_discovery_detail_adj(vty, ifaces_buffer, adj);
a5d10512
RW
308 break;
309 case HELLO_TARGETED:
bc0eb287 310 show_discovery_detail_adj(vty, tnbrs_buffer, adj);
a5d10512
RW
311 break;
312 }
313 break;
314 case IMSG_CTL_END:
315 rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
96ade3ed
QY
316 vty_outln (vty, "Local:");
317 vty_outln (vty, " LSR Id: %s:0",inet_ntoa(rtr_id));
0f7b5df9 318 if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
96ade3ed
QY
319 vty_outln (vty, " Transport Address (IPv4): %s",
320 log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr));
0f7b5df9 321 if (ldpd_conf->ipv6.flags & F_LDPD_AF_ENABLED)
96ade3ed
QY
322 vty_outln (vty, " Transport Address (IPv6): %s",
323 log_addr(AF_INET6, &ldpd_conf->ipv6.trans_addr));
324 vty_outln (vty, "Discovery Sources:");
325 vty_outln (vty, " Interfaces:");
a5d10512 326 vty_out(vty, "%s", ifaces_buffer);
96ade3ed 327 vty_outln (vty, " Targeted Hellos:");
a5d10512 328 vty_out(vty, "%s", tnbrs_buffer);
e31b6333 329 vty_out (vty, VTYNL);
a5d10512
RW
330 return (1);
331 default:
332 break;
333 }
e8dbef04 334
a5d10512
RW
335 return (0);
336}
337
bc0eb287
RW
338static int
339show_discovery_msg_json(struct imsg *imsg, struct show_params *params,
340 json_object *json)
341{
342 struct ctl_adj *adj;
343 json_object *json_array;
344 json_object *json_adj;
345
346 switch (imsg->hdr.type) {
347 case IMSG_CTL_SHOW_DISCOVERY:
348 adj = imsg->data;
349
350 if (params->family != AF_UNSPEC && params->family != adj->af)
351 break;
352
353 json_object_object_get_ex(json, "adjacencies", &json_array);
354 if (!json_array) {
355 json_array = json_object_new_array();
356 json_object_object_add(json, "adjacencies", json_array);
357 }
358
359 json_adj = json_object_new_object();
360 json_object_string_add(json_adj, "addressFamily",
361 af_name(adj->af));
362 json_object_string_add(json_adj, "neighborId",
363 inet_ntoa(adj->id));
364 switch(adj->type) {
365 case HELLO_LINK:
366 json_object_string_add(json_adj, "type", "link");
367 json_object_string_add(json_adj, "interface",
368 adj->ifname);
369 break;
370 case HELLO_TARGETED:
371 json_object_string_add(json_adj, "type", "targeted");
372 json_object_string_add(json_adj, "peer",
373 log_addr(adj->af, &adj->src_addr));
374 break;
375 }
376 json_object_int_add(json_adj, "helloHoldtime", adj->holdtime);
377
378 json_object_array_add(json_array, json_adj);
379 break;
380 case IMSG_CTL_END:
381 return (1);
382 default:
383 break;
384 }
385
386 return (0);
387}
388
a5d10512 389static void
bc0eb287 390show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj)
a5d10512
RW
391{
392 json_object *json_adj;
393 json_object *json_array;
394
395 json_object_object_get_ex(json, "adjacencies", &json_array);
396 if (!json_array) {
397 json_array = json_object_new_array();
398 json_object_object_add(json, "adjacencies", json_array);
399 }
400
401 json_adj = json_object_new_object();
0f7b5df9
RW
402 json_object_string_add(json_adj, "lsrId", inet_ntoa(adj->id));
403 json_object_string_add(json_adj, "sourceAddress", log_addr(adj->af,
404 &adj->src_addr));
a5d10512
RW
405 json_object_string_add(json_adj, "transportAddress", log_addr(adj->af,
406 &adj->trans_addr));
0f7b5df9
RW
407 json_object_int_add(json_adj, "helloHoldtime", adj->holdtime);
408 json_object_int_add(json_adj, "helloHoldtimeRemaining",
409 adj->holdtime_remaining);
410 json_object_int_add(json_adj, "dualStackCapabilityTlv",
411 adj->ds_tlv);
a5d10512
RW
412 json_object_array_add(json_array, json_adj);
413}
414
415static int
bc0eb287 416show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params,
a5d10512
RW
417 json_object *json)
418{
419 struct ctl_adj *adj;
420 struct ctl_disc_if *iface;
421 struct ctl_disc_tnbr *tnbr;
422 struct in_addr rtr_id;
423 union ldpd_addr *trans_addr;
424 json_object *json_interface;
425 json_object *json_target;
426 static json_object *json_interfaces;
427 static json_object *json_targets;
428 static json_object *json_container;
429
430 switch (imsg->hdr.type) {
431 case IMSG_CTL_SHOW_DISCOVERY:
432 rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
0f7b5df9
RW
433 json_object_string_add(json, "lsrId", inet_ntoa(rtr_id));
434 if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
435 json_object_string_add(json, "transportAddressIPv4",
436 log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr));
437 if (ldpd_conf->ipv6.flags & F_LDPD_AF_ENABLED)
438 json_object_string_add(json, "transportAddressIPv6",
439 log_addr(AF_INET6, &ldpd_conf->ipv6.trans_addr));
a5d10512
RW
440 json_interfaces = json_object_new_object();
441 json_object_object_add(json, "interfaces", json_interfaces);
442 json_targets = json_object_new_object();
443 json_object_object_add(json, "targetedHellos", json_targets);
444 json_container = NULL;
eac6e3f0 445 break;
a5d10512
RW
446 case IMSG_CTL_SHOW_DISC_IFACE:
447 iface = imsg->data;
eac6e3f0 448
a5d10512
RW
449 if (params->family != AF_UNSPEC &&
450 ((params->family == AF_INET && !iface->active_v4) ||
451 (params->family == AF_INET6 && !iface->active_v6)))
eac6e3f0
RW
452 break;
453
a5d10512 454 json_interface = json_object_new_object();
a5d10512
RW
455 json_object_object_add(json_interfaces, iface->name,
456 json_interface);
457 json_container = json_interface;
458 break;
459 case IMSG_CTL_SHOW_DISC_TNBR:
460 tnbr = imsg->data;
e8dbef04 461
a5d10512
RW
462 if (params->family != AF_UNSPEC && params->family != tnbr->af)
463 break;
e8dbef04 464
a5d10512 465 trans_addr = &(ldp_af_conf_get(ldpd_conf, tnbr->af))->trans_addr;
e8dbef04 466
a5d10512
RW
467 json_target = json_object_new_object();
468 json_object_string_add(json_target, "sourceAddress",
469 log_addr(tnbr->af, trans_addr));
a5d10512
RW
470 json_object_object_add(json_targets, log_addr(tnbr->af,
471 &tnbr->addr), json_target);
472 json_container = json_target;
eac6e3f0
RW
473 break;
474 case IMSG_CTL_SHOW_DISC_ADJ:
475 adj = imsg->data;
476
a5d10512 477 if (params->family != AF_UNSPEC && params->family != adj->af)
eac6e3f0
RW
478 break;
479
480 switch(adj->type) {
481 case HELLO_LINK:
bc0eb287 482 show_discovery_detail_adj_json(json_container, adj);
eac6e3f0
RW
483 break;
484 case HELLO_TARGETED:
bc0eb287 485 show_discovery_detail_adj_json(json_container, adj);
eac6e3f0
RW
486 break;
487 }
488 break;
489 case IMSG_CTL_END:
a5d10512 490 return (1);
eac6e3f0
RW
491 default:
492 break;
493 }
494
495 return (0);
496}
497
bc0eb287
RW
498static int
499show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
500{
501 struct ctl_nbr *nbr;
502 const char *addr;
503
504 switch (imsg->hdr.type) {
505 case IMSG_CTL_SHOW_NBR:
506 nbr = imsg->data;
507
508 addr = log_addr(nbr->af, &nbr->raddr);
509
510 vty_out(vty, "%-4s %-15s %-11s %-15s",
511 af_name(nbr->af), inet_ntoa(nbr->id),
512 nbr_state_name(nbr->nbr_state), addr);
513 if (strlen(addr) > 15)
1318e7c8 514 vty_out(vty, "%s%48s", VTYNL, " ");
96ade3ed 515 vty_outln (vty, " %8s", log_time(nbr->uptime));
bc0eb287
RW
516 break;
517 case IMSG_CTL_END:
518 return (1);
519 default:
520 break;
521 }
522
523 return (0);
524}
525
eac6e3f0 526static void
bc0eb287 527show_nbr_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
eac6e3f0
RW
528{
529 size_t buflen = strlen(buffer);
530
531 switch (adj->type) {
532 case HELLO_LINK:
a5d10512 533 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
1318e7c8 534 " Interface: %s%s", adj->ifname, VTYNL);
eac6e3f0
RW
535 break;
536 case HELLO_TARGETED:
a5d10512
RW
537 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
538 " Targeted Hello: %s%s", log_addr(adj->af,
1318e7c8 539 &adj->src_addr), VTYNL);
eac6e3f0
RW
540 break;
541 }
542}
543
544static int
0f7b5df9
RW
545show_nbr_detail_msg(struct vty *vty, struct imsg *imsg,
546 struct show_params *params)
eac6e3f0 547{
eac6e3f0 548 struct ctl_nbr *nbr;
0f7b5df9 549 struct ldp_stats *stats;
a5d10512 550 struct ctl_adj *adj;
eac6e3f0
RW
551 static char v4adjs_buffer[LDPBUFSIZ];
552 static char v6adjs_buffer[LDPBUFSIZ];
553
554 switch (imsg->hdr.type) {
555 case IMSG_CTL_SHOW_NBR:
556 nbr = imsg->data;
557
a5d10512
RW
558 v4adjs_buffer[0] = '\0';
559 v6adjs_buffer[0] = '\0';
96ade3ed
QY
560 vty_outln (vty, "Peer LDP Identifier: %s:0",
561 inet_ntoa(nbr->id));
562 vty_outln (vty, " TCP connection: %s:%u - %s:%u",
a5d10512 563 log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport),
96ade3ed
QY
564 log_addr(nbr->af, &nbr->raddr),ntohs(nbr->rport));
565 vty_outln (vty, " Authentication: %s",
566 (nbr->auth_method == AUTH_MD5SIG) ? "TCP MD5 Signature" : "none");
567 vty_outln(vty, " Session Holdtime: %u secs; "
568 "KeepAlive interval: %u secs", nbr->holdtime,
569 nbr->holdtime / KEEPALIVE_PER_PERIOD);
570 vty_outln(vty, " State: %s; Downstream-Unsolicited",
571 nbr_state_name(nbr->nbr_state));
572 vty_outln (vty, " Up time: %s",log_time(nbr->uptime));
0f7b5df9
RW
573
574 stats = &nbr->stats;
96ade3ed
QY
575 vty_outln (vty, " Messages sent/rcvd:");
576 vty_outln (vty, " - Keepalive Messages: %u/%u",
577 stats->kalive_sent, stats->kalive_rcvd);
578 vty_outln (vty, " - Address Messages: %u/%u",
579 stats->addr_sent, stats->addr_rcvd);
580 vty_outln (vty, " - Address Withdraw Messages: %u/%u",
581 stats->addrwdraw_sent, stats->addrwdraw_rcvd);
582 vty_outln (vty, " - Notification Messages: %u/%u",
583 stats->notif_sent, stats->notif_rcvd);
584 vty_outln (vty, " - Capability Messages: %u/%u",
585 stats->capability_sent, stats->capability_rcvd);
586 vty_outln (vty, " - Label Mapping Messages: %u/%u",
587 stats->labelmap_sent, stats->labelmap_rcvd);
588 vty_outln (vty, " - Label Request Messages: %u/%u",
589 stats->labelreq_sent, stats->labelreq_rcvd);
590 vty_outln (vty, " - Label Withdraw Messages: %u/%u",
591 stats->labelwdraw_sent, stats->labelwdraw_rcvd);
592 vty_outln (vty, " - Label Release Messages: %u/%u",
593 stats->labelrel_sent, stats->labelrel_rcvd);
594 vty_outln (vty, " - Label Abort Request Messages: %u/%u",
595 stats->labelabreq_sent, stats->labelabreq_rcvd);
0f7b5df9
RW
596
597 show_nbr_capabilities(vty, nbr);
eac6e3f0
RW
598 break;
599 case IMSG_CTL_SHOW_NBR_DISC:
600 adj = imsg->data;
601
602 switch (adj->af) {
603 case AF_INET:
bc0eb287 604 show_nbr_detail_adj(vty, v4adjs_buffer, adj);
eac6e3f0
RW
605 break;
606 case AF_INET6:
bc0eb287 607 show_nbr_detail_adj(vty, v6adjs_buffer, adj);
eac6e3f0
RW
608 break;
609 default:
bc0eb287 610 fatalx("show_nbr_detail_msg: unknown af");
a5d10512
RW
611 }
612 break;
613 case IMSG_CTL_SHOW_NBR_END:
96ade3ed 614 vty_outln (vty, " LDP Discovery Sources:");
a5d10512 615 if (v4adjs_buffer[0] != '\0') {
96ade3ed 616 vty_outln (vty, " IPv4:");
a5d10512
RW
617 vty_out(vty, "%s", v4adjs_buffer);
618 }
619 if (v6adjs_buffer[0] != '\0') {
96ade3ed 620 vty_outln (vty, " IPv6:");
a5d10512
RW
621 vty_out(vty, "%s", v6adjs_buffer);
622 }
e31b6333 623 vty_out (vty, VTYNL);
a5d10512
RW
624 break;
625 case IMSG_CTL_END:
626 return (1);
627 default:
628 break;
629 }
630
631 return (0);
632}
633
bc0eb287
RW
634static int
635show_nbr_msg_json(struct imsg *imsg, struct show_params *params,
636 json_object *json)
637{
638 struct ctl_nbr *nbr;
639 json_object *json_array;
640 json_object *json_nbr;
641
642 switch (imsg->hdr.type) {
643 case IMSG_CTL_SHOW_NBR:
644 nbr = imsg->data;
645
646 json_object_object_get_ex(json, "neighbors", &json_array);
647 if (!json_array) {
648 json_array = json_object_new_array();
649 json_object_object_add(json, "neighbors", json_array);
650 }
651
652 json_nbr = json_object_new_object();
653 json_object_string_add(json_nbr, "addressFamily",
654 af_name(nbr->af));
655 json_object_string_add(json_nbr, "neighborId",
656 inet_ntoa(nbr->id));
657 json_object_string_add(json_nbr, "state",
658 nbr_state_name(nbr->nbr_state));
659 json_object_string_add(json_nbr, "transportAddress",
660 log_addr(nbr->af, &nbr->raddr));
661 json_object_string_add(json_nbr, "upTime",
662 log_time(nbr->uptime));
663
664 json_object_array_add(json_array, json_nbr);
665 break;
666 case IMSG_CTL_END:
667 return (1);
668 default:
669 break;
670 }
671
672 return (0);
673}
674
a5d10512 675static void
bc0eb287 676show_nbr_detail_adj_json(struct ctl_adj *adj, json_object *adj_list)
a5d10512
RW
677{
678 char adj_string[128];
679
680 switch (adj->type) {
681 case HELLO_LINK:
682 strlcpy(adj_string, "interface: ", sizeof(adj_string));
683 strlcat(adj_string, adj->ifname, sizeof(adj_string));
684 break;
685 case HELLO_TARGETED:
686 strlcpy(adj_string, "targetedHello: ", sizeof(adj_string));
687 strlcat(adj_string, log_addr(adj->af, &adj->src_addr),
688 sizeof(adj_string));
689 break;
690 }
691
692 json_object_array_add(adj_list, json_object_new_string(adj_string));
693}
694
695static int
bc0eb287 696show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params,
a5d10512
RW
697 json_object *json)
698{
699 struct ctl_nbr *nbr;
0f7b5df9 700 struct ldp_stats *stats;
a5d10512
RW
701 struct ctl_adj *adj;
702 json_object *json_nbr;
0f7b5df9
RW
703 json_object *json_array;
704 json_object *json_counter;
a5d10512
RW
705 static json_object *json_nbr_sources;
706 static json_object *json_v4adjs;
707 static json_object *json_v6adjs;
708
709 switch (imsg->hdr.type) {
710 case IMSG_CTL_SHOW_NBR:
711 nbr = imsg->data;
712
713 json_nbr = json_object_new_object();
0f7b5df9
RW
714 json_object_object_add(json, inet_ntoa(nbr->id), json_nbr);
715
a5d10512
RW
716 json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id));
717 json_object_string_add(json_nbr, "tcpLocalAddress",
718 log_addr(nbr->af, &nbr->laddr));
719 json_object_int_add(json_nbr, "tcpLocalPort",
720 ntohs(nbr->lport));
721 json_object_string_add(json_nbr, "tcpRemoteAddress",
722 log_addr(nbr->af, &nbr->raddr));
723 json_object_int_add(json_nbr, "tcpRemotePort",
724 ntohs(nbr->rport));
0f7b5df9
RW
725 json_object_string_add(json_nbr, "authentication",
726 (nbr->auth_method == AUTH_MD5SIG) ? "TCP MD5 Signature" :
727 "none");
728 json_object_int_add(json_nbr, "sessionHoldtime", nbr->holdtime);
729 json_object_int_add(json_nbr, "keepAliveInterval",
730 nbr->holdtime / KEEPALIVE_PER_PERIOD);
a5d10512
RW
731 json_object_string_add(json_nbr, "state",
732 nbr_state_name(nbr->nbr_state));
733 json_object_string_add(json_nbr, "upTime",
734 log_time(nbr->uptime));
a5d10512 735
0f7b5df9
RW
736 /* message_counters */
737 stats = &nbr->stats;
738 json_array = json_object_new_array();
739 json_object_object_add(json_nbr, "sentMessages", json_array);
740 json_counter = json_object_new_object();
741 json_object_int_add(json_counter, "keepalive",
742 stats->kalive_sent);
743 json_object_array_add(json_array, json_counter);
744 json_counter = json_object_new_object();
745 json_object_int_add(json_counter, "address",
746 stats->addr_sent);
747 json_object_array_add(json_array, json_counter);
748 json_counter = json_object_new_object();
749 json_object_int_add(json_counter, "addressWithdraw",
750 stats->addrwdraw_sent);
751 json_object_array_add(json_array, json_counter);
752 json_counter = json_object_new_object();
753 json_object_int_add(json_counter, "notification",
754 stats->notif_sent);
755 json_object_array_add(json_array, json_counter);
756 json_counter = json_object_new_object();
757 json_object_int_add(json_counter, "capability",
758 stats->capability_sent);
759 json_object_array_add(json_array, json_counter);
760 json_counter = json_object_new_object();
761 json_object_int_add(json_counter, "labelMapping",
762 stats->labelmap_sent);
763 json_object_array_add(json_array, json_counter);
764 json_counter = json_object_new_object();
765 json_object_int_add(json_counter, "labelRequest",
766 stats->labelreq_sent);
767 json_object_array_add(json_array, json_counter);
768 json_counter = json_object_new_object();
769 json_object_int_add(json_counter, "labelWithdraw",
770 stats->labelwdraw_sent);
771 json_object_array_add(json_array, json_counter);
772 json_counter = json_object_new_object();
773 json_object_int_add(json_counter, "labelRelease",
774 stats->labelrel_sent);
775 json_object_array_add(json_array, json_counter);
776 json_counter = json_object_new_object();
777 json_object_int_add(json_counter, "labelAbortRequest",
778 stats->labelabreq_sent);
779 json_object_array_add(json_array, json_counter);
780
781 json_array = json_object_new_array();
782 json_object_object_add(json_nbr, "receivedMessages", json_array);
783 json_counter = json_object_new_object();
784 json_object_int_add(json_counter, "keepalive",
785 stats->kalive_rcvd);
786 json_object_array_add(json_array, json_counter);
787 json_counter = json_object_new_object();
788 json_object_int_add(json_counter, "address",
789 stats->addr_rcvd);
790 json_object_array_add(json_array, json_counter);
791 json_counter = json_object_new_object();
792 json_object_int_add(json_counter, "addressWithdraw",
793 stats->addrwdraw_rcvd);
794 json_object_array_add(json_array, json_counter);
795 json_counter = json_object_new_object();
796 json_object_int_add(json_counter, "notification",
797 stats->notif_rcvd);
798 json_object_array_add(json_array, json_counter);
799 json_counter = json_object_new_object();
800 json_object_int_add(json_counter, "capability",
801 stats->capability_rcvd);
802 json_object_array_add(json_array, json_counter);
803 json_counter = json_object_new_object();
804 json_object_int_add(json_counter, "labelMapping",
805 stats->labelmap_rcvd);
806 json_object_array_add(json_array, json_counter);
807 json_counter = json_object_new_object();
808 json_object_int_add(json_counter, "labelRequest",
809 stats->labelreq_rcvd);
810 json_object_array_add(json_array, json_counter);
811 json_counter = json_object_new_object();
812 json_object_int_add(json_counter, "labelWithdraw",
813 stats->labelwdraw_rcvd);
814 json_object_array_add(json_array, json_counter);
815 json_counter = json_object_new_object();
816 json_object_int_add(json_counter, "labelRelease",
817 stats->labelrel_rcvd);
818 json_object_array_add(json_array, json_counter);
819 json_counter = json_object_new_object();
820 json_object_int_add(json_counter, "labelAbortRequest",
821 stats->labelabreq_rcvd);
822 json_object_array_add(json_array, json_counter);
823
824 /* capabilities */
825 show_nbr_capabilities_json(nbr, json_nbr);
826
827 /* discovery sources */
a5d10512
RW
828 json_nbr_sources = json_object_new_object();
829 json_object_object_add(json_nbr, "discoverySources",
830 json_nbr_sources);
831 json_v4adjs = NULL;
832 json_v6adjs = NULL;
833 break;
834 case IMSG_CTL_SHOW_NBR_DISC:
835 adj = imsg->data;
836
837 switch (adj->af) {
838 case AF_INET:
839 if (!json_v4adjs) {
840 json_v4adjs = json_object_new_array();
841 json_object_object_add(json_nbr_sources, "ipv4",
842 json_v4adjs);
843 }
bc0eb287 844 show_nbr_detail_adj_json(adj, json_v4adjs);
a5d10512
RW
845 break;
846 case AF_INET6:
847 if (!json_v6adjs) {
848 json_v6adjs = json_object_new_array();
849 json_object_object_add(json_nbr_sources, "ipv6",
850 json_v6adjs);
851 }
bc0eb287 852 show_nbr_detail_adj_json(adj, json_v6adjs);
a5d10512
RW
853 break;
854 default:
bc0eb287 855 fatalx("show_nbr_detail_msg_json: unknown af");
a5d10512 856 }
eac6e3f0
RW
857 break;
858 case IMSG_CTL_SHOW_NBR_END:
eac6e3f0
RW
859 break;
860 case IMSG_CTL_END:
861 return (1);
862 default:
863 break;
864 }
865
866 return (0);
867}
868
0f7b5df9
RW
869void
870show_nbr_capabilities(struct vty *vty, struct ctl_nbr *nbr)
871{
96ade3ed 872 vty_outln (vty, " Capabilities Sent:%s"
0f7b5df9
RW
873 " - Dynamic Announcement (0x0506)%s"
874 " - Typed Wildcard (0x050B)%s"
96ade3ed 875 " - Unrecognized Notification (0x0603)",
1318e7c8 876 VTYNL, VTYNL, VTYNL);
96ade3ed 877 vty_outln (vty, " Capabilities Received:");
0f7b5df9 878 if (nbr->flags & F_NBR_CAP_DYNAMIC)
96ade3ed 879 vty_outln (vty," - Dynamic Announcement (0x0506)");
0f7b5df9 880 if (nbr->flags & F_NBR_CAP_TWCARD)
96ade3ed 881 vty_outln (vty, " - Typed Wildcard (0x050B)");
0f7b5df9 882 if (nbr->flags & F_NBR_CAP_UNOTIF)
96ade3ed 883 vty_outln (vty," - Unrecognized Notification (0x0603)");
0f7b5df9
RW
884}
885
99cfc17f
RW
886static int
887show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
888{
889 struct ctl_nbr *nbr;
890
891 switch (imsg->hdr.type) {
892 case IMSG_CTL_SHOW_NBR:
893 nbr = imsg->data;
894
895 if (nbr->nbr_state != NBR_STA_OPER)
896 break;
897
96ade3ed
QY
898 vty_outln (vty, "Peer LDP Identifier: %s:0",
899 inet_ntoa(nbr->id));
0f7b5df9 900 show_nbr_capabilities(vty, nbr);
e31b6333 901 vty_out (vty, VTYNL);
99cfc17f
RW
902 break;
903 case IMSG_CTL_END:
e31b6333 904 vty_out (vty, VTYNL);
99cfc17f
RW
905 return (1);
906 default:
907 break;
908 }
909
910 return (0);
911}
912
0f7b5df9
RW
913static void
914show_nbr_capabilities_json(struct ctl_nbr *nbr, json_object *json_nbr)
99cfc17f 915{
99cfc17f
RW
916 json_object *json_array;
917 json_object *json_cap;
918
0f7b5df9
RW
919 /* sent capabilities */
920 json_array = json_object_new_array();
921 json_object_object_add(json_nbr, "sentCapabilities", json_array);
922
923 /* Dynamic Announcement (0x0506) */
924 json_cap = json_object_new_object();
925 json_object_string_add(json_cap, "description", "Dynamic Announcement");
926 json_object_string_add(json_cap, "tlvType", "0x0506");
927 json_object_array_add(json_array, json_cap);
928
929 /* Typed Wildcard (0x050B) */
930 json_cap = json_object_new_object();
931 json_object_string_add(json_cap, "description", "Typed Wildcard");
932 json_object_string_add(json_cap, "tlvType", "0x050B");
933 json_object_array_add(json_array, json_cap);
934
935 /* Unrecognized Notification (0x0603) */
936 json_cap = json_object_new_object();
937 json_object_string_add(json_cap, "description",
938 "Unrecognized Notification");
939 json_object_string_add(json_cap, "tlvType", "0x0603");
940 json_object_array_add(json_array, json_cap);
941
942 /* received capabilities */
943 json_array = json_object_new_array();
944 json_object_object_add(json_nbr, "receivedCapabilities", json_array);
945
946 /* Dynamic Announcement (0x0506) */
947 if (nbr->flags & F_NBR_CAP_DYNAMIC) {
99cfc17f
RW
948 json_cap = json_object_new_object();
949 json_object_string_add(json_cap, "description",
950 "Dynamic Announcement");
0f7b5df9 951 json_object_string_add(json_cap, "tlvType", "0x0506");
99cfc17f 952 json_object_array_add(json_array, json_cap);
0f7b5df9 953 }
99cfc17f 954
0f7b5df9
RW
955 /* Typed Wildcard (0x050B) */
956 if (nbr->flags & F_NBR_CAP_TWCARD) {
99cfc17f
RW
957 json_cap = json_object_new_object();
958 json_object_string_add(json_cap, "description",
959 "Typed Wildcard");
0f7b5df9 960 json_object_string_add(json_cap, "tlvType", "0x050B");
99cfc17f 961 json_object_array_add(json_array, json_cap);
0f7b5df9 962 }
99cfc17f 963
0f7b5df9
RW
964 /* Unrecognized Notification (0x0603) */
965 if (nbr->flags & F_NBR_CAP_UNOTIF) {
99cfc17f
RW
966 json_cap = json_object_new_object();
967 json_object_string_add(json_cap, "description",
968 "Unrecognized Notification");
0f7b5df9 969 json_object_string_add(json_cap, "tlvType", "0x0603");
99cfc17f 970 json_object_array_add(json_array, json_cap);
0f7b5df9
RW
971 }
972}
99cfc17f 973
0f7b5df9
RW
974static int
975show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params,
976 json_object *json)
977{
978 struct ctl_nbr *nbr;
979 json_object *json_nbr;
99cfc17f 980
0f7b5df9
RW
981 switch (imsg->hdr.type) {
982 case IMSG_CTL_SHOW_NBR:
983 nbr = imsg->data;
99cfc17f 984
0f7b5df9
RW
985 if (nbr->nbr_state != NBR_STA_OPER)
986 break;
987
988 json_nbr = json_object_new_object();
989 json_object_object_add(json, inet_ntoa(nbr->id), json_nbr);
990 show_nbr_capabilities_json(nbr, json_nbr);
99cfc17f
RW
991 break;
992 case IMSG_CTL_END:
993 return (1);
994 default:
995 break;
996 }
997
998 return (0);
999}
1000
eac6e3f0 1001static int
a5d10512 1002show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
eac6e3f0
RW
1003{
1004 struct ctl_rt *rt;
1005 char dstnet[BUFSIZ];
1006
bc0eb287 1007 switch (imsg->hdr.type) {
0f7b5df9
RW
1008 case IMSG_CTL_SHOW_LIB_BEGIN:
1009 case IMSG_CTL_SHOW_LIB_RCVD:
bc0eb287
RW
1010 rt = imsg->data;
1011
0f7b5df9
RW
1012 if (imsg->hdr.type == IMSG_CTL_SHOW_LIB_BEGIN &&
1013 !rt->no_downstream)
1014 break;
1015
bc0eb287
RW
1016 if (params->family != AF_UNSPEC && params->family != rt->af)
1017 break;
1018
1019 snprintf(dstnet, sizeof(dstnet), "%s/%d",
1020 log_addr(rt->af, &rt->prefix), rt->prefixlen);
1021
1022 vty_out(vty, "%-4s %-20s", af_name(rt->af), dstnet);
1023 if (strlen(dstnet) > 20)
1318e7c8 1024 vty_out(vty, "%s%25s", VTYNL, " ");
96ade3ed 1025 vty_outln (vty, " %-15s %-11s %-13s %6s", inet_ntoa(rt->nexthop),
bc0eb287 1026 log_label(rt->local_label), log_label(rt->remote_label),
96ade3ed 1027 rt->in_use ? "yes" : "no");
bc0eb287
RW
1028 break;
1029 case IMSG_CTL_END:
e31b6333 1030 vty_out (vty, VTYNL);
bc0eb287
RW
1031 return (1);
1032 default:
1033 break;
1034 }
1035
1036 return (0);
1037}
1038
1039static int
1040show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
1041{
f790d62a 1042 struct ctl_rt *rt = NULL;
bc0eb287 1043 char dstnet[BUFSIZ];
0f7b5df9
RW
1044 static int upstream, downstream;
1045 size_t buflen;
1046 static char sent_buffer[LDPBUFSIZ];
1047 static char rcvd_buffer[LDPBUFSIZ];
bc0eb287 1048
eac6e3f0 1049 switch (imsg->hdr.type) {
0f7b5df9
RW
1050 case IMSG_CTL_SHOW_LIB_BEGIN:
1051 case IMSG_CTL_SHOW_LIB_SENT:
1052 case IMSG_CTL_SHOW_LIB_RCVD:
1053 case IMSG_CTL_SHOW_LIB_END:
eac6e3f0 1054 rt = imsg->data;
a5d10512 1055 if (params->family != AF_UNSPEC && params->family != rt->af)
0f7b5df9
RW
1056 return (0);
1057 break;
1058 default:
1059 break;
1060 }
1061
1062 switch (imsg->hdr.type) {
1063 case IMSG_CTL_SHOW_LIB_BEGIN:
1064 upstream = 0;
1065 downstream = 0;
1066 sent_buffer[0] = '\0';
1067 rcvd_buffer[0] = '\0';
eac6e3f0
RW
1068
1069 snprintf(dstnet, sizeof(dstnet), "%s/%d",
a5d10512
RW
1070 log_addr(rt->af, &rt->prefix), rt->prefixlen);
1071
96ade3ed
QY
1072 vty_outln (vty, "%s", dstnet);
1073 vty_outln (vty, "%-8sLocal binding: label: %s", "",
1074 log_label(rt->local_label));
0f7b5df9
RW
1075 break;
1076 case IMSG_CTL_SHOW_LIB_SENT:
1077 upstream = 1;
1078 buflen = strlen(sent_buffer);
1079 snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
1318e7c8 1080 "%12s%s:0%s", "", inet_ntoa(rt->nexthop), VTYNL);
0f7b5df9
RW
1081 break;
1082 case IMSG_CTL_SHOW_LIB_RCVD:
1083 downstream = 1;
1084 buflen = strlen(rcvd_buffer);
1085 snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
1086 "%12s%s:0, label %s%s%s", "", inet_ntoa(rt->nexthop),
1087 log_label(rt->remote_label),
1318e7c8 1088 rt->in_use ? " (in use)" : "", VTYNL);
0f7b5df9
RW
1089 break;
1090 case IMSG_CTL_SHOW_LIB_END:
1091 if (upstream) {
96ade3ed 1092 vty_outln (vty, "%-8sAdvertised to:", "");
0f7b5df9 1093 vty_out(vty, "%s", sent_buffer);
a5d10512 1094 }
0f7b5df9 1095 if (downstream) {
96ade3ed 1096 vty_outln (vty, "%-8sRemote bindings:", "");
0f7b5df9
RW
1097 vty_out(vty, "%s", rcvd_buffer);
1098 } else
96ade3ed 1099 vty_outln (vty, "%-8sNo remote bindings","");
eac6e3f0
RW
1100 break;
1101 case IMSG_CTL_END:
e31b6333 1102 vty_out (vty, VTYNL);
eac6e3f0
RW
1103 return (1);
1104 default:
1105 break;
1106 }
1107
1108 return (0);
1109}
1110
1111static int
a5d10512
RW
1112show_lib_msg_json(struct imsg *imsg, struct show_params *params,
1113 json_object *json)
bc0eb287
RW
1114{
1115 struct ctl_rt *rt;
1116 json_object *json_array;
1117 json_object *json_lib_entry;
1118 char dstnet[BUFSIZ];
1119
1120 switch (imsg->hdr.type) {
0f7b5df9
RW
1121 case IMSG_CTL_SHOW_LIB_BEGIN:
1122 case IMSG_CTL_SHOW_LIB_RCVD:
bc0eb287
RW
1123 rt = imsg->data;
1124
0f7b5df9
RW
1125 if (imsg->hdr.type == IMSG_CTL_SHOW_LIB_BEGIN &&
1126 !rt->no_downstream)
bc0eb287
RW
1127 break;
1128
1129 json_object_object_get_ex(json, "bindings", &json_array);
1130 if (!json_array) {
1131 json_array = json_object_new_array();
1132 json_object_object_add(json, "bindings", json_array);
1133 }
1134
1135 json_lib_entry = json_object_new_object();
1136 json_object_string_add(json_lib_entry, "addressFamily",
1137 af_name(rt->af));
1138 snprintf(dstnet, sizeof(dstnet), "%s/%d",
1139 log_addr(rt->af, &rt->prefix), rt->prefixlen);
1140 json_object_string_add(json_lib_entry, "prefix", dstnet);
1141 json_object_string_add(json_lib_entry, "neighborId",
1142 inet_ntoa(rt->nexthop));
1143 json_object_string_add(json_lib_entry, "localLabel",
1144 log_label(rt->local_label));
1145 json_object_string_add(json_lib_entry, "remoteLabel",
1146 log_label(rt->remote_label));
1147 json_object_int_add(json_lib_entry, "inUse", rt->in_use);
1148
1149 json_object_array_add(json_array, json_lib_entry);
1150 break;
1151 case IMSG_CTL_END:
1152 return (1);
1153 default:
1154 break;
1155 }
1156
1157 return (0);
1158}
1159
1160static int
1161show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
1162 json_object *json)
a5d10512 1163{
f790d62a 1164 struct ctl_rt *rt = NULL;
a5d10512 1165 char dstnet[BUFSIZ];
0f7b5df9
RW
1166 static json_object *json_lib_entry;
1167 static json_object *json_adv_labels;
1168 json_object *json_adv_label;
a5d10512
RW
1169 static json_object *json_remote_labels;
1170 json_object *json_remote_label;
1171
1172 switch (imsg->hdr.type) {
0f7b5df9
RW
1173 case IMSG_CTL_SHOW_LIB_BEGIN:
1174 case IMSG_CTL_SHOW_LIB_SENT:
1175 case IMSG_CTL_SHOW_LIB_RCVD:
1176 case IMSG_CTL_SHOW_LIB_END:
a5d10512 1177 rt = imsg->data;
a5d10512 1178 if (params->family != AF_UNSPEC && params->family != rt->af)
0f7b5df9
RW
1179 return (0);
1180 break;
1181 default:
1182 break;
1183 }
a5d10512 1184
0f7b5df9
RW
1185 switch (imsg->hdr.type) {
1186 case IMSG_CTL_SHOW_LIB_BEGIN:
a5d10512
RW
1187 snprintf(dstnet, sizeof(dstnet), "%s/%d",
1188 log_addr(rt->af, &rt->prefix), rt->prefixlen);
1189
0f7b5df9
RW
1190 json_lib_entry = json_object_new_object();
1191 json_object_string_add(json_lib_entry, "localLabel",
1192 log_label(rt->local_label));
a5d10512 1193
0f7b5df9
RW
1194 json_adv_labels = json_object_new_array();
1195 json_object_object_add(json_lib_entry, "advertisedTo",
1196 json_adv_labels);
a5d10512 1197
0f7b5df9
RW
1198 json_remote_labels = json_object_new_array();
1199 json_object_object_add(json_lib_entry, "remoteLabels",
1200 json_remote_labels);
1201
1202 json_object_object_add(json, dstnet, json_lib_entry);
1203 break;
1204 case IMSG_CTL_SHOW_LIB_SENT:
1205 json_adv_label = json_object_new_object();
1206 json_object_string_add(json_adv_label, "neighborId",
1207 inet_ntoa(rt->nexthop));
1208 json_object_array_add(json_adv_labels, json_adv_label);
1209 break;
1210 case IMSG_CTL_SHOW_LIB_RCVD:
1211 json_remote_label = json_object_new_object();
1212 json_object_string_add(json_remote_label, "neighborId",
1213 inet_ntoa(rt->nexthop));
1214 json_object_string_add(json_remote_label, "label",
1215 log_label(rt->remote_label));
1216 json_object_int_add(json_remote_label, "inUse", rt->in_use);
1217 json_object_array_add(json_remote_labels, json_remote_label);
a5d10512
RW
1218 break;
1219 case IMSG_CTL_END:
1220 return (1);
1221 default:
1222 break;
1223 }
1224
1225 return (0);
1226}
1227
1228static int
1229show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg,
1230 struct show_params *params)
eac6e3f0
RW
1231{
1232 struct ctl_pw *pw;
1233
1234 switch (imsg->hdr.type) {
1235 case IMSG_CTL_SHOW_L2VPN_BINDING:
1236 pw = imsg->data;
1237
96ade3ed
QY
1238 vty_outln (vty, " Destination Address: %s, VC ID: %u",
1239 inet_ntoa(pw->lsr_id), pw->pwid);
eac6e3f0
RW
1240
1241 /* local binding */
1242 if (pw->local_label != NO_LABEL) {
96ade3ed
QY
1243 vty_outln (vty, " Local Label: %u",
1244 pw->local_label);
1245 vty_outln (vty, "%-8sCbit: %u, VC Type: %s, "
1246 "GroupID: %u", "", pw->local_cword,
1247 pw_type_name(pw->type),pw->local_gid);
1248 vty_outln (vty, "%-8sMTU: %u", "",pw->local_ifmtu);
eac6e3f0 1249 } else
96ade3ed 1250 vty_outln (vty," Local Label: unassigned");
eac6e3f0
RW
1251
1252 /* remote binding */
1253 if (pw->remote_label != NO_LABEL) {
96ade3ed
QY
1254 vty_outln (vty, " Remote Label: %u",
1255 pw->remote_label);
1256 vty_outln (vty, "%-8sCbit: %u, VC Type: %s, "
1257 "GroupID: %u", "", pw->remote_cword,
1258 pw_type_name(pw->type),pw->remote_gid);
1259 vty_outln (vty, "%-8sMTU: %u", "",pw->remote_ifmtu);
eac6e3f0 1260 } else
96ade3ed 1261 vty_outln (vty," Remote Label: unassigned");
eac6e3f0
RW
1262 break;
1263 case IMSG_CTL_END:
e31b6333 1264 vty_out (vty, VTYNL);
eac6e3f0
RW
1265 return (1);
1266 default:
1267 break;
1268 }
1269
1270 return (0);
1271}
1272
1273static int
a5d10512
RW
1274show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params,
1275 json_object *json)
1276{
1277 struct ctl_pw *pw;
1278 json_object *json_pw;
1279 char key_name[64];
1280
1281 switch (imsg->hdr.type) {
1282 case IMSG_CTL_SHOW_L2VPN_BINDING:
1283 pw = imsg->data;
1284
1285 json_pw = json_object_new_object();
1286 json_object_string_add(json_pw, "destination",
1287 inet_ntoa(pw->lsr_id));
1288 json_object_int_add(json_pw, "vcId", pw->pwid);
1289
1290 /* local binding */
1291 if (pw->local_label != NO_LABEL) {
1292 json_object_int_add(json_pw, "localLabel",
1293 pw->local_label);
1294 json_object_int_add(json_pw, "localControlWord",
1295 pw->local_cword);
1296 json_object_string_add(json_pw, "localVcType",
1297 pw_type_name(pw->type));
1298 json_object_int_add(json_pw, "localGroupID",
1299 pw->local_gid);
1300 json_object_int_add(json_pw, "localIfMtu",
1301 pw->local_ifmtu);
1302 } else
1303 json_object_string_add(json_pw, "localLabel",
1304 "unassigned");
1305
1306 /* remote binding */
1307 if (pw->remote_label != NO_LABEL) {
1308 json_object_int_add(json_pw, "remoteLabel",
1309 pw->remote_label);
1310 json_object_int_add(json_pw, "remoteControlWord",
1311 pw->remote_cword);
1312 json_object_string_add(json_pw, "remoteVcType",
1313 pw_type_name(pw->type));
1314 json_object_int_add(json_pw, "remoteGroupID",
1315 pw->remote_gid);
1316 json_object_int_add(json_pw, "remoteIfMtu",
1317 pw->remote_ifmtu);
1318 } else
1319 json_object_string_add(json_pw, "remoteLabel",
1320 "unassigned");
1321
1322 sprintf(key_name, "%s: %u", inet_ntoa(pw->lsr_id), pw->pwid);
1323 json_object_object_add(json, key_name, json_pw);
1324 break;
1325 case IMSG_CTL_END:
1326 return (1);
1327 default:
1328 break;
1329 }
1330
1331 return (0);
1332}
1333
1334static int
1335show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
eac6e3f0
RW
1336{
1337 struct ctl_pw *pw;
1338
1339 switch (imsg->hdr.type) {
1340 case IMSG_CTL_SHOW_L2VPN_PW:
1341 pw = imsg->data;
1342
96ade3ed 1343 vty_outln (vty, "%-9s %-15s %-10u %-16s %-10s", pw->ifname,
eac6e3f0 1344 inet_ntoa(pw->lsr_id), pw->pwid, pw->l2vpn_name,
96ade3ed 1345 (pw->status ? "UP" : "DOWN"));
eac6e3f0
RW
1346 break;
1347 case IMSG_CTL_END:
e31b6333 1348 vty_out (vty, VTYNL);
eac6e3f0
RW
1349 return (1);
1350 default:
1351 break;
1352 }
1353
1354 return (0);
1355}
1356
a5d10512
RW
1357static int
1358show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params,
1359 json_object *json)
1360{
1361 struct ctl_pw *pw;
1362 json_object *json_pw;
1363
1364 switch (imsg->hdr.type) {
1365 case IMSG_CTL_SHOW_L2VPN_PW:
1366 pw = imsg->data;
1367
1368 json_pw = json_object_new_object();
1369 json_object_string_add(json_pw, "peerId", inet_ntoa(pw->lsr_id));
1370 json_object_int_add(json_pw, "vcId", pw->pwid);
1371 json_object_string_add(json_pw, "VpnName", pw->l2vpn_name);
1372 if (pw->status)
1373 json_object_string_add(json_pw, "status", "up");
1374 else
1375 json_object_string_add(json_pw, "status", "down");
1376 json_object_object_add(json, pw->ifname, json_pw);
1377 break;
1378 case IMSG_CTL_END:
1379 return (1);
1380 default:
1381 break;
1382 }
1383
1384 return (0);
1385}
1386
eac6e3f0
RW
1387static int
1388ldp_vty_connect(struct imsgbuf *ibuf)
1389{
1390 struct sockaddr_un s_un;
1391 int ctl_sock;
1392
1393 /* connect to ldpd control socket */
1394 if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
1395 log_warn("%s: socket", __func__);
1396 return (-1);
1397 }
1398
1399 memset(&s_un, 0, sizeof(s_un));
1400 s_un.sun_family = AF_UNIX;
372b8bd3 1401 strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
eac6e3f0 1402 if (connect(ctl_sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
372b8bd3 1403 log_warn("%s: connect: %s", __func__, ctl_sock_path);
eac6e3f0
RW
1404 close(ctl_sock);
1405 return (-1);
1406 }
1407
1408 imsg_init(ibuf, ctl_sock);
1409
1410 return (0);
1411}
1412
a5d10512
RW
1413static int
1414ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
1415 struct show_params *params, json_object *json)
1416{
bc0eb287
RW
1417 int ret;
1418
a5d10512
RW
1419 switch (cmd) {
1420 case SHOW_IFACE:
bc0eb287
RW
1421 if (params->json)
1422 ret = show_interface_msg_json(imsg, params, json);
1423 else
1424 ret = show_interface_msg(vty, imsg, params);
1425 break;
a5d10512 1426 case SHOW_DISC:
bc0eb287
RW
1427 if (params->detail) {
1428 if (params->json)
1429 ret = show_discovery_detail_msg_json(imsg,
1430 params, json);
1431 else
1432 ret = show_discovery_detail_msg(vty, imsg,
1433 params);
1434 } else {
1435 if (params->json)
1436 ret = show_discovery_msg_json(imsg, params,
1437 json);
1438 else
1439 ret = show_discovery_msg(vty, imsg, params);
1440 }
1441 break;
a5d10512 1442 case SHOW_NBR:
99cfc17f
RW
1443 if (params->capabilities) {
1444 if (params->json)
1445 ret = show_nbr_capabilities_msg_json(imsg,
1446 params, json);
1447 else
1448 ret = show_nbr_capabilities_msg(vty, imsg,
1449 params);
1450 } else if (params->detail) {
bc0eb287
RW
1451 if (params->json)
1452 ret = show_nbr_detail_msg_json(imsg, params,
1453 json);
1454 else
1455 ret = show_nbr_detail_msg(vty, imsg, params);
1456 } else {
1457 if (params->json)
1458 ret = show_nbr_msg_json(imsg, params, json);
1459 else
1460 ret = show_nbr_msg(vty, imsg, params);
1461 }
1462 break;
a5d10512 1463 case SHOW_LIB:
bc0eb287
RW
1464 if (params->detail) {
1465 if (params->json)
1466 ret = show_lib_detail_msg_json(imsg, params,
1467 json);
1468 else
1469 ret = show_lib_detail_msg(vty, imsg, params);
1470 } else {
1471 if (params->json)
1472 ret = show_lib_msg_json(imsg, params, json);
1473 else
1474 ret = show_lib_msg(vty, imsg, params);
1475 }
1476 break;
a5d10512 1477 case SHOW_L2VPN_PW:
bc0eb287
RW
1478 if (params->json)
1479 ret = show_l2vpn_pw_msg_json(imsg, params, json);
1480 else
1481 ret = show_l2vpn_pw_msg(vty, imsg, params);
1482 break;
a5d10512 1483 case SHOW_L2VPN_BINDING:
bc0eb287
RW
1484 if (params->json)
1485 ret = show_l2vpn_binding_msg_json(imsg, params, json);
1486 else
1487 ret = show_l2vpn_binding_msg(vty, imsg, params);
1488 break;
a5d10512
RW
1489 default:
1490 return (0);
1491 }
bc0eb287
RW
1492
1493 return (ret);
a5d10512
RW
1494}
1495
eac6e3f0
RW
1496static int
1497ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
a5d10512 1498 struct show_params *params)
eac6e3f0
RW
1499{
1500 struct imsg imsg;
a5d10512
RW
1501 int n, done = 0, ret = CMD_SUCCESS;
1502 json_object *json = NULL;
eac6e3f0
RW
1503
1504 while (ibuf->w.queued)
1505 if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) {
1506 log_warn("write error");
1507 close(ibuf->fd);
1508 return (CMD_WARNING);
1509 }
1510
a5d10512
RW
1511 if (params->json)
1512 json = json_object_new_object();
e8dbef04 1513
eac6e3f0
RW
1514 while (!done) {
1515 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) {
1516 log_warnx("imsg_read error");
a5d10512
RW
1517 ret = CMD_WARNING;
1518 goto done;
eac6e3f0
RW
1519 }
1520 if (n == 0) {
1521 log_warnx("pipe closed");
a5d10512
RW
1522 ret = CMD_WARNING;
1523 goto done;
eac6e3f0
RW
1524 }
1525
1526 while (!done) {
1527 if ((n = imsg_get(ibuf, &imsg)) == -1) {
1528 log_warnx("imsg_get error");
a5d10512
RW
1529 ret = CMD_WARNING;
1530 goto done;
eac6e3f0
RW
1531 }
1532 if (n == 0)
1533 break;
a5d10512
RW
1534 done = ldp_vty_dispatch_msg(vty, &imsg, cmd, params,
1535 json);
eac6e3f0
RW
1536 imsg_free(&imsg);
1537 }
1538 }
1539
a5d10512 1540 done:
eac6e3f0 1541 close(ibuf->fd);
a5d10512 1542 if (json) {
96ade3ed
QY
1543 vty_outln (vty, "%s",
1544 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
a5d10512
RW
1545 json_object_free(json);
1546 }
eac6e3f0 1547
a5d10512 1548 return (ret);
eac6e3f0
RW
1549}
1550
1551static int
1552ldp_vty_get_af(const char *str, int *af)
1553{
1554 if (str == NULL) {
1555 *af = AF_UNSPEC;
1556 return (0);
1557 } else if (strcmp(str, "ipv4") == 0) {
1558 *af = AF_INET;
1559 return (0);
1560 } else if (strcmp(str, "ipv6") == 0) {
1561 *af = AF_INET6;
1562 return (0);
1563 }
1564
1565 return (-1);
1566}
1567
1568int
c740f7d3 1569ldp_vty_show_binding(struct vty *vty, const char *af_str, int detail, int json)
eac6e3f0
RW
1570{
1571 struct imsgbuf ibuf;
a5d10512 1572 struct show_params params;
eac6e3f0
RW
1573 int af;
1574
1575 if (ldp_vty_connect(&ibuf) < 0)
1576 return (CMD_WARNING);
1577
eac6e3f0
RW
1578 if (ldp_vty_get_af(af_str, &af) < 0)
1579 return (CMD_ERR_NO_MATCH);
1580
a5d10512
RW
1581 memset(&params, 0, sizeof(params));
1582 params.family = af;
c740f7d3
RW
1583 params.detail = detail;
1584 params.json = json;
eac6e3f0 1585
bc0eb287 1586 if (!params.detail && !params.json)
96ade3ed 1587 vty_outln (vty, "%-4s %-20s %-15s %-11s %-13s %6s", "AF",
bc0eb287 1588 "Destination", "Nexthop", "Local Label", "Remote Label",
96ade3ed 1589 "In Use");
bc0eb287 1590
a5d10512
RW
1591 imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0);
1592 return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, &params));
eac6e3f0
RW
1593}
1594
1595int
c740f7d3
RW
1596ldp_vty_show_discovery(struct vty *vty, const char *af_str, int detail,
1597 int json)
eac6e3f0
RW
1598{
1599 struct imsgbuf ibuf;
a5d10512 1600 struct show_params params;
eac6e3f0
RW
1601 int af;
1602
1603 if (ldp_vty_connect(&ibuf) < 0)
1604 return (CMD_WARNING);
1605
eac6e3f0
RW
1606 if (ldp_vty_get_af(af_str, &af) < 0)
1607 return (CMD_ERR_NO_MATCH);
1608
a5d10512
RW
1609 memset(&params, 0, sizeof(params));
1610 params.family = af;
c740f7d3
RW
1611 params.detail = detail;
1612 params.json = json;
eac6e3f0 1613
bc0eb287 1614 if (!params.detail && !params.json)
96ade3ed
QY
1615 vty_outln (vty, "%-4s %-15s %-8s %-15s %9s",
1616 "AF", "ID", "Type", "Source", "Holdtime");
bc0eb287
RW
1617
1618 if (params.detail)
1619 imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY_DTL, 0, 0, -1,
1620 NULL, 0);
1621 else
1622 imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
a5d10512 1623 return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, &params));
eac6e3f0
RW
1624}
1625
1626int
c740f7d3 1627ldp_vty_show_interface(struct vty *vty, const char *af_str, int json)
eac6e3f0
RW
1628{
1629 struct imsgbuf ibuf;
a5d10512 1630 struct show_params params;
eac6e3f0 1631 unsigned int ifidx = 0;
eac6e3f0
RW
1632 int af;
1633
1634 if (ldp_vty_connect(&ibuf) < 0)
1635 return (CMD_WARNING);
1636
eac6e3f0
RW
1637 if (ldp_vty_get_af(af_str, &af) < 0)
1638 return (CMD_ERR_NO_MATCH);
1639
a5d10512
RW
1640 memset(&params, 0, sizeof(params));
1641 params.family = af;
c740f7d3 1642 params.json = json;
eac6e3f0
RW
1643
1644 /* header */
a5d10512 1645 if (!params.json) {
96ade3ed
QY
1646 vty_outln (vty, "%-4s %-11s %-6s %-8s %-12s %3s", "AF",
1647 "Interface", "State", "Uptime", "Hello Timers","ac");
a5d10512 1648 }
eac6e3f0 1649
a5d10512
RW
1650 imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx,
1651 sizeof(ifidx));
1652 return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &params));
eac6e3f0
RW
1653}
1654
99cfc17f 1655int
c740f7d3 1656ldp_vty_show_capabilities(struct vty *vty, int json)
99cfc17f 1657{
c740f7d3 1658 if (json) {
99cfc17f
RW
1659 json_object *json;
1660 json_object *json_array;
1661 json_object *json_cap;
1662
1663 json = json_object_new_object();
1664 json_array = json_object_new_array();
1665 json_object_object_add(json, "capabilities", json_array);
1666
1667 /* Dynamic Announcement (0x0506) */
1668 json_cap = json_object_new_object();
1669 json_object_string_add(json_cap, "description",
1670 "Dynamic Announcement");
1671 json_object_string_add(json_cap, "tlvType",
1672 "0x0506");
1673 json_object_array_add(json_array, json_cap);
1674
1675 /* Typed Wildcard (0x050B) */
1676 json_cap = json_object_new_object();
1677 json_object_string_add(json_cap, "description",
1678 "Typed Wildcard");
1679 json_object_string_add(json_cap, "tlvType",
1680 "0x050B");
1681 json_object_array_add(json_array, json_cap);
1682
1683 /* Unrecognized Notification (0x0603) */
1684 json_cap = json_object_new_object();
1685 json_object_string_add(json_cap, "description",
1686 "Unrecognized Notification");
1687 json_object_string_add(json_cap, "tlvType",
1688 "0x0603");
1689 json_object_array_add(json_array, json_cap);
1690
96ade3ed
QY
1691 vty_outln (vty, "%s",
1692 json_object_to_json_string_ext(json, JSON_C_TO_STRING_PRETTY));
99cfc17f
RW
1693 json_object_free(json);
1694 return (0);
1695 }
1696
96ade3ed 1697 vty_outln (vty,
99cfc17f
RW
1698 "Supported LDP Capabilities%s"
1699 " * Dynamic Announcement (0x0506)%s"
1700 " * Typed Wildcard (0x050B)%s"
1318e7c8
QY
1701 " * Unrecognized Notification (0x0603)%s", VTYNL,
1702 VTYNL, VTYNL, VTYNL);
99cfc17f
RW
1703
1704 return (0);
1705}
1706
eac6e3f0 1707int
c740f7d3 1708ldp_vty_show_neighbor(struct vty *vty, int capabilities, int detail, int json)
eac6e3f0
RW
1709{
1710 struct imsgbuf ibuf;
a5d10512 1711 struct show_params params;
eac6e3f0
RW
1712
1713 if (ldp_vty_connect(&ibuf) < 0)
1714 return (CMD_WARNING);
1715
a5d10512 1716 memset(&params, 0, sizeof(params));
c740f7d3
RW
1717 params.capabilities = capabilities;
1718 params.detail = detail;
1719 params.json = json;
eac6e3f0 1720
99cfc17f
RW
1721 if (params.capabilities)
1722 params.detail = 1;
1723
bc0eb287 1724 if (!params.detail && !params.json)
96ade3ed
QY
1725 vty_outln (vty, "%-4s %-15s %-11s %-15s %8s",
1726 "AF", "ID", "State", "Remote Address","Uptime");
bc0eb287 1727
a5d10512
RW
1728 imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
1729 return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, &params));
eac6e3f0
RW
1730}
1731
1732int
c740f7d3 1733ldp_vty_show_atom_binding(struct vty *vty, int json)
eac6e3f0
RW
1734{
1735 struct imsgbuf ibuf;
a5d10512 1736 struct show_params params;
eac6e3f0
RW
1737
1738 if (ldp_vty_connect(&ibuf) < 0)
1739 return (CMD_WARNING);
1740
a5d10512 1741 memset(&params, 0, sizeof(params));
c740f7d3 1742 params.json = json;
eac6e3f0 1743
a5d10512
RW
1744 imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
1745 return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
eac6e3f0
RW
1746}
1747
1748int
c740f7d3 1749ldp_vty_show_atom_vc(struct vty *vty, int json)
eac6e3f0
RW
1750{
1751 struct imsgbuf ibuf;
a5d10512 1752 struct show_params params;
eac6e3f0
RW
1753
1754 if (ldp_vty_connect(&ibuf) < 0)
1755 return (CMD_WARNING);
1756
a5d10512 1757 memset(&params, 0, sizeof(params));
c740f7d3 1758 params.json = json;
a5d10512
RW
1759
1760 if (!params.json) {
1761 /* header */
96ade3ed
QY
1762 vty_outln (vty, "%-9s %-15s %-10s %-16s %-10s",
1763 "Interface", "Peer ID", "VC ID", "Name","Status");
1764 vty_outln (vty, "%-9s %-15s %-10s %-16s %-10s",
a5d10512 1765 "---------", "---------------", "----------",
96ade3ed 1766 "----------------", "----------");
a5d10512 1767 }
eac6e3f0 1768
a5d10512
RW
1769 imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0);
1770 return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, &params));
eac6e3f0
RW
1771}
1772
1773int
c740f7d3 1774ldp_vty_clear_nbr(struct vty *vty, const char *addr_str)
eac6e3f0
RW
1775{
1776 struct imsgbuf ibuf;
eac6e3f0
RW
1777 struct ctl_nbr nbr;
1778
eac6e3f0
RW
1779 memset(&nbr, 0, sizeof(nbr));
1780 if (addr_str &&
1781 (ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 ||
1782 bad_addr(nbr.af, &nbr.raddr))) {
96ade3ed 1783 vty_outln (vty, "%% Malformed address");
eac6e3f0
RW
1784 return (CMD_WARNING);
1785 }
1786
1787 if (ldp_vty_connect(&ibuf) < 0)
1788 return (CMD_WARNING);
1789
1790 imsg_compose(&ibuf, IMSG_CTL_CLEAR_NBR, 0, 0, -1, &nbr, sizeof(nbr));
1791
1792 while (ibuf.w.queued)
1793 if (msgbuf_write(&ibuf.w) <= 0 && errno != EAGAIN) {
1794 log_warn("write error");
1795 close(ibuf.fd);
1796 return (CMD_WARNING);
1797 }
1798
1799 close(ibuf.fd);
1800
1801 return (CMD_SUCCESS);
1802}