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