]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_vty_exec.c
pimd: fix mtracebis tool warning
[mirror_frr.git] / ldpd / ldp_vty_exec.c
CommitLineData
eac6e3f0
RW
1/*
2 * Copyright (C) 2016 by Open Source Routing.
3 *
180fc2cd
RW
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
eac6e3f0 8 *
180fc2cd 9 * This program is distributed in the hope that it will be useful, but
eac6e3f0
RW
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
180fc2cd
RW
14 * You should have received a copy of the GNU General Public License
15 * along with this program; see the file COPYING; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
17 * MA 02110-1301 USA
eac6e3f0
RW
18 */
19
20#include <zebra.h>
21#include <sys/un.h>
903a7226 22#include "lib/printfrr.h"
eac6e3f0
RW
23
24#include "ldpd.h"
25#include "ldpe.h"
26#include "lde.h"
27#include "log.h"
28#include "ldp_vty.h"
e8dbef04 29#include "lib/json.h"
eac6e3f0
RW
30
31#include "command.h"
32#include "vty.h"
33#include "mpls.h"
34
35enum show_command {
36 SHOW_DISC,
37 SHOW_IFACE,
38 SHOW_NBR,
39 SHOW_LIB,
40 SHOW_L2VPN_PW,
e1894ff7
KS
41 SHOW_L2VPN_BINDING,
42 SHOW_LDP_SYNC
eac6e3f0
RW
43};
44
a5d10512 45struct show_params {
eac6e3f0
RW
46 int family;
47 union ldpd_addr addr;
48 uint8_t prefixlen;
bc0eb287 49 int detail;
a5d10512 50 int json;
f0722791
RW
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 };
eac6e3f0
RW
71};
72
73#define LDPBUFSIZ 65535
74
75static int show_interface_msg(struct vty *, struct imsg *,
a5d10512
RW
76 struct show_params *);
77static int show_interface_msg_json(struct imsg *,
78 struct show_params *, json_object *);
eac6e3f0 79static int show_discovery_msg(struct vty *, struct imsg *,
a5d10512 80 struct show_params *);
bc0eb287 81static void show_discovery_detail_adj(struct vty *, char *,
a5d10512 82 struct ctl_adj *);
bc0eb287
RW
83static int show_discovery_detail_msg(struct vty *, struct imsg *,
84 struct show_params *);
a5d10512
RW
85static int show_discovery_msg_json(struct imsg *,
86 struct show_params *, json_object *);
bc0eb287
RW
87static void show_discovery_detail_adj_json(json_object *,
88 struct ctl_adj *);
89static int show_discovery_detail_msg_json(struct imsg *,
90 struct show_params *, json_object *);
e1894ff7
KS
91static int show_ldp_sync_msg(struct vty *, struct imsg *,
92 struct show_params *);
93static int show_ldp_sync_msg_json(struct imsg *,
94 struct show_params *, json_object *);
99cfc17f 95
eac6e3f0 96static int show_nbr_msg(struct vty *, struct imsg *,
a5d10512 97 struct show_params *);
a5d10512
RW
98static int show_nbr_msg_json(struct imsg *, struct show_params *,
99 json_object *);
bc0eb287
RW
100static void show_nbr_detail_adj(struct vty *, char *,
101 struct ctl_adj *);
102static int show_nbr_detail_msg(struct vty *, struct imsg *,
103 struct show_params *);
104static void show_nbr_detail_adj_json(struct ctl_adj *,
105 json_object *);
106static int show_nbr_detail_msg_json(struct imsg *,
107 struct show_params *, json_object *);
0f7b5df9 108static void show_nbr_capabilities(struct vty *, struct ctl_nbr *);
99cfc17f
RW
109static int show_nbr_capabilities_msg(struct vty *, struct imsg *,
110 struct show_params *);
0f7b5df9
RW
111static void show_nbr_capabilities_json(struct ctl_nbr *,
112 json_object *);
99cfc17f
RW
113static int show_nbr_capabilities_msg_json(struct imsg *,
114 struct show_params *, json_object *);
eac6e3f0 115static int show_lib_msg(struct vty *, struct imsg *,
a5d10512 116 struct show_params *);
bc0eb287
RW
117static int show_lib_detail_msg(struct vty *, struct imsg *,
118 struct show_params *);
a5d10512
RW
119static int show_lib_msg_json(struct imsg *, struct show_params *,
120 json_object *);
bc0eb287
RW
121static int show_lib_detail_msg_json(struct imsg *,
122 struct show_params *, json_object *);
a5d10512
RW
123static int show_l2vpn_binding_msg(struct vty *, struct imsg *,
124 struct show_params *);
125static int show_l2vpn_binding_msg_json(struct imsg *,
126 struct show_params *, json_object *);
127static int show_l2vpn_pw_msg(struct vty *, struct imsg *,
128 struct show_params *);
129static int show_l2vpn_pw_msg_json(struct imsg *,
130 struct show_params *, json_object *);
a5d10512
RW
131static int ldp_vty_dispatch_msg(struct vty *, struct imsg *,
132 enum show_command, struct show_params *,
133 json_object *);
eac6e3f0 134static int ldp_vty_dispatch(struct vty *, struct imsgbuf *,
a5d10512 135 enum show_command, struct show_params *);
eac6e3f0
RW
136static int ldp_vty_get_af(const char *, int *);
137
138static int
139show_interface_msg(struct vty *vty, struct imsg *imsg,
a5d10512 140 struct show_params *params)
eac6e3f0
RW
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
a5d10512 149 if (params->family != AF_UNSPEC && params->family != iface->af)
eac6e3f0
RW
150 break;
151
a5d10512
RW
152 snprintf(timers, sizeof(timers), "%u/%u",
153 iface->hello_interval, iface->hello_holdtime);
154
5c7571d4 155 vty_out (vty, "%-4s %-11s %-6s %-8s %-12s %3u\n",
a5d10512
RW
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,
96ade3ed 159 iface->adj_cnt);
eac6e3f0
RW
160 break;
161 case IMSG_CTL_END:
6d3c2ed4 162 vty_out (vty, "\n");
eac6e3f0
RW
163 return (1);
164 default:
165 break;
166 }
167
168 return (0);
169}
170
a5d10512
RW
171static int
172show_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
772270f3
QY
201 snprintf(key_name, sizeof(key_name), "%s: %s", iface->name,
202 af_name(iface->af));
a5d10512
RW
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
e1894ff7
KS
214static int
215show_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)
903a7226
MS
241 vty_out (vty, " Peer LDP Identifier: %pI4:0\n",
242 &iface->peer_ldp_id);
e1894ff7
KS
243
244 break;
245 case IMSG_CTL_END:
246 return (1);
247 default:
248 break;
249 }
250
251 return (0);
252}
253
254static int
255show_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;
903a7226 260 char buf[PREFIX_STRLEN];
e1894ff7
KS
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 ?
903a7226
MS
283 inet_ntop(AF_INET, &iface->peer_ldp_id, buf, sizeof(buf)) :
284 "");
e1894ff7
KS
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
bc0eb287
RW
297static int
298show_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
903a7226 311 vty_out(vty, "%-4s %-15pI4 ", af_name(adj->af), &adj->id);
bc0eb287
RW
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)
61b7d449 321 vty_out(vty, "\n%46s", " ");
bc0eb287
RW
322 break;
323 }
5c7571d4 324 vty_out (vty, "%9u\n", adj->holdtime);
bc0eb287
RW
325 break;
326 case IMSG_CTL_END:
6d3c2ed4 327 vty_out (vty, "\n");
bc0eb287
RW
328 return (1);
329 default:
330 break;
331 }
332
333 return (0);
334}
335
eac6e3f0 336static void
bc0eb287 337show_discovery_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
eac6e3f0
RW
338{
339 size_t buflen = strlen(buffer);
a5d10512 340
903a7226
MS
341 snprintfrr(buffer + buflen, LDPBUFSIZ - buflen,
342 " LSR Id: %pI4:0\n", &adj->id);
0f7b5df9
RW
343 buflen = strlen(buffer);
344 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
345 " Source address: %s\n",
346 log_addr(adj->af, &adj->src_addr));
0f7b5df9
RW
347 buflen = strlen(buffer);
348 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
349 " Transport address: %s\n",
350 log_addr(adj->af, &adj->trans_addr));
0f7b5df9
RW
351 buflen = strlen(buffer);
352 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
353 " Hello hold time: %u secs (due in %u secs)\n",
354 adj->holdtime, adj->holdtime_remaining);
a5d10512
RW
355 buflen = strlen(buffer);
356 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
357 " Dual-stack capability TLV: %s\n",
358 (adj->ds_tlv) ? "yes" : "no");
eac6e3f0
RW
359}
360
361static int
bc0eb287 362show_discovery_detail_msg(struct vty *vty, struct imsg *imsg,
a5d10512 363 struct show_params *params)
eac6e3f0
RW
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
a5d10512
RW
382 if (params->family != AF_UNSPEC &&
383 ((params->family == AF_INET && !iface->active_v4) ||
384 (params->family == AF_INET6 && !iface->active_v6)))
eac6e3f0
RW
385 break;
386
a5d10512
RW
387 buflen = strlen(ifaces_buffer);
388 snprintf(ifaces_buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
389 " %s: %s\n", iface->name, (iface->no_adj) ?
390 "(no adjacencies)" : "");
a5d10512
RW
391 break;
392 case IMSG_CTL_SHOW_DISC_TNBR:
393 tnbr = imsg->data;
e8dbef04 394
a5d10512
RW
395 if (params->family != AF_UNSPEC && params->family != tnbr->af)
396 break;
e8dbef04 397
a5d10512
RW
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,
625e016d 402 " %s -> %s: %s\n", log_addr(tnbr->af, trans_addr),
0f7b5df9 403 log_addr(tnbr->af, &tnbr->addr), (tnbr->no_adj) ?
625e016d 404 "(no adjacencies)" : "");
a5d10512
RW
405 break;
406 case IMSG_CTL_SHOW_DISC_ADJ:
407 adj = imsg->data;
e8dbef04 408
a5d10512
RW
409 if (params->family != AF_UNSPEC && params->family != adj->af)
410 break;
e8dbef04 411
a5d10512
RW
412 switch(adj->type) {
413 case HELLO_LINK:
bc0eb287 414 show_discovery_detail_adj(vty, ifaces_buffer, adj);
a5d10512
RW
415 break;
416 case HELLO_TARGETED:
bc0eb287 417 show_discovery_detail_adj(vty, tnbrs_buffer, adj);
a5d10512
RW
418 break;
419 }
420 break;
421 case IMSG_CTL_END:
422 rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
5c7571d4 423 vty_out (vty, "Local:\n");
903a7226 424 vty_out (vty, " LSR Id: %pI4:0\n",&rtr_id);
0f7b5df9 425 if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
5c7571d4 426 vty_out (vty, " Transport Address (IPv4): %s\n",
96ade3ed 427 log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr));
0f7b5df9 428 if (ldpd_conf->ipv6.flags & F_LDPD_AF_ENABLED)
5c7571d4 429 vty_out (vty, " Transport Address (IPv6): %s\n",
96ade3ed 430 log_addr(AF_INET6, &ldpd_conf->ipv6.trans_addr));
5c7571d4
DL
431 vty_out (vty, "Discovery Sources:\n");
432 vty_out (vty, " Interfaces:\n");
a5d10512 433 vty_out(vty, "%s", ifaces_buffer);
5c7571d4 434 vty_out (vty, " Targeted Hellos:\n");
a5d10512 435 vty_out(vty, "%s", tnbrs_buffer);
6d3c2ed4 436 vty_out (vty, "\n");
a5d10512
RW
437 return (1);
438 default:
439 break;
440 }
e8dbef04 441
a5d10512
RW
442 return (0);
443}
444
bc0eb287
RW
445static int
446show_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));
19fee2b7
DA
469 json_object_string_addf(json_adj, "neighborId", "%pI4",
470 &adj->id);
bc0eb287
RW
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
a5d10512 496static void
bc0eb287 497show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj)
a5d10512
RW
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();
19fee2b7 509 json_object_string_addf(json_adj, "lsrId", "%pI4", &adj->id);
0f7b5df9
RW
510 json_object_string_add(json_adj, "sourceAddress", log_addr(adj->af,
511 &adj->src_addr));
a5d10512
RW
512 json_object_string_add(json_adj, "transportAddress", log_addr(adj->af,
513 &adj->trans_addr));
0f7b5df9
RW
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);
a5d10512
RW
519 json_object_array_add(json_array, json_adj);
520}
521
522static int
bc0eb287 523show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params,
a5d10512
RW
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);
19fee2b7 540 json_object_string_addf(json, "lsrId", "%pI4", &rtr_id);
0f7b5df9
RW
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));
a5d10512
RW
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;
eac6e3f0 552 break;
a5d10512
RW
553 case IMSG_CTL_SHOW_DISC_IFACE:
554 iface = imsg->data;
eac6e3f0 555
a5d10512
RW
556 if (params->family != AF_UNSPEC &&
557 ((params->family == AF_INET && !iface->active_v4) ||
558 (params->family == AF_INET6 && !iface->active_v6)))
eac6e3f0
RW
559 break;
560
a5d10512 561 json_interface = json_object_new_object();
a5d10512
RW
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;
e8dbef04 568
a5d10512
RW
569 if (params->family != AF_UNSPEC && params->family != tnbr->af)
570 break;
e8dbef04 571
a5d10512 572 trans_addr = &(ldp_af_conf_get(ldpd_conf, tnbr->af))->trans_addr;
e8dbef04 573
a5d10512
RW
574 json_target = json_object_new_object();
575 json_object_string_add(json_target, "sourceAddress",
576 log_addr(tnbr->af, trans_addr));
a5d10512
RW
577 json_object_object_add(json_targets, log_addr(tnbr->af,
578 &tnbr->addr), json_target);
579 json_container = json_target;
eac6e3f0
RW
580 break;
581 case IMSG_CTL_SHOW_DISC_ADJ:
582 adj = imsg->data;
583
a5d10512 584 if (params->family != AF_UNSPEC && params->family != adj->af)
eac6e3f0
RW
585 break;
586
587 switch(adj->type) {
588 case HELLO_LINK:
bc0eb287 589 show_discovery_detail_adj_json(json_container, adj);
eac6e3f0
RW
590 break;
591 case HELLO_TARGETED:
bc0eb287 592 show_discovery_detail_adj_json(json_container, adj);
eac6e3f0
RW
593 break;
594 }
595 break;
596 case IMSG_CTL_END:
a5d10512 597 return (1);
eac6e3f0
RW
598 default:
599 break;
600 }
601
602 return (0);
603}
604
bc0eb287
RW
605static int
606show_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
903a7226
MS
617 vty_out(vty, "%-4s %-15pI4 %-11s %-15s",
618 af_name(nbr->af), &nbr->id,
619 nbr_state_name(nbr->nbr_state), addr);
bc0eb287 620 if (strlen(addr) > 15)
61b7d449 621 vty_out(vty, "\n%48s", " ");
5c7571d4 622 vty_out (vty, " %8s\n", log_time(nbr->uptime));
bc0eb287
RW
623 break;
624 case IMSG_CTL_END:
625 return (1);
626 default:
627 break;
628 }
629
630 return (0);
631}
632
eac6e3f0 633static void
bc0eb287 634show_nbr_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
eac6e3f0
RW
635{
636 size_t buflen = strlen(buffer);
637
638 switch (adj->type) {
639 case HELLO_LINK:
a5d10512 640 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d 641 " Interface: %s\n", adj->ifname);
eac6e3f0
RW
642 break;
643 case HELLO_TARGETED:
a5d10512 644 snprintf(buffer + buflen, LDPBUFSIZ - buflen,
625e016d
DL
645 " Targeted Hello: %s\n", log_addr(adj->af,
646 &adj->src_addr));
eac6e3f0
RW
647 break;
648 }
649}
650
651static int
0f7b5df9
RW
652show_nbr_detail_msg(struct vty *vty, struct imsg *imsg,
653 struct show_params *params)
eac6e3f0 654{
eac6e3f0 655 struct ctl_nbr *nbr;
0f7b5df9 656 struct ldp_stats *stats;
a5d10512 657 struct ctl_adj *adj;
eac6e3f0
RW
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
a5d10512
RW
665 v4adjs_buffer[0] = '\0';
666 v6adjs_buffer[0] = '\0';
903a7226
MS
667 vty_out (vty, "Peer LDP Identifier: %pI4:0\n",
668 &nbr->id);
5c7571d4 669 vty_out (vty, " TCP connection: %s:%u - %s:%u\n",
a5d10512 670 log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport),
96ade3ed 671 log_addr(nbr->af, &nbr->raddr),ntohs(nbr->rport));
5c7571d4 672 vty_out (vty, " Authentication: %s\n",
96ade3ed 673 (nbr->auth_method == AUTH_MD5SIG) ? "TCP MD5 Signature" : "none");
3efd0893 674 vty_out(vty, " Session Holdtime: %u secs; KeepAlive interval: %u secs\n", nbr->holdtime,
96ade3ed 675 nbr->holdtime / KEEPALIVE_PER_PERIOD);
5c7571d4 676 vty_out(vty, " State: %s; Downstream-Unsolicited\n",
96ade3ed 677 nbr_state_name(nbr->nbr_state));
5c7571d4 678 vty_out (vty, " Up time: %s\n",log_time(nbr->uptime));
0f7b5df9
RW
679
680 stats = &nbr->stats;
5c7571d4
DL
681 vty_out (vty, " Messages sent/rcvd:\n");
682 vty_out (vty, " - Keepalive Messages: %u/%u\n",
96ade3ed 683 stats->kalive_sent, stats->kalive_rcvd);
5c7571d4 684 vty_out (vty, " - Address Messages: %u/%u\n",
96ade3ed 685 stats->addr_sent, stats->addr_rcvd);
5c7571d4 686 vty_out (vty, " - Address Withdraw Messages: %u/%u\n",
96ade3ed 687 stats->addrwdraw_sent, stats->addrwdraw_rcvd);
5c7571d4 688 vty_out (vty, " - Notification Messages: %u/%u\n",
96ade3ed 689 stats->notif_sent, stats->notif_rcvd);
5c7571d4 690 vty_out (vty, " - Capability Messages: %u/%u\n",
96ade3ed 691 stats->capability_sent, stats->capability_rcvd);
5c7571d4 692 vty_out (vty, " - Label Mapping Messages: %u/%u\n",
96ade3ed 693 stats->labelmap_sent, stats->labelmap_rcvd);
5c7571d4 694 vty_out (vty, " - Label Request Messages: %u/%u\n",
96ade3ed 695 stats->labelreq_sent, stats->labelreq_rcvd);
5c7571d4 696 vty_out (vty, " - Label Withdraw Messages: %u/%u\n",
96ade3ed 697 stats->labelwdraw_sent, stats->labelwdraw_rcvd);
5c7571d4 698 vty_out (vty, " - Label Release Messages: %u/%u\n",
96ade3ed 699 stats->labelrel_sent, stats->labelrel_rcvd);
5c7571d4 700 vty_out (vty, " - Label Abort Request Messages: %u/%u\n",
96ade3ed 701 stats->labelabreq_sent, stats->labelabreq_rcvd);
0f7b5df9
RW
702
703 show_nbr_capabilities(vty, nbr);
eac6e3f0
RW
704 break;
705 case IMSG_CTL_SHOW_NBR_DISC:
706 adj = imsg->data;
707
708 switch (adj->af) {
709 case AF_INET:
bc0eb287 710 show_nbr_detail_adj(vty, v4adjs_buffer, adj);
eac6e3f0
RW
711 break;
712 case AF_INET6:
bc0eb287 713 show_nbr_detail_adj(vty, v6adjs_buffer, adj);
eac6e3f0
RW
714 break;
715 default:
bc0eb287 716 fatalx("show_nbr_detail_msg: unknown af");
a5d10512
RW
717 }
718 break;
719 case IMSG_CTL_SHOW_NBR_END:
5c7571d4 720 vty_out (vty, " LDP Discovery Sources:\n");
a5d10512 721 if (v4adjs_buffer[0] != '\0') {
5c7571d4 722 vty_out (vty, " IPv4:\n");
a5d10512
RW
723 vty_out(vty, "%s", v4adjs_buffer);
724 }
725 if (v6adjs_buffer[0] != '\0') {
5c7571d4 726 vty_out (vty, " IPv6:\n");
a5d10512
RW
727 vty_out(vty, "%s", v6adjs_buffer);
728 }
6d3c2ed4 729 vty_out (vty, "\n");
a5d10512
RW
730 break;
731 case IMSG_CTL_END:
732 return (1);
733 default:
734 break;
735 }
736
737 return (0);
738}
739
bc0eb287
RW
740static int
741show_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));
19fee2b7
DA
761 json_object_string_addf(json_nbr, "neighborId", "%pI4",
762 &nbr->id);
bc0eb287
RW
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
a5d10512 781static void
bc0eb287 782show_nbr_detail_adj_json(struct ctl_adj *adj, json_object *adj_list)
a5d10512
RW
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
801static int
bc0eb287 802show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params,
a5d10512
RW
803 json_object *json)
804{
805 struct ctl_nbr *nbr;
0f7b5df9 806 struct ldp_stats *stats;
a5d10512 807 struct ctl_adj *adj;
903a7226 808 char buf[PREFIX_STRLEN];
a5d10512 809 json_object *json_nbr;
0f7b5df9
RW
810 json_object *json_array;
811 json_object *json_counter;
a5d10512
RW
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();
903a7226
MS
821 json_object_object_add(json,
822 inet_ntop(AF_INET, &nbr->id, buf,
823 sizeof(buf)), json_nbr);
19fee2b7 824 json_object_string_addf(json_nbr, "peerId", "%pI4", &nbr->id);
a5d10512
RW
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));
0f7b5df9
RW
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);
a5d10512
RW
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));
a5d10512 843
0f7b5df9
RW
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 */
a5d10512
RW
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 }
bc0eb287 952 show_nbr_detail_adj_json(adj, json_v4adjs);
a5d10512
RW
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 }
bc0eb287 960 show_nbr_detail_adj_json(adj, json_v6adjs);
a5d10512
RW
961 break;
962 default:
bc0eb287 963 fatalx("show_nbr_detail_msg_json: unknown af");
a5d10512 964 }
eac6e3f0
RW
965 break;
966 case IMSG_CTL_SHOW_NBR_END:
eac6e3f0
RW
967 break;
968 case IMSG_CTL_END:
969 return (1);
970 default:
971 break;
972 }
973
974 return (0);
975}
976
0f7b5df9
RW
977void
978show_nbr_capabilities(struct vty *vty, struct ctl_nbr *nbr)
979{
625e016d
DL
980 vty_out (vty, " Capabilities Sent:\n"
981 " - Dynamic Announcement (0x0506)\n"
982 " - Typed Wildcard (0x050B)\n"
983 " - Unrecognized Notification (0x0603)\n");
5c7571d4 984 vty_out (vty, " Capabilities Received:\n");
0f7b5df9 985 if (nbr->flags & F_NBR_CAP_DYNAMIC)
5c7571d4 986 vty_out (vty," - Dynamic Announcement (0x0506)\n");
0f7b5df9 987 if (nbr->flags & F_NBR_CAP_TWCARD)
5c7571d4 988 vty_out (vty, " - Typed Wildcard (0x050B)\n");
0f7b5df9 989 if (nbr->flags & F_NBR_CAP_UNOTIF)
5c7571d4 990 vty_out (vty," - Unrecognized Notification (0x0603)\n");
0f7b5df9
RW
991}
992
99cfc17f
RW
993static int
994show_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
903a7226
MS
1005 vty_out (vty, "Peer LDP Identifier: %pI4:0\n",
1006 &nbr->id);
0f7b5df9 1007 show_nbr_capabilities(vty, nbr);
6d3c2ed4 1008 vty_out (vty, "\n");
99cfc17f
RW
1009 break;
1010 case IMSG_CTL_END:
6d3c2ed4 1011 vty_out (vty, "\n");
99cfc17f
RW
1012 return (1);
1013 default:
1014 break;
1015 }
1016
1017 return (0);
1018}
1019
0f7b5df9
RW
1020static void
1021show_nbr_capabilities_json(struct ctl_nbr *nbr, json_object *json_nbr)
99cfc17f 1022{
99cfc17f
RW
1023 json_object *json_array;
1024 json_object *json_cap;
1025
0f7b5df9
RW
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) {
99cfc17f
RW
1055 json_cap = json_object_new_object();
1056 json_object_string_add(json_cap, "description",
1057 "Dynamic Announcement");
0f7b5df9 1058 json_object_string_add(json_cap, "tlvType", "0x0506");
99cfc17f 1059 json_object_array_add(json_array, json_cap);
0f7b5df9 1060 }
99cfc17f 1061
0f7b5df9
RW
1062 /* Typed Wildcard (0x050B) */
1063 if (nbr->flags & F_NBR_CAP_TWCARD) {
99cfc17f
RW
1064 json_cap = json_object_new_object();
1065 json_object_string_add(json_cap, "description",
1066 "Typed Wildcard");
0f7b5df9 1067 json_object_string_add(json_cap, "tlvType", "0x050B");
99cfc17f 1068 json_object_array_add(json_array, json_cap);
0f7b5df9 1069 }
99cfc17f 1070
0f7b5df9
RW
1071 /* Unrecognized Notification (0x0603) */
1072 if (nbr->flags & F_NBR_CAP_UNOTIF) {
99cfc17f
RW
1073 json_cap = json_object_new_object();
1074 json_object_string_add(json_cap, "description",
1075 "Unrecognized Notification");
0f7b5df9 1076 json_object_string_add(json_cap, "tlvType", "0x0603");
99cfc17f 1077 json_object_array_add(json_array, json_cap);
0f7b5df9
RW
1078 }
1079}
99cfc17f 1080
0f7b5df9
RW
1081static int
1082show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params,
1083 json_object *json)
1084{
1085 struct ctl_nbr *nbr;
903a7226 1086 char buf[PREFIX_STRLEN];
0f7b5df9 1087 json_object *json_nbr;
99cfc17f 1088
0f7b5df9
RW
1089 switch (imsg->hdr.type) {
1090 case IMSG_CTL_SHOW_NBR:
1091 nbr = imsg->data;
99cfc17f 1092
0f7b5df9
RW
1093 if (nbr->nbr_state != NBR_STA_OPER)
1094 break;
1095
1096 json_nbr = json_object_new_object();
903a7226
MS
1097 json_object_object_add(json, inet_ntop(AF_INET, &nbr->id, buf,
1098 sizeof(buf)), json_nbr);
0f7b5df9 1099 show_nbr_capabilities_json(nbr, json_nbr);
99cfc17f
RW
1100 break;
1101 case IMSG_CTL_END:
1102 return (1);
1103 default:
1104 break;
1105 }
1106
1107 return (0);
1108}
1109
eac6e3f0 1110static int
a5d10512 1111show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
eac6e3f0
RW
1112{
1113 struct ctl_rt *rt;
1114 char dstnet[BUFSIZ];
1115
bc0eb287 1116 switch (imsg->hdr.type) {
0f7b5df9 1117 case IMSG_CTL_SHOW_LIB_BEGIN:
f0722791
RW
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 */
0f7b5df9 1124 case IMSG_CTL_SHOW_LIB_RCVD:
bc0eb287
RW
1125 rt = imsg->data;
1126
0f7b5df9
RW
1127 if (imsg->hdr.type == IMSG_CTL_SHOW_LIB_BEGIN &&
1128 !rt->no_downstream)
1129 break;
1130
bc0eb287
RW
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)
61b7d449 1136 vty_out(vty, "\n%25s", " ");
903a7226
MS
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");
bc0eb287
RW
1141 break;
1142 case IMSG_CTL_END:
6d3c2ed4 1143 vty_out (vty, "\n");
bc0eb287
RW
1144 return (1);
1145 default:
1146 break;
1147 }
1148
1149 return (0);
1150}
1151
1152static int
1153show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
1154{
f790d62a 1155 struct ctl_rt *rt = NULL;
f0722791 1156 static char dstnet[BUFSIZ];
0f7b5df9
RW
1157 static int upstream, downstream;
1158 size_t buflen;
1159 static char sent_buffer[LDPBUFSIZ];
1160 static char rcvd_buffer[LDPBUFSIZ];
bc0eb287 1161
eac6e3f0 1162 switch (imsg->hdr.type) {
0f7b5df9 1163 case IMSG_CTL_SHOW_LIB_BEGIN:
eac6e3f0 1164 rt = imsg->data;
0f7b5df9 1165
0f7b5df9
RW
1166 upstream = 0;
1167 downstream = 0;
1168 sent_buffer[0] = '\0';
1169 rcvd_buffer[0] = '\0';
eac6e3f0 1170 snprintf(dstnet, sizeof(dstnet), "%s/%d",
a5d10512 1171 log_addr(rt->af, &rt->prefix), rt->prefixlen);
0f7b5df9
RW
1172 break;
1173 case IMSG_CTL_SHOW_LIB_SENT:
f0722791
RW
1174 rt = imsg->data;
1175
0f7b5df9
RW
1176 upstream = 1;
1177 buflen = strlen(sent_buffer);
903a7226
MS
1178 snprintfrr(sent_buffer + buflen, LDPBUFSIZ - buflen,
1179 "%12s%pI4:0\n", "", &rt->nexthop);
0f7b5df9
RW
1180 break;
1181 case IMSG_CTL_SHOW_LIB_RCVD:
f0722791 1182 rt = imsg->data;
0f7b5df9
RW
1183 downstream = 1;
1184 buflen = strlen(rcvd_buffer);
903a7226
MS
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)" : "");
0f7b5df9
RW
1189 break;
1190 case IMSG_CTL_SHOW_LIB_END:
f0722791
RW
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));
0f7b5df9 1199 if (upstream) {
5c7571d4 1200 vty_out (vty, "%-8sAdvertised to:\n", "");
0f7b5df9 1201 vty_out(vty, "%s", sent_buffer);
a5d10512 1202 }
0f7b5df9 1203 if (downstream) {
5c7571d4 1204 vty_out (vty, "%-8sRemote bindings:\n", "");
0f7b5df9
RW
1205 vty_out(vty, "%s", rcvd_buffer);
1206 } else
5c7571d4 1207 vty_out (vty, "%-8sNo remote bindings\n","");
eac6e3f0
RW
1208 break;
1209 case IMSG_CTL_END:
6d3c2ed4 1210 vty_out (vty, "\n");
eac6e3f0
RW
1211 return (1);
1212 default:
1213 break;
1214 }
1215
1216 return (0);
1217}
1218
1219static int
a5d10512
RW
1220show_lib_msg_json(struct imsg *imsg, struct show_params *params,
1221 json_object *json)
bc0eb287
RW
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) {
0f7b5df9
RW
1229 case IMSG_CTL_SHOW_LIB_BEGIN:
1230 case IMSG_CTL_SHOW_LIB_RCVD:
bc0eb287
RW
1231 rt = imsg->data;
1232
0f7b5df9
RW
1233 if (imsg->hdr.type == IMSG_CTL_SHOW_LIB_BEGIN &&
1234 !rt->no_downstream)
bc0eb287
RW
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);
19fee2b7
DA
1249 json_object_string_addf(json_lib_entry, "neighborId", "%pI4",
1250 &rt->nexthop);
bc0eb287 1251 json_object_string_add(json_lib_entry, "localLabel",
903a7226 1252 log_label(rt->local_label));
bc0eb287 1253 json_object_string_add(json_lib_entry, "remoteLabel",
903a7226 1254 log_label(rt->remote_label));
bc0eb287
RW
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
1268static int
1269show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
1270 json_object *json)
a5d10512 1271{
f790d62a 1272 struct ctl_rt *rt = NULL;
a5d10512 1273 char dstnet[BUFSIZ];
0f7b5df9
RW
1274 static json_object *json_lib_entry;
1275 static json_object *json_adv_labels;
1276 json_object *json_adv_label;
a5d10512
RW
1277 static json_object *json_remote_labels;
1278 json_object *json_remote_label;
1279
1280 switch (imsg->hdr.type) {
0f7b5df9 1281 case IMSG_CTL_SHOW_LIB_BEGIN:
a5d10512 1282 rt = imsg->data;
a5d10512
RW
1283
1284 snprintf(dstnet, sizeof(dstnet), "%s/%d",
1285 log_addr(rt->af, &rt->prefix), rt->prefixlen);
1286
0f7b5df9
RW
1287 json_lib_entry = json_object_new_object();
1288 json_object_string_add(json_lib_entry, "localLabel",
1289 log_label(rt->local_label));
a5d10512 1290
0f7b5df9
RW
1291 json_adv_labels = json_object_new_array();
1292 json_object_object_add(json_lib_entry, "advertisedTo",
1293 json_adv_labels);
a5d10512 1294
0f7b5df9
RW
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:
f0722791
RW
1302 rt = imsg->data;
1303
0f7b5df9 1304 json_adv_label = json_object_new_object();
19fee2b7
DA
1305 json_object_string_addf(json_adv_label, "neighborId", "%pI4",
1306 &rt->nexthop);
0f7b5df9
RW
1307 json_object_array_add(json_adv_labels, json_adv_label);
1308 break;
1309 case IMSG_CTL_SHOW_LIB_RCVD:
f0722791
RW
1310 rt = imsg->data;
1311
0f7b5df9 1312 json_remote_label = json_object_new_object();
19fee2b7
DA
1313 json_object_string_addf(json_remote_label, "neighborId", "%pI4",
1314 &rt->nexthop);
0f7b5df9 1315 json_object_string_add(json_remote_label, "label",
903a7226 1316 log_label(rt->remote_label));
0f7b5df9
RW
1317 json_object_int_add(json_remote_label, "inUse", rt->in_use);
1318 json_object_array_add(json_remote_labels, json_remote_label);
a5d10512
RW
1319 break;
1320 case IMSG_CTL_END:
1321 return (1);
1322 default:
1323 break;
1324 }
1325
1326 return (0);
1327}
1328
1329static int
1330show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg,
1331 struct show_params *params)
eac6e3f0
RW
1332{
1333 struct ctl_pw *pw;
1334
1335 switch (imsg->hdr.type) {
1336 case IMSG_CTL_SHOW_L2VPN_BINDING:
1337 pw = imsg->data;
1338
903a7226
MS
1339 vty_out (vty, " Destination Address: %pI4, VC ID: %u\n",
1340 &pw->lsr_id, pw->pwid);
eac6e3f0
RW
1341
1342 /* local binding */
1343 if (pw->local_label != NO_LABEL) {
5c7571d4 1344 vty_out (vty, " Local Label: %u\n",
96ade3ed 1345 pw->local_label);
3efd0893 1346 vty_out (vty, "%-8sCbit: %u, VC Type: %s, GroupID: %u\n", "", pw->local_cword,
96ade3ed 1347 pw_type_name(pw->type),pw->local_gid);
5c7571d4 1348 vty_out (vty, "%-8sMTU: %u\n", "",pw->local_ifmtu);
6bbdd9e9 1349 vty_out (vty, "%-8sLast failure: %s\n", "",
1350 pw_error_code(pw->reason));
eac6e3f0 1351 } else
5c7571d4 1352 vty_out (vty," Local Label: unassigned\n");
eac6e3f0
RW
1353
1354 /* remote binding */
1355 if (pw->remote_label != NO_LABEL) {
5c7571d4 1356 vty_out (vty, " Remote Label: %u\n",
96ade3ed 1357 pw->remote_label);
3efd0893 1358 vty_out (vty, "%-8sCbit: %u, VC Type: %s, GroupID: %u\n", "", pw->remote_cword,
96ade3ed 1359 pw_type_name(pw->type),pw->remote_gid);
5c7571d4 1360 vty_out (vty, "%-8sMTU: %u\n", "",pw->remote_ifmtu);
eac6e3f0 1361 } else
5c7571d4 1362 vty_out (vty," Remote Label: unassigned\n");
eac6e3f0
RW
1363 break;
1364 case IMSG_CTL_END:
6d3c2ed4 1365 vty_out (vty, "\n");
eac6e3f0
RW
1366 return (1);
1367 default:
1368 break;
1369 }
1370
1371 return (0);
1372}
1373
1374static int
a5d10512
RW
1375show_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();
19fee2b7
DA
1387 json_object_string_addf(json_pw, "destination", "%pI4",
1388 &pw->lsr_id);
a5d10512
RW
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);
6bbdd9e9 1403 json_object_string_add(json_pw, "lastFailureReason",
1404 pw_error_code(pw->reason));
a5d10512
RW
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
903a7226
MS
1425 snprintfrr(key_name, sizeof(key_name), "%pI4: %u",
1426 &pw->lsr_id, pw->pwid);
a5d10512
RW
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
1438static int
1439show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
eac6e3f0
RW
1440{
1441 struct ctl_pw *pw;
1442
1443 switch (imsg->hdr.type) {
1444 case IMSG_CTL_SHOW_L2VPN_PW:
1445 pw = imsg->data;
1446
903a7226
MS
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"));
eac6e3f0
RW
1450 break;
1451 case IMSG_CTL_END:
6d3c2ed4 1452 vty_out (vty, "\n");
eac6e3f0
RW
1453 return (1);
1454 default:
1455 break;
1456 }
1457
1458 return (0);
1459}
1460
a5d10512
RW
1461static int
1462show_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();
19fee2b7 1473 json_object_string_addf(json_pw, "peerId", "%pI4", &pw->lsr_id);
a5d10512 1474 json_object_int_add(json_pw, "vcId", pw->pwid);
77a2f8e5
DA
1475#if CONFDATE > 20230131
1476CPP_NOTICE("Remove JSON object commands with keys starting with capital")
1477#endif
a5d10512 1478 json_object_string_add(json_pw, "VpnName", pw->l2vpn_name);
77a2f8e5 1479 json_object_string_add(json_pw, "vpnName", pw->l2vpn_name);
fd563cc7 1480 if (pw->status == PW_FORWARDING)
a5d10512
RW
1481 json_object_string_add(json_pw, "status", "up");
1482 else
1483 json_object_string_add(json_pw, "status", "down");
1484 json_object_object_add(json, pw->ifname, json_pw);
1485 break;
1486 case IMSG_CTL_END:
1487 return (1);
1488 default:
1489 break;
1490 }
1491
1492 return (0);
1493}
1494
eac6e3f0
RW
1495static int
1496ldp_vty_connect(struct imsgbuf *ibuf)
1497{
1498 struct sockaddr_un s_un;
1499 int ctl_sock;
1500
1501 /* connect to ldpd control socket */
1502 if ((ctl_sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
1503 log_warn("%s: socket", __func__);
1504 return (-1);
1505 }
1506
1507 memset(&s_un, 0, sizeof(s_un));
1508 s_un.sun_family = AF_UNIX;
372b8bd3 1509 strlcpy(s_un.sun_path, ctl_sock_path, sizeof(s_un.sun_path));
eac6e3f0 1510 if (connect(ctl_sock, (struct sockaddr *)&s_un, sizeof(s_un)) == -1) {
372b8bd3 1511 log_warn("%s: connect: %s", __func__, ctl_sock_path);
eac6e3f0
RW
1512 close(ctl_sock);
1513 return (-1);
1514 }
1515
1516 imsg_init(ibuf, ctl_sock);
1517
1518 return (0);
1519}
1520
a5d10512 1521static int
f0722791 1522ldp_vty_dispatch_iface(struct vty *vty, struct imsg *imsg,
a5d10512
RW
1523 struct show_params *params, json_object *json)
1524{
bc0eb287
RW
1525 int ret;
1526
f0722791
RW
1527 if (params->json)
1528 ret = show_interface_msg_json(imsg, params, json);
1529 else
1530 ret = show_interface_msg(vty, imsg, params);
1531
1532 return (ret);
1533}
1534
e1894ff7
KS
1535static int
1536ldp_vty_dispatch_ldp_sync(struct vty *vty, struct imsg *imsg,
1537 struct show_params *params, json_object *json)
1538{
1539 int ret;
1540
1541 if (params->json)
1542 ret = show_ldp_sync_msg_json(imsg, params, json);
1543 else
1544 ret = show_ldp_sync_msg(vty, imsg, params);
1545
1546 return (ret);
1547}
1548
f0722791
RW
1549static int
1550ldp_vty_dispatch_disc(struct vty *vty, struct imsg *imsg,
1551 struct show_params *params, json_object *json)
1552{
1553 int ret;
1554
1555 if (params->detail) {
bc0eb287 1556 if (params->json)
f0722791
RW
1557 ret = show_discovery_detail_msg_json(imsg, params,
1558 json);
bc0eb287 1559 else
f0722791
RW
1560 ret = show_discovery_detail_msg(vty, imsg, params);
1561 } else {
1562 if (params->json)
1563 ret = show_discovery_msg_json(imsg, params, json);
1564 else
1565 ret = show_discovery_msg(vty, imsg, params);
1566 }
1567
1568 return (ret);
1569}
1570
1571static int
1572ldp_vty_dispatch_nbr(struct vty *vty, struct imsg *imsg,
1573 struct show_params *params, json_object *json)
1574{
1575 static bool filtered = false;
1576 struct ctl_nbr *nbr;
1577 int ret;
1578
1579 switch (imsg->hdr.type) {
1580 case IMSG_CTL_SHOW_NBR:
1581 filtered = false;
1582 nbr = imsg->data;
1583
1584 if (params->neighbor.lsr_id.s_addr != INADDR_ANY &&
1585 params->neighbor.lsr_id.s_addr != nbr->id.s_addr) {
1586 filtered = true;
1587 return (0);
bc0eb287
RW
1588 }
1589 break;
f0722791
RW
1590 case IMSG_CTL_SHOW_NBR_DISC:
1591 case IMSG_CTL_SHOW_NBR_END:
1592 if (filtered)
1593 return (0);
bc0eb287 1594 break;
f0722791 1595 default:
bc0eb287 1596 break;
f0722791
RW
1597 }
1598
1599 if (params->neighbor.capabilities) {
bc0eb287 1600 if (params->json)
f0722791
RW
1601 ret = show_nbr_capabilities_msg_json(imsg, params,
1602 json);
bc0eb287 1603 else
f0722791
RW
1604 ret = show_nbr_capabilities_msg(vty, imsg, params);
1605 } else if (params->detail) {
1606 if (params->json)
1607 ret = show_nbr_detail_msg_json(imsg, params, json);
1608 else
1609 ret = show_nbr_detail_msg(vty, imsg, params);
1610 } else {
1611 if (params->json)
1612 ret = show_nbr_msg_json(imsg, params, json);
1613 else
1614 ret = show_nbr_msg(vty, imsg, params);
1615 }
1616
1617 return (ret);
1618}
1619
1620static int
1621ldp_vty_dispatch_lib(struct vty *vty, struct imsg *imsg,
1622 struct show_params *params, json_object *json)
1623{
1624 static bool filtered = false;
7f677840 1625 struct ctl_rt *rt = NULL;
f0722791
RW
1626 struct prefix prefix;
1627 int ret;
1628
1629 switch (imsg->hdr.type) {
1630 case IMSG_CTL_SHOW_LIB_BEGIN:
1631 filtered = false;
bc0eb287 1632 break;
f0722791
RW
1633 case IMSG_CTL_SHOW_LIB_SENT:
1634 case IMSG_CTL_SHOW_LIB_RCVD:
1635 case IMSG_CTL_SHOW_LIB_END:
1636 if (filtered)
1637 return (0);
1638 break;
1639 default:
1640 break;
1641 }
1642
1643 switch (imsg->hdr.type) {
1644 case IMSG_CTL_SHOW_LIB_BEGIN:
1645 case IMSG_CTL_SHOW_LIB_SENT:
1646 case IMSG_CTL_SHOW_LIB_RCVD:
1647 case IMSG_CTL_SHOW_LIB_END:
1648 rt = imsg->data;
1649
1650 if (params->family != AF_UNSPEC && params->family != rt->af) {
1651 filtered = true;
1652 return (0);
1653 }
1654
1655 prefix.family = rt->af;
1656 prefix.prefixlen = rt->prefixlen;
1657 memcpy(&prefix.u.val, &rt->prefix, sizeof(prefix.u.val));
1658 if (params->lib.prefix.family != AF_UNSPEC) {
1659 if (!params->lib.longer_prefixes &&
1660 !prefix_same(&params->lib.prefix, &prefix)) {
1661 filtered = true;
1662 return (0);
1663 } else if (params->lib.longer_prefixes &&
1664 !prefix_match(&params->lib.prefix, &prefix)) {
1665 filtered = true;
1666 return (0);
1667 }
1668 }
1669
1670 if (params->lib.local_label != NO_LABEL &&
1671 params->lib.local_label != rt->local_label) {
1672 filtered = true;
1673 return (0);
1674 }
1675 break;
1676 default:
1677 break;
1678 }
1679
1680 switch (imsg->hdr.type) {
1681 case IMSG_CTL_SHOW_LIB_SENT:
1682 case IMSG_CTL_SHOW_LIB_RCVD:
1683 if (params->lib.neighbor.s_addr != INADDR_ANY &&
1684 params->lib.neighbor.s_addr != rt->nexthop.s_addr)
1685 return (0);
1686 break;
1687 default:
1688 break;
1689 }
1690
1691 switch (imsg->hdr.type) {
1692 case IMSG_CTL_SHOW_LIB_RCVD:
1693 if (params->lib.remote_label != NO_LABEL &&
1694 params->lib.remote_label != rt->remote_label)
1695 return (0);
1696 break;
1697 default:
1698 break;
1699 }
1700
1701 if (params->detail) {
bc0eb287 1702 if (params->json)
f0722791 1703 ret = show_lib_detail_msg_json(imsg, params, json);
bc0eb287 1704 else
f0722791
RW
1705 ret = show_lib_detail_msg(vty, imsg, params);
1706 } else {
1707 if (params->json)
1708 ret = show_lib_msg_json(imsg, params, json);
1709 else
1710 ret = show_lib_msg(vty, imsg, params);
1711 }
1712
1713 return (ret);
1714}
1715
1716static int
1717ldp_vty_dispatch_l2vpn_pw(struct vty *vty, struct imsg *imsg,
1718 struct show_params *params, json_object *json)
1719{
1720 struct ctl_pw *pw;
1721 int ret;
1722
1723 switch (imsg->hdr.type) {
1724 case IMSG_CTL_SHOW_L2VPN_PW:
1725 pw = imsg->data;
1726 if (params->l2vpn.peer.s_addr != INADDR_ANY &&
1727 params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
1728 return (0);
1729 if (params->l2vpn.ifname[0] != '\0' &&
1730 strcmp(params->l2vpn.ifname, pw->ifname))
1731 return (0);
1732 if (params->l2vpn.vcid && params->l2vpn.vcid != pw->pwid)
1733 return (0);
bc0eb287 1734 break;
a5d10512 1735 default:
f0722791 1736 break;
a5d10512 1737 }
bc0eb287 1738
f0722791
RW
1739 if (params->json)
1740 ret = show_l2vpn_pw_msg_json(imsg, params, json);
1741 else
1742 ret = show_l2vpn_pw_msg(vty, imsg, params);
1743
bc0eb287 1744 return (ret);
a5d10512
RW
1745}
1746
f0722791
RW
1747static int
1748ldp_vty_dispatch_l2vpn_binding(struct vty *vty, struct imsg *imsg,
1749 struct show_params *params, json_object *json)
1750{
1751 struct ctl_pw *pw;
1752 int ret;
1753
1754 switch (imsg->hdr.type) {
1755 case IMSG_CTL_SHOW_L2VPN_BINDING:
1756 pw = imsg->data;
1757 if (params->l2vpn.peer.s_addr != INADDR_ANY &&
1758 params->l2vpn.peer.s_addr != pw->lsr_id.s_addr)
1759 return (0);
1760 if (params->l2vpn.local_label != NO_LABEL &&
1761 params->l2vpn.local_label != pw->local_label)
1762 return (0);
1763 if (params->l2vpn.remote_label != NO_LABEL &&
1764 params->l2vpn.remote_label != pw->remote_label)
1765 return (0);
1766 break;
1767 default:
1768 break;
1769 }
1770
1771 if (params->json)
1772 ret = show_l2vpn_binding_msg_json(imsg, params, json);
1773 else
1774 ret = show_l2vpn_binding_msg(vty, imsg, params);
1775
1776 return (ret);
1777}
1778
1779static int
1780ldp_vty_dispatch_msg(struct vty *vty, struct imsg *imsg, enum show_command cmd,
1781 struct show_params *params, json_object *json)
1782{
1783 switch (cmd) {
1784 case SHOW_IFACE:
1785 return (ldp_vty_dispatch_iface(vty, imsg, params, json));
1786 case SHOW_DISC:
1787 return (ldp_vty_dispatch_disc(vty, imsg, params, json));
1788 case SHOW_NBR:
1789 return (ldp_vty_dispatch_nbr(vty, imsg, params, json));
1790 case SHOW_LIB:
1791 return (ldp_vty_dispatch_lib(vty, imsg, params, json));
1792 case SHOW_L2VPN_PW:
1793 return (ldp_vty_dispatch_l2vpn_pw(vty, imsg, params, json));
1794 case SHOW_L2VPN_BINDING:
1795 return (ldp_vty_dispatch_l2vpn_binding(vty, imsg, params,
1796 json));
e1894ff7
KS
1797 case SHOW_LDP_SYNC:
1798 return (ldp_vty_dispatch_ldp_sync(vty, imsg, params, json));
f0722791
RW
1799 default:
1800 return (0);
1801 }
1802}
1803
eac6e3f0
RW
1804static int
1805ldp_vty_dispatch(struct vty *vty, struct imsgbuf *ibuf, enum show_command cmd,
a5d10512 1806 struct show_params *params)
eac6e3f0
RW
1807{
1808 struct imsg imsg;
a5d10512
RW
1809 int n, done = 0, ret = CMD_SUCCESS;
1810 json_object *json = NULL;
eac6e3f0
RW
1811
1812 while (ibuf->w.queued)
1813 if (msgbuf_write(&ibuf->w) <= 0 && errno != EAGAIN) {
1814 log_warn("write error");
1815 close(ibuf->fd);
1816 return (CMD_WARNING);
1817 }
1818
a5d10512
RW
1819 if (params->json)
1820 json = json_object_new_object();
e8dbef04 1821
eac6e3f0
RW
1822 while (!done) {
1823 if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) {
1824 log_warnx("imsg_read error");
a5d10512
RW
1825 ret = CMD_WARNING;
1826 goto done;
eac6e3f0
RW
1827 }
1828 if (n == 0) {
1829 log_warnx("pipe closed");
a5d10512
RW
1830 ret = CMD_WARNING;
1831 goto done;
eac6e3f0
RW
1832 }
1833
1834 while (!done) {
1835 if ((n = imsg_get(ibuf, &imsg)) == -1) {
1836 log_warnx("imsg_get error");
a5d10512
RW
1837 ret = CMD_WARNING;
1838 goto done;
eac6e3f0
RW
1839 }
1840 if (n == 0)
1841 break;
a5d10512
RW
1842 done = ldp_vty_dispatch_msg(vty, &imsg, cmd, params,
1843 json);
eac6e3f0
RW
1844 imsg_free(&imsg);
1845 }
1846 }
1847
a5d10512 1848 done:
eac6e3f0 1849 close(ibuf->fd);
a5d10512 1850 if (json) {
038c0a8f 1851 vty_json(vty, json);
a5d10512 1852 }
eac6e3f0 1853
a5d10512 1854 return (ret);
eac6e3f0
RW
1855}
1856
1857static int
1858ldp_vty_get_af(const char *str, int *af)
1859{
1860 if (str == NULL) {
1861 *af = AF_UNSPEC;
1862 return (0);
1863 } else if (strcmp(str, "ipv4") == 0) {
1864 *af = AF_INET;
1865 return (0);
1866 } else if (strcmp(str, "ipv6") == 0) {
1867 *af = AF_INET6;
1868 return (0);
1869 }
1870
1871 return (-1);
1872}
1873
1874int
f0722791
RW
1875ldp_vty_show_binding(struct vty *vty, const char *af_str, const char *prefix,
1876 int longer_prefixes, const char *neighbor, unsigned long local_label,
1877 unsigned long remote_label, const char *detail, const char *json)
eac6e3f0
RW
1878{
1879 struct imsgbuf ibuf;
a5d10512 1880 struct show_params params;
eac6e3f0
RW
1881 int af;
1882
1883 if (ldp_vty_connect(&ibuf) < 0)
1884 return (CMD_WARNING);
1885
eac6e3f0
RW
1886 if (ldp_vty_get_af(af_str, &af) < 0)
1887 return (CMD_ERR_NO_MATCH);
1888
a5d10512
RW
1889 memset(&params, 0, sizeof(params));
1890 params.family = af;
1224e5c4
RW
1891 params.detail = (detail) ? 1 : 0;
1892 params.json = (json) ? 1 : 0;
f0722791
RW
1893 if (prefix) {
1894 (void)str2prefix(prefix, &params.lib.prefix);
1895 params.lib.longer_prefixes = longer_prefixes;
1896 }
1897 if (neighbor &&
1898 (inet_pton(AF_INET, neighbor, &params.lib.neighbor) != 1 ||
1899 bad_addr_v4(params.lib.neighbor))) {
1900 vty_out (vty, "%% Malformed address\n");
1901 return (CMD_SUCCESS);
1902 }
1903 params.lib.local_label = local_label;
1904 params.lib.remote_label = remote_label;
eac6e3f0 1905
bc0eb287 1906 if (!params.detail && !params.json)
5c7571d4 1907 vty_out (vty, "%-4s %-20s %-15s %-11s %-13s %6s\n", "AF",
bc0eb287 1908 "Destination", "Nexthop", "Local Label", "Remote Label",
96ade3ed 1909 "In Use");
bc0eb287 1910
a5d10512
RW
1911 imsg_compose(&ibuf, IMSG_CTL_SHOW_LIB, 0, 0, -1, NULL, 0);
1912 return (ldp_vty_dispatch(vty, &ibuf, SHOW_LIB, &params));
eac6e3f0
RW
1913}
1914
1915int
1224e5c4
RW
1916ldp_vty_show_discovery(struct vty *vty, const char *af_str, const char *detail,
1917 const char *json)
eac6e3f0
RW
1918{
1919 struct imsgbuf ibuf;
a5d10512 1920 struct show_params params;
eac6e3f0
RW
1921 int af;
1922
1923 if (ldp_vty_connect(&ibuf) < 0)
1924 return (CMD_WARNING);
1925
eac6e3f0
RW
1926 if (ldp_vty_get_af(af_str, &af) < 0)
1927 return (CMD_ERR_NO_MATCH);
1928
a5d10512
RW
1929 memset(&params, 0, sizeof(params));
1930 params.family = af;
1224e5c4
RW
1931 params.detail = (detail) ? 1 : 0;
1932 params.json = (json) ? 1 : 0;
eac6e3f0 1933
bc0eb287 1934 if (!params.detail && !params.json)
5c7571d4 1935 vty_out (vty, "%-4s %-15s %-8s %-15s %9s\n",
96ade3ed 1936 "AF", "ID", "Type", "Source", "Holdtime");
bc0eb287
RW
1937
1938 if (params.detail)
1939 imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY_DTL, 0, 0, -1,
1940 NULL, 0);
1941 else
1942 imsg_compose(&ibuf, IMSG_CTL_SHOW_DISCOVERY, 0, 0, -1, NULL, 0);
a5d10512 1943 return (ldp_vty_dispatch(vty, &ibuf, SHOW_DISC, &params));
eac6e3f0
RW
1944}
1945
1946int
1224e5c4 1947ldp_vty_show_interface(struct vty *vty, const char *af_str, const char *json)
eac6e3f0
RW
1948{
1949 struct imsgbuf ibuf;
a5d10512 1950 struct show_params params;
eac6e3f0 1951 unsigned int ifidx = 0;
eac6e3f0
RW
1952 int af;
1953
1954 if (ldp_vty_connect(&ibuf) < 0)
1955 return (CMD_WARNING);
1956
eac6e3f0
RW
1957 if (ldp_vty_get_af(af_str, &af) < 0)
1958 return (CMD_ERR_NO_MATCH);
1959
a5d10512
RW
1960 memset(&params, 0, sizeof(params));
1961 params.family = af;
1224e5c4 1962 params.json = (json) ? 1 : 0;
eac6e3f0
RW
1963
1964 /* header */
a5d10512 1965 if (!params.json) {
5c7571d4 1966 vty_out (vty, "%-4s %-11s %-6s %-8s %-12s %3s\n", "AF",
96ade3ed 1967 "Interface", "State", "Uptime", "Hello Timers","ac");
a5d10512 1968 }
eac6e3f0 1969
a5d10512
RW
1970 imsg_compose(&ibuf, IMSG_CTL_SHOW_INTERFACE, 0, 0, -1, &ifidx,
1971 sizeof(ifidx));
1972 return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &params));
eac6e3f0
RW
1973}
1974
99cfc17f 1975int
1224e5c4 1976ldp_vty_show_capabilities(struct vty *vty, const char *json)
99cfc17f 1977{
c740f7d3 1978 if (json) {
99cfc17f
RW
1979 json_object *json;
1980 json_object *json_array;
1981 json_object *json_cap;
1982
1983 json = json_object_new_object();
1984 json_array = json_object_new_array();
1985 json_object_object_add(json, "capabilities", json_array);
1986
1987 /* Dynamic Announcement (0x0506) */
1988 json_cap = json_object_new_object();
1989 json_object_string_add(json_cap, "description",
1990 "Dynamic Announcement");
1991 json_object_string_add(json_cap, "tlvType",
1992 "0x0506");
1993 json_object_array_add(json_array, json_cap);
1994
1995 /* Typed Wildcard (0x050B) */
1996 json_cap = json_object_new_object();
1997 json_object_string_add(json_cap, "description",
1998 "Typed Wildcard");
1999 json_object_string_add(json_cap, "tlvType",
2000 "0x050B");
2001 json_object_array_add(json_array, json_cap);
2002
2003 /* Unrecognized Notification (0x0603) */
2004 json_cap = json_object_new_object();
2005 json_object_string_add(json_cap, "description",
2006 "Unrecognized Notification");
2007 json_object_string_add(json_cap, "tlvType",
2008 "0x0603");
2009 json_object_array_add(json_array, json_cap);
2010
038c0a8f 2011 vty_json(vty, json);
99cfc17f
RW
2012 return (0);
2013 }
2014
181039f3 2015 vty_out (vty,
625e016d
DL
2016 "Supported LDP Capabilities\n"
2017 " * Dynamic Announcement (0x0506)\n"
2018 " * Typed Wildcard (0x050B)\n"
2019 " * Unrecognized Notification (0x0603)\n\n");
99cfc17f
RW
2020
2021 return (0);
2022}
2023
eac6e3f0 2024int
f0722791
RW
2025ldp_vty_show_neighbor(struct vty *vty, const char *lsr_id, int capabilities,
2026 const char *detail, const char *json)
eac6e3f0
RW
2027{
2028 struct imsgbuf ibuf;
a5d10512 2029 struct show_params params;
eac6e3f0
RW
2030
2031 if (ldp_vty_connect(&ibuf) < 0)
2032 return (CMD_WARNING);
2033
a5d10512 2034 memset(&params, 0, sizeof(params));
1224e5c4
RW
2035 params.detail = (detail) ? 1 : 0;
2036 params.json = (json) ? 1 : 0;
f0722791
RW
2037 params.neighbor.capabilities = capabilities;
2038 if (lsr_id &&
2039 (inet_pton(AF_INET, lsr_id, &params.neighbor.lsr_id) != 1 ||
2040 bad_addr_v4(params.neighbor.lsr_id))) {
2041 vty_out (vty, "%% Malformed address\n");
2042 return (CMD_SUCCESS);
2043 }
eac6e3f0 2044
f0722791 2045 if (params.neighbor.capabilities)
99cfc17f
RW
2046 params.detail = 1;
2047
bc0eb287 2048 if (!params.detail && !params.json)
5c7571d4 2049 vty_out (vty, "%-4s %-15s %-11s %-15s %8s\n",
96ade3ed 2050 "AF", "ID", "State", "Remote Address","Uptime");
bc0eb287 2051
a5d10512
RW
2052 imsg_compose(&ibuf, IMSG_CTL_SHOW_NBR, 0, 0, -1, NULL, 0);
2053 return (ldp_vty_dispatch(vty, &ibuf, SHOW_NBR, &params));
eac6e3f0
RW
2054}
2055
e1894ff7
KS
2056int
2057ldp_vty_show_ldp_sync(struct vty *vty, const char *json)
2058{
2059 struct imsgbuf ibuf;
2060 struct show_params params;
2061
2062 if (ldp_vty_connect(&ibuf) < 0)
2063 return (CMD_WARNING);
2064
2065 memset(&params, 0, sizeof(params));
2066 params.json = (json) ? 1 : 0;
2067
2068 imsg_compose(&ibuf, IMSG_CTL_SHOW_LDP_SYNC, 0, 0, -1, NULL, 0);
2069 return (ldp_vty_dispatch(vty, &ibuf, SHOW_LDP_SYNC, &params));
2070}
2071
eac6e3f0 2072int
f0722791
RW
2073ldp_vty_show_atom_binding(struct vty *vty, const char *peer,
2074 unsigned long local_label, unsigned long remote_label, const char *json)
eac6e3f0
RW
2075{
2076 struct imsgbuf ibuf;
a5d10512 2077 struct show_params params;
eac6e3f0
RW
2078
2079 if (ldp_vty_connect(&ibuf) < 0)
2080 return (CMD_WARNING);
2081
a5d10512 2082 memset(&params, 0, sizeof(params));
1224e5c4 2083 params.json = (json) ? 1 : 0;
f0722791
RW
2084 if (peer &&
2085 (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
2086 bad_addr_v4(params.l2vpn.peer))) {
2087 vty_out (vty, "%% Malformed address\n");
2088 return (CMD_SUCCESS);
2089 }
2090 params.l2vpn.local_label = local_label;
2091 params.l2vpn.remote_label = remote_label;
eac6e3f0 2092
a5d10512
RW
2093 imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_BINDING, 0, 0, -1, NULL, 0);
2094 return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_BINDING, &params));
eac6e3f0
RW
2095}
2096
2097int
f0722791
RW
2098ldp_vty_show_atom_vc(struct vty *vty, const char *peer, const char *ifname,
2099 const char *vcid, const char *json)
eac6e3f0
RW
2100{
2101 struct imsgbuf ibuf;
a5d10512 2102 struct show_params params;
eac6e3f0
RW
2103
2104 if (ldp_vty_connect(&ibuf) < 0)
2105 return (CMD_WARNING);
2106
a5d10512 2107 memset(&params, 0, sizeof(params));
1224e5c4 2108 params.json = (json) ? 1 : 0;
f0722791
RW
2109 if (peer &&
2110 (inet_pton(AF_INET, peer, &params.l2vpn.peer) != 1 ||
2111 bad_addr_v4(params.l2vpn.peer))) {
2112 vty_out (vty, "%% Malformed address\n");
2113 return (CMD_SUCCESS);
2114 }
2115 if (ifname)
2116 strlcpy(params.l2vpn.ifname, ifname,
2117 sizeof(params.l2vpn.ifname));
2118 if (vcid)
2119 params.l2vpn.vcid = atoi(vcid);
a5d10512
RW
2120
2121 if (!params.json) {
2122 /* header */
5c7571d4 2123 vty_out (vty, "%-9s %-15s %-10s %-16s %-10s\n",
96ade3ed 2124 "Interface", "Peer ID", "VC ID", "Name","Status");
5c7571d4 2125 vty_out (vty, "%-9s %-15s %-10s %-16s %-10s\n",
a5d10512 2126 "---------", "---------------", "----------",
96ade3ed 2127 "----------------", "----------");
a5d10512 2128 }
eac6e3f0 2129
a5d10512
RW
2130 imsg_compose(&ibuf, IMSG_CTL_SHOW_L2VPN_PW, 0, 0, -1, NULL, 0);
2131 return (ldp_vty_dispatch(vty, &ibuf, SHOW_L2VPN_PW, &params));
eac6e3f0
RW
2132}
2133
2134int
c740f7d3 2135ldp_vty_clear_nbr(struct vty *vty, const char *addr_str)
eac6e3f0
RW
2136{
2137 struct imsgbuf ibuf;
eac6e3f0
RW
2138 struct ctl_nbr nbr;
2139
eac6e3f0
RW
2140 memset(&nbr, 0, sizeof(nbr));
2141 if (addr_str &&
2142 (ldp_get_address(addr_str, &nbr.af, &nbr.raddr) == -1 ||
2143 bad_addr(nbr.af, &nbr.raddr))) {
5c7571d4 2144 vty_out (vty, "%% Malformed address\n");
eac6e3f0
RW
2145 return (CMD_WARNING);
2146 }
2147
2148 if (ldp_vty_connect(&ibuf) < 0)
2149 return (CMD_WARNING);
2150
2151 imsg_compose(&ibuf, IMSG_CTL_CLEAR_NBR, 0, 0, -1, &nbr, sizeof(nbr));
2152
2153 while (ibuf.w.queued)
2154 if (msgbuf_write(&ibuf.w) <= 0 && errno != EAGAIN) {
2155 log_warn("write error");
2156 close(ibuf.fd);
2157 return (CMD_WARNING);
2158 }
2159
2160 close(ibuf.fd);
2161
2162 return (CMD_SUCCESS);
2163}