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