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