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