]> git.proxmox.com Git - mirror_frr.git/blob - ldpd/ldp_vty_conf.c
ldpd: adapt the code for Quagga
[mirror_frr.git] / ldpd / ldp_vty_conf.c
1 /*
2 * Copyright (C) 2016 by Open Source Routing.
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 #include "ldpd.h"
25 #include "ldpe.h"
26 #include "lde.h"
27 #include "log.h"
28
29 #include "command.h"
30 #include "vrf.h"
31 #include "if.h"
32 #include "vty.h"
33 #include "ldp_vty.h"
34
35 static int interface_config_write(struct vty *);
36 static void ldp_af_iface_config_write(struct vty *, int);
37 static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *,
38 struct ldpd_af_conf *);
39 static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
40 static int ldp_vty_get_af(struct vty *);
41 static int ldp_iface_is_configured(struct ldpd_conf *, const char *);
42 static int ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]);
43 static int ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]);
44
45 static char vty_ifname[IF_NAMESIZE];
46 static char vty_l2vpn_name[L2VPN_NAME_LEN];
47 static char vty_pw_ifname[IF_NAMESIZE];
48
49 static struct cmd_node interface_node =
50 {
51 INTERFACE_NODE,
52 "%s(config-if)# ",
53 1
54 };
55
56 struct cmd_node ldp_node =
57 {
58 LDP_NODE,
59 "%s(config-ldp)# ",
60 1,
61 };
62
63 struct cmd_node ldp_ipv4_node =
64 {
65 LDP_IPV4_NODE,
66 "%s(config-ldp-af)# ",
67 1,
68 };
69
70 struct cmd_node ldp_ipv6_node =
71 {
72 LDP_IPV6_NODE,
73 "%s(config-ldp-af)# ",
74 1,
75 };
76
77 struct cmd_node ldp_ipv4_iface_node =
78 {
79 LDP_IPV4_IFACE_NODE,
80 "%s(config-ldp-af-if)# ",
81 1,
82 };
83
84 struct cmd_node ldp_ipv6_iface_node =
85 {
86 LDP_IPV6_IFACE_NODE,
87 "%s(config-ldp-af-if)# ",
88 1,
89 };
90
91 struct cmd_node ldp_l2vpn_node =
92 {
93 LDP_L2VPN_NODE,
94 "%s(config-l2vpn)# ",
95 1,
96 };
97
98 struct cmd_node ldp_pseudowire_node =
99 {
100 LDP_PSEUDOWIRE_NODE,
101 "%s(config-l2vpn-pw)# ",
102 1,
103 };
104
105 int
106 ldp_get_address(const char *str, int *af, union ldpd_addr *addr)
107 {
108 memset(addr, 0, sizeof(*addr));
109
110 if (inet_pton(AF_INET, str, &addr->v4) == 1) {
111 *af = AF_INET;
112 return (0);
113 }
114
115 if (inet_pton(AF_INET6, str, &addr->v6) == 1) {
116 *af = AF_INET6;
117 return (0);
118 }
119
120 return (-1);
121 }
122
123 static int
124 interface_config_write(struct vty *vty)
125 {
126 struct listnode *node;
127 struct interface *ifp;
128 int write = 0;
129
130 for (ALL_LIST_ELEMENTS_RO(vrf_iflist (VRF_DEFAULT), node, ifp)) {
131 vty_out(vty, "!%s", VTY_NEWLINE);
132 vty_out(vty, "interface %s%s", ifp->name, VTY_NEWLINE);
133 if (ifp->desc)
134 vty_out(vty, " description %s%s", ifp->desc,
135 VTY_NEWLINE);
136
137 write++;
138 }
139
140 return (write);
141 }
142
143 static void
144 ldp_af_iface_config_write(struct vty *vty, int af)
145 {
146 struct iface *iface;
147 struct iface_af *ia;
148
149 LIST_FOREACH(iface, &ldpd_conf->iface_list, entry) {
150 ia = iface_af_get(iface, af);
151 if (!ia->enabled)
152 continue;
153
154 vty_out(vty, " !%s", VTY_NEWLINE);
155 vty_out(vty, " interface %s%s", iface->name, VTY_NEWLINE);
156
157 if (ia->hello_holdtime != LINK_DFLT_HOLDTIME &&
158 ia->hello_holdtime != 0)
159 vty_out(vty, " discovery hello holdtime %u%s",
160 ia->hello_holdtime, VTY_NEWLINE);
161 if (ia->hello_interval != DEFAULT_HELLO_INTERVAL &&
162 ia->hello_interval != 0)
163 vty_out(vty, " discovery hello interval %u%s",
164 ia->hello_interval, VTY_NEWLINE);
165 }
166 }
167
168 static void
169 ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
170 struct ldpd_af_conf *af_conf)
171 {
172 struct tnbr *tnbr;
173
174 if (!(af_conf->flags & F_LDPD_AF_ENABLED))
175 return;
176
177 vty_out(vty, " !%s", VTY_NEWLINE);
178 vty_out(vty, " address-family %s%s", af_name(af), VTY_NEWLINE);
179
180 if (af_conf->lhello_holdtime != LINK_DFLT_HOLDTIME &&
181 af_conf->lhello_holdtime != 0 )
182 vty_out(vty, " discovery hello holdtime %u%s",
183 af_conf->lhello_holdtime, VTY_NEWLINE);
184 if (af_conf->lhello_interval != DEFAULT_HELLO_INTERVAL &&
185 af_conf->lhello_interval != 0)
186 vty_out(vty, " discovery hello interval %u%s",
187 af_conf->lhello_interval, VTY_NEWLINE);
188
189 if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT)
190 vty_out(vty, " discovery targeted-hello accept%s",
191 VTY_NEWLINE);
192
193 if (af_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
194 af_conf->thello_holdtime != 0)
195 vty_out(vty, " discovery targeted-hello holdtime %u%s",
196 af_conf->thello_holdtime, VTY_NEWLINE);
197 if (af_conf->thello_interval != DEFAULT_HELLO_INTERVAL &&
198 af_conf->thello_interval != 0)
199 vty_out(vty, " discovery targeted-hello interval %u%s",
200 af_conf->thello_interval, VTY_NEWLINE);
201
202 if (ldp_addrisset(af, &af_conf->trans_addr))
203 vty_out(vty, " discovery transport-address %s%s",
204 log_addr(af, &af_conf->trans_addr), VTY_NEWLINE);
205 else
206 vty_out(vty, " ! Incomplete config, specify a discovery "
207 "transport-address%s", VTY_NEWLINE);
208
209 if (af_conf->flags & F_LDPD_AF_EXPNULL)
210 vty_out(vty, " label local advertise explicit-null%s",
211 VTY_NEWLINE);
212
213 if (af_conf->flags & F_LDPD_AF_NO_GTSM)
214 vty_out(vty, " ttl-security disable%s", VTY_NEWLINE);
215
216 if (af_conf->keepalive != DEFAULT_KEEPALIVE)
217 vty_out(vty, " session holdtime %u%s", af_conf->keepalive,
218 VTY_NEWLINE);
219
220 LIST_FOREACH(tnbr, &ldpd_conf->tnbr_list, entry) {
221 if (tnbr->af == af) {
222 vty_out(vty, " !%s", VTY_NEWLINE);
223 vty_out(vty, " neighbor %s targeted%s",
224 log_addr(tnbr->af, &tnbr->addr), VTY_NEWLINE);
225 }
226 }
227
228 ldp_af_iface_config_write(vty, af);
229
230 vty_out(vty, " !%s", VTY_NEWLINE);
231 }
232
233 int
234 ldp_config_write(struct vty *vty)
235 {
236 struct nbr_params *nbrp;
237
238 if (!(ldpd_conf->flags & F_LDPD_ENABLED))
239 return (0);
240
241 vty_out(vty, "mpls ldp%s", VTY_NEWLINE);
242
243 if (ldpd_conf->rtr_id.s_addr != 0)
244 vty_out(vty, " router-id %s%s",
245 inet_ntoa(ldpd_conf->rtr_id), VTY_NEWLINE);
246
247 if (ldpd_conf->lhello_holdtime != LINK_DFLT_HOLDTIME &&
248 ldpd_conf->lhello_holdtime != 0)
249 vty_out(vty, " discovery hello holdtime %u%s",
250 ldpd_conf->lhello_holdtime, VTY_NEWLINE);
251 if (ldpd_conf->lhello_interval != DEFAULT_HELLO_INTERVAL &&
252 ldpd_conf->lhello_interval != 0)
253 vty_out(vty, " discovery hello interval %u%s",
254 ldpd_conf->lhello_interval, VTY_NEWLINE);
255
256 if (ldpd_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
257 ldpd_conf->thello_holdtime != 0)
258 vty_out(vty, " discovery targeted-hello holdtime %u%s",
259 ldpd_conf->thello_holdtime, VTY_NEWLINE);
260 if (ldpd_conf->thello_interval != DEFAULT_HELLO_INTERVAL &&
261 ldpd_conf->thello_interval != 0)
262 vty_out(vty, " discovery targeted-hello interval %u%s",
263 ldpd_conf->thello_interval, VTY_NEWLINE);
264
265 if (ldpd_conf->trans_pref == DUAL_STACK_LDPOV4)
266 vty_out(vty, " dual-stack transport-connection prefer ipv4%s",
267 VTY_NEWLINE);
268
269 if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP)
270 vty_out(vty, " dual-stack cisco-interop%s", VTY_NEWLINE);
271
272 LIST_FOREACH(nbrp, &ldpd_conf->nbrp_list, entry) {
273 if (nbrp->flags & F_NBRP_KEEPALIVE)
274 vty_out(vty, " neighbor %s session holdtime %u%s",
275 inet_ntoa(nbrp->lsr_id), nbrp->keepalive,
276 VTY_NEWLINE);
277
278 if (nbrp->flags & F_NBRP_GTSM) {
279 if (nbrp->gtsm_enabled)
280 vty_out(vty, " neighbor %s ttl-security hops "
281 "%u%s", inet_ntoa(nbrp->lsr_id),
282 nbrp->gtsm_hops, VTY_NEWLINE);
283 else
284 vty_out(vty, " neighbor %s ttl-security "
285 "disable%s", inet_ntoa(nbrp->lsr_id),
286 VTY_NEWLINE);
287 }
288
289 if (nbrp->auth.method == AUTH_MD5SIG)
290 vty_out(vty, " neighbor %s password %s%s",
291 inet_ntoa(nbrp->lsr_id), nbrp->auth.md5key,
292 VTY_NEWLINE);
293 }
294
295 ldp_af_config_write(vty, AF_INET, ldpd_conf, &ldpd_conf->ipv4);
296 ldp_af_config_write(vty, AF_INET6, ldpd_conf, &ldpd_conf->ipv6);
297 vty_out(vty, " !%s", VTY_NEWLINE);
298 vty_out(vty, "!%s", VTY_NEWLINE);
299
300 return (1);
301 }
302
303 static void
304 ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw)
305 {
306 int missing_lsrid = 0;
307 int missing_pwid = 0;
308
309 vty_out(vty, " !%s", VTY_NEWLINE);
310 vty_out(vty, " member pseudowire %s%s", pw->ifname, VTY_NEWLINE);
311
312 if (pw->lsr_id.s_addr != INADDR_ANY)
313 vty_out(vty, " neighbor lsr-id %s%s", inet_ntoa(pw->lsr_id),
314 VTY_NEWLINE);
315 else
316 missing_lsrid = 1;
317
318 if (pw->flags & F_PW_STATIC_NBR_ADDR)
319 vty_out(vty, " neighbor address %s%s", log_addr(pw->af,
320 &pw->addr), VTY_NEWLINE);
321
322 if (pw->pwid != 0)
323 vty_out(vty, " pw-id %u%s", pw->pwid, VTY_NEWLINE);
324 else
325 missing_pwid = 1;
326
327 if (!(pw->flags & F_PW_CWORD_CONF))
328 vty_out(vty, " control-word exclude%s", VTY_NEWLINE);
329
330 if (!(pw->flags & F_PW_STATUSTLV_CONF))
331 vty_out(vty, " pw-status disable%s", VTY_NEWLINE);
332
333 if (missing_lsrid)
334 vty_out(vty, " ! Incomplete config, specify a neighbor "
335 "lsr-id%s", VTY_NEWLINE);
336 if (missing_pwid)
337 vty_out(vty, " ! Incomplete config, specify a pw-id%s",
338 VTY_NEWLINE);
339 }
340
341 int
342 ldp_l2vpn_config_write(struct vty *vty)
343 {
344 struct l2vpn *l2vpn;
345 struct l2vpn_if *lif;
346 struct l2vpn_pw *pw;
347
348 LIST_FOREACH(l2vpn, &ldpd_conf->l2vpn_list, entry) {
349 vty_out(vty, "l2vpn %s type vpls%s", l2vpn->name, VTY_NEWLINE);
350
351 if (l2vpn->pw_type != DEFAULT_PW_TYPE)
352 vty_out(vty, " vc type ethernet-tagged%s", VTY_NEWLINE);
353
354 if (l2vpn->mtu != DEFAULT_L2VPN_MTU)
355 vty_out(vty, " mtu %u%s", l2vpn->mtu, VTY_NEWLINE);
356
357 if (l2vpn->br_ifname[0] != '\0')
358 vty_out(vty, " bridge %s%s", l2vpn->br_ifname,
359 VTY_NEWLINE);
360
361 LIST_FOREACH(lif, &l2vpn->if_list, entry)
362 vty_out(vty, " member interface %s%s", lif->ifname,
363 VTY_NEWLINE);
364
365 LIST_FOREACH(pw, &l2vpn->pw_list, entry)
366 ldp_l2vpn_pw_config_write(vty, pw);
367 LIST_FOREACH(pw, &l2vpn->pw_inactive_list, entry)
368 ldp_l2vpn_pw_config_write(vty, pw);
369
370 vty_out(vty, " !%s", VTY_NEWLINE);
371 vty_out(vty, "!%s", VTY_NEWLINE);
372 }
373
374 return (0);
375 }
376
377 static int
378 ldp_vty_get_af(struct vty *vty)
379 {
380 switch (vty->node) {
381 case LDP_IPV4_NODE:
382 case LDP_IPV4_IFACE_NODE:
383 return (AF_INET);
384 case LDP_IPV6_NODE:
385 case LDP_IPV6_IFACE_NODE:
386 return (AF_INET6);
387 default:
388 fatalx("ldp_vty_get_af: unexpected node");
389 }
390 }
391
392 static int
393 ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
394 {
395 struct l2vpn *l2vpn;
396
397 if (if_lookup_name(xconf, ifname))
398 return (1);
399
400 LIST_FOREACH(l2vpn, &xconf->l2vpn_list, entry) {
401 if (l2vpn_if_find_name(l2vpn, ifname))
402 return (1);
403 if (l2vpn_pw_find_name(l2vpn, ifname))
404 return (1);
405 }
406
407 return (0);
408 }
409
410 int
411 ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
412 {
413 struct ldpd_conf *vty_conf;
414 int disable;
415
416 vty_conf = ldp_dup_config(ldpd_conf);
417
418 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
419
420 if (disable)
421 vty_conf->flags &= ~F_LDPD_ENABLED;
422 else {
423 vty->node = LDP_NODE;
424 vty_conf->flags |= F_LDPD_ENABLED;
425 }
426
427 ldp_reload(vty_conf);
428
429 return (CMD_SUCCESS);
430 }
431
432 int
433 ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
434 {
435 struct ldpd_conf *vty_conf;
436 struct ldpd_af_conf *af_conf;
437 int af;
438 const char *af_str;
439 int disable;
440
441 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
442 af_str = vty_get_arg_value(args, "address-family");
443
444 vty_conf = ldp_dup_config(ldpd_conf);
445 if (strcmp(af_str, "ipv4") == 0) {
446 af = AF_INET;
447 af_conf = &vty_conf->ipv4;
448 } else if (strcmp(af_str, "ipv6") == 0) {
449 af = AF_INET6;
450 af_conf = &vty_conf->ipv6;
451 } else
452 return (CMD_WARNING);
453
454 if (disable) {
455 af_conf->flags &= ~F_LDPD_AF_ENABLED;
456 ldp_reload(vty_conf);
457 return (CMD_SUCCESS);
458 }
459
460 switch (af) {
461 case AF_INET:
462 vty->node = LDP_IPV4_NODE;
463 break;
464 case AF_INET6:
465 vty->node = LDP_IPV6_NODE;
466 break;
467 default:
468 fatalx("ldp_vty_address_family: unknown af");
469 }
470 af_conf->flags |= F_LDPD_AF_ENABLED;
471
472 ldp_reload(vty_conf);
473
474 return (CMD_SUCCESS);
475 }
476
477 int
478 ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
479 {
480 struct ldpd_conf *vty_conf;
481 struct ldpd_af_conf *af_conf;
482 struct iface *iface;
483 struct iface_af *ia;
484 int af;
485 char *ep;
486 long int secs;
487 enum hello_type hello_type;
488 const char *seconds_str;
489 const char *hello_type_str;
490 int disable;
491
492 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
493 seconds_str = vty_get_arg_value(args, "seconds");
494 hello_type_str = vty_get_arg_value(args, "hello_type");
495
496 secs = strtol(seconds_str, &ep, 10);
497 if (*ep != '\0' || secs < MIN_HOLDTIME || secs > MAX_HOLDTIME) {
498 vty_out(vty, "%% Invalid holdtime%s", VTY_NEWLINE);
499 return (CMD_WARNING);
500 }
501
502 if (hello_type_str[0] == 'h')
503 hello_type = HELLO_LINK;
504 else
505 hello_type = HELLO_TARGETED;
506
507 vty_conf = ldp_dup_config(ldpd_conf);
508
509 switch (vty->node) {
510 case LDP_NODE:
511 if (disable) {
512 switch (hello_type) {
513 case HELLO_LINK:
514 vty_conf->lhello_holdtime = LINK_DFLT_HOLDTIME;
515 break;
516 case HELLO_TARGETED:
517 vty_conf->thello_holdtime =
518 TARGETED_DFLT_HOLDTIME;
519 break;
520 }
521 } else {
522 switch (hello_type) {
523 case HELLO_LINK:
524 vty_conf->lhello_holdtime = secs;
525 break;
526 case HELLO_TARGETED:
527 vty_conf->thello_holdtime = secs;
528 break;
529 }
530 }
531 break;
532 case LDP_IPV4_NODE:
533 case LDP_IPV6_NODE:
534 af = ldp_vty_get_af(vty);
535 af_conf = ldp_af_conf_get(vty_conf, af);
536
537 if (disable) {
538 switch (hello_type) {
539 case HELLO_LINK:
540 af_conf->lhello_holdtime = 0;
541 break;
542 case HELLO_TARGETED:
543 af_conf->thello_holdtime = 0;
544 break;
545 }
546 } else {
547 switch (hello_type) {
548 case HELLO_LINK:
549 af_conf->lhello_holdtime = secs;
550 break;
551 case HELLO_TARGETED:
552 af_conf->thello_holdtime = secs;
553 break;
554 }
555 }
556 break;
557 case LDP_IPV4_IFACE_NODE:
558 case LDP_IPV6_IFACE_NODE:
559 af = ldp_vty_get_af(vty);
560 iface = if_lookup_name(vty_conf, vty_ifname);
561 ia = iface_af_get(iface, af);
562
563 if (disable)
564 ia->hello_holdtime = 0;
565 else
566 ia->hello_holdtime = secs;
567 break;
568 default:
569 fatalx("ldp_vty_disc_holdtime: unexpected node");
570 }
571
572 ldp_reload(vty_conf);
573
574 return (CMD_SUCCESS);
575 }
576
577 int
578 ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
579 {
580 struct ldpd_conf *vty_conf;
581 struct ldpd_af_conf *af_conf;
582 struct iface *iface;
583 struct iface_af *ia;
584 int af;
585 char *ep;
586 long int secs;
587 enum hello_type hello_type;
588 const char *seconds_str;
589 const char *hello_type_str;
590 int disable;
591
592 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
593 seconds_str = vty_get_arg_value(args, "seconds");
594 hello_type_str = vty_get_arg_value(args, "hello_type");
595
596 secs = strtol(seconds_str, &ep, 10);
597 if (*ep != '\0' || secs < MIN_HELLO_INTERVAL ||
598 secs > MAX_HELLO_INTERVAL) {
599 vty_out(vty, "%% Invalid interval%s", VTY_NEWLINE);
600 return (CMD_WARNING);
601 }
602
603 if (hello_type_str[0] == 'h')
604 hello_type = HELLO_LINK;
605 else
606 hello_type = HELLO_TARGETED;
607
608 vty_conf = ldp_dup_config(ldpd_conf);
609
610 switch (vty->node) {
611 case LDP_NODE:
612 if (disable) {
613 switch (hello_type) {
614 case HELLO_LINK:
615 vty_conf->lhello_interval = LINK_DFLT_HOLDTIME;
616 break;
617 case HELLO_TARGETED:
618 vty_conf->thello_interval =
619 TARGETED_DFLT_HOLDTIME;
620 break;
621 }
622 } else {
623 switch (hello_type) {
624 case HELLO_LINK:
625 vty_conf->lhello_interval = secs;
626 break;
627 case HELLO_TARGETED:
628 vty_conf->thello_interval = secs;
629 break;
630 }
631 }
632 break;
633 case LDP_IPV4_NODE:
634 case LDP_IPV6_NODE:
635 af = ldp_vty_get_af(vty);
636 af_conf = ldp_af_conf_get(vty_conf, af);
637
638 if (disable) {
639 switch (hello_type) {
640 case HELLO_LINK:
641 af_conf->lhello_interval = 0;
642 break;
643 case HELLO_TARGETED:
644 af_conf->thello_interval = 0;
645 break;
646 }
647 } else {
648 switch (hello_type) {
649 case HELLO_LINK:
650 af_conf->lhello_interval = secs;
651 break;
652 case HELLO_TARGETED:
653 af_conf->thello_interval = secs;
654 break;
655 }
656 }
657 break;
658 case LDP_IPV4_IFACE_NODE:
659 case LDP_IPV6_IFACE_NODE:
660 af = ldp_vty_get_af(vty);
661 iface = if_lookup_name(vty_conf, vty_ifname);
662 ia = iface_af_get(iface, af);
663
664 if (disable)
665 ia->hello_interval = 0;
666 else
667 ia->hello_interval = secs;
668 break;
669 default:
670 fatalx("ldp_vty_disc_interval: unexpected node");
671 }
672
673 ldp_reload(vty_conf);
674
675 return (CMD_SUCCESS);
676 }
677
678 int
679 ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
680 {
681 struct ldpd_conf *vty_conf;
682 struct ldpd_af_conf *af_conf;
683 int af;
684 int disable;
685
686 vty_conf = ldp_dup_config(ldpd_conf);
687
688 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
689
690 af = ldp_vty_get_af(vty);
691 af_conf = ldp_af_conf_get(vty_conf, af);
692
693 if (disable)
694 af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
695 else
696 af_conf->flags |= F_LDPD_AF_THELLO_ACCEPT;
697
698 ldp_reload(vty_conf);
699
700 return (CMD_SUCCESS);
701 }
702
703 static int
704 ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
705 {
706 struct ldpd_conf *vty_conf;
707 char *ep;
708 long int secs;
709 struct in_addr lsr_id;
710 struct nbr_params *nbrp;
711 const char *seconds_str;
712 const char *lsr_id_str;
713 int disable;
714
715 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
716 seconds_str = vty_get_arg_value(args, "seconds");
717 lsr_id_str = vty_get_arg_value(args, "lsr_id");
718
719 if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
720 bad_addr_v4(lsr_id)) {
721 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
722 return (CMD_WARNING);
723 }
724
725 vty_conf = ldp_dup_config(ldpd_conf);
726 nbrp = nbr_params_find(vty_conf, lsr_id);
727
728 secs = strtol(seconds_str, &ep, 10);
729 if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
730 vty_out(vty, "%% Invalid holdtime%s", VTY_NEWLINE);
731 goto cancel;
732 }
733
734 if (disable) {
735 if (nbrp == NULL)
736 goto cancel;
737
738 nbrp->keepalive = 0;
739 nbrp->flags &= ~F_NBRP_KEEPALIVE;
740 } else {
741 if (nbrp == NULL) {
742 nbrp = nbr_params_new(lsr_id);
743 LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
744 } else if (nbrp->keepalive == secs)
745 goto cancel;
746
747 nbrp->keepalive = secs;
748 nbrp->flags |= F_NBRP_KEEPALIVE;
749 }
750
751 ldp_reload(vty_conf);
752
753 return (CMD_SUCCESS);
754
755 cancel:
756 ldp_clear_config(vty_conf);
757 return (CMD_SUCCESS);
758 }
759
760 static int
761 ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
762 {
763 struct ldpd_conf *vty_conf;
764 struct ldpd_af_conf *af_conf;
765 int af;
766 char *ep;
767 long int secs;
768 const char *seconds_str;
769 int disable;
770
771 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
772 seconds_str = vty_get_arg_value(args, "seconds");
773
774 secs = strtol(seconds_str, &ep, 10);
775 if (*ep != '\0' || secs < MIN_KEEPALIVE || secs > MAX_KEEPALIVE) {
776 vty_out(vty, "%% Invalid holdtime%s", VTY_NEWLINE);
777 return (CMD_SUCCESS);
778 }
779
780 vty_conf = ldp_dup_config(ldpd_conf);
781 af = ldp_vty_get_af(vty);
782 af_conf = ldp_af_conf_get(vty_conf, af);
783
784 if (disable)
785 af_conf->keepalive = DEFAULT_KEEPALIVE;
786 else
787 af_conf->keepalive = secs;
788
789 ldp_reload(vty_conf);
790
791 return (CMD_SUCCESS);
792 }
793
794 int
795 ldp_vty_session_holdtime(struct vty *vty, struct vty_arg *args[])
796 {
797 switch (vty->node) {
798 case LDP_NODE:
799 return (ldp_vty_nbr_session_holdtime(vty, args));
800 case LDP_IPV4_NODE:
801 case LDP_IPV6_NODE:
802 return (ldp_vty_af_session_holdtime(vty, args));
803 default:
804 fatalx("ldp_vty_session_holdtime: unexpected node");
805 }
806 }
807
808 int
809 ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
810 {
811 struct ldpd_conf *vty_conf;
812 int af;
813 struct iface *iface;
814 struct iface_af *ia;
815 struct interface *ifp;
816 struct kif kif;
817 const char *ifname;
818 int disable;
819
820 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
821 ifname = vty_get_arg_value(args, "ifname");
822
823 vty_conf = ldp_dup_config(ldpd_conf);
824 af = ldp_vty_get_af(vty);
825 iface = if_lookup_name(vty_conf, ifname);
826
827 if (disable) {
828 if (iface == NULL)
829 goto cancel;
830
831 ia = iface_af_get(iface, af);
832 if (ia->enabled == 0)
833 goto cancel;
834
835 ia->enabled = 0;
836 ldp_reload(vty_conf);
837 return (CMD_SUCCESS);
838 }
839
840 switch (af) {
841 case AF_INET:
842 vty->node = LDP_IPV4_IFACE_NODE;
843 break;
844 case AF_INET6:
845 vty->node = LDP_IPV6_IFACE_NODE;
846 break;
847 default:
848 break;
849 }
850 strlcpy(vty_ifname, ifname, sizeof(vty_ifname));
851
852 if (iface == NULL) {
853 if (ldp_iface_is_configured(vty_conf, ifname)) {
854 vty_out(vty, "%% Interface is already in use%s",
855 VTY_NEWLINE);
856 goto cancel;
857 }
858
859 ifp = if_lookup_by_name(ifname);
860 memset(&kif, 0, sizeof(kif));
861 strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
862 if (ifp) {
863 kif.ifindex = ifp->ifindex;
864 kif.flags = ifp->flags;
865 }
866 iface = if_new(&kif);
867
868 ia = iface_af_get(iface, af);
869 ia->enabled = 1;
870 LIST_INSERT_HEAD(&vty_conf->iface_list, iface, entry);
871 } else {
872 memset(&kif, 0, sizeof(kif));
873 strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
874
875 ia = iface_af_get(iface, af);
876 if (ia->enabled)
877 goto cancel;
878 ia->enabled = 1;
879 }
880
881 ldp_reload(vty_conf);
882 return (CMD_SUCCESS);
883
884 cancel:
885 ldp_clear_config(vty_conf);
886 return (CMD_SUCCESS);
887 }
888
889 int
890 ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[])
891 {
892 struct ldpd_conf *vty_conf;
893 struct ldpd_af_conf *af_conf;
894 int af;
895 const char *addr_str;
896 int disable;
897
898 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
899 addr_str = vty_get_arg_value(args, "addr");
900
901 vty_conf = ldp_dup_config(ldpd_conf);
902 af = ldp_vty_get_af(vty);
903 af_conf = ldp_af_conf_get(vty_conf, af);
904
905 if (disable)
906 memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
907 else {
908 if (inet_pton(af, addr_str, &af_conf->trans_addr) != 1 ||
909 bad_addr(af, &af_conf->trans_addr)) {
910 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
911 goto cancel;
912 }
913 }
914
915 ldp_reload(vty_conf);
916
917 return (CMD_SUCCESS);
918
919 cancel:
920 ldp_clear_config(vty_conf);
921 return (CMD_SUCCESS);
922 }
923
924 int
925 ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
926 {
927 struct ldpd_conf *vty_conf;
928 int af;
929 union ldpd_addr addr;
930 struct tnbr *tnbr;
931 const char *addr_str;
932 int disable;
933
934 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
935 addr_str = vty_get_arg_value(args, "addr");
936
937 af = ldp_vty_get_af(vty);
938
939 if (inet_pton(af, addr_str, &addr) != 1 ||
940 bad_addr(af, &addr)) {
941 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
942 return (CMD_WARNING);
943 }
944 if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&addr.v6)) {
945 vty_out(vty, "%% Address can not be link-local%s", VTY_NEWLINE);
946 return (CMD_WARNING);
947 }
948
949 vty_conf = ldp_dup_config(ldpd_conf);
950 tnbr = tnbr_find(vty_conf, af, &addr);
951
952 if (disable) {
953 if (tnbr == NULL)
954 goto cancel;
955
956 LIST_REMOVE(tnbr, entry);
957 free(tnbr);
958 ldp_reload(vty_conf);
959 return (CMD_SUCCESS);
960 }
961
962 if (tnbr)
963 goto cancel;
964
965 tnbr = tnbr_new(af, &addr);
966 tnbr->flags |= F_TNBR_CONFIGURED;
967 LIST_INSERT_HEAD(&vty_conf->tnbr_list, tnbr, entry);
968
969 ldp_reload(vty_conf);
970
971 return (CMD_SUCCESS);
972
973 cancel:
974 ldp_clear_config(vty_conf);
975 return (CMD_SUCCESS);
976 }
977
978 int
979 ldp_vty_explicit_null(struct vty *vty, struct vty_arg *args[])
980 {
981 struct ldpd_conf *vty_conf;
982 struct ldpd_af_conf *af_conf;
983 int af;
984 int disable;
985
986 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
987
988 vty_conf = ldp_dup_config(ldpd_conf);
989 af = ldp_vty_get_af(vty);
990 af_conf = ldp_af_conf_get(vty_conf, af);
991
992 if (disable)
993 af_conf->flags &= ~F_LDPD_AF_EXPNULL;
994 else
995 af_conf->flags |= F_LDPD_AF_EXPNULL;
996
997 ldp_reload(vty_conf);
998
999 return (CMD_SUCCESS);
1000 }
1001
1002 int
1003 ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
1004 {
1005 struct ldpd_conf *vty_conf;
1006 struct ldpd_af_conf *af_conf;
1007 int af;
1008 int disable;
1009
1010 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1011
1012 vty_conf = ldp_dup_config(ldpd_conf);
1013 af = ldp_vty_get_af(vty);
1014 af_conf = ldp_af_conf_get(vty_conf, af);
1015
1016 if (disable)
1017 af_conf->flags &= ~F_LDPD_AF_NO_GTSM;
1018 else
1019 af_conf->flags |= F_LDPD_AF_NO_GTSM;
1020
1021 ldp_reload(vty_conf);
1022
1023 return (CMD_SUCCESS);
1024 }
1025
1026 int
1027 ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
1028 {
1029 struct ldpd_conf *vty_conf;
1030 const char *addr_str;
1031 int disable;
1032
1033 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1034 addr_str = vty_get_arg_value(args, "addr");
1035
1036 vty_conf = ldp_dup_config(ldpd_conf);
1037
1038 if (disable)
1039 vty_conf->rtr_id.s_addr = INADDR_ANY;
1040 else {
1041 if (inet_pton(AF_INET, addr_str, &vty_conf->rtr_id) != 1 ||
1042 bad_addr_v4(vty_conf->rtr_id)) {
1043 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
1044 goto cancel;
1045 }
1046 }
1047
1048 ldp_reload(vty_conf);
1049
1050 return (CMD_SUCCESS);
1051
1052 cancel:
1053 ldp_clear_config(vty_conf);
1054 return (CMD_SUCCESS);
1055 }
1056
1057 int
1058 ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
1059 {
1060 struct ldpd_conf *vty_conf;
1061 int disable;
1062
1063 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1064
1065 vty_conf = ldp_dup_config(ldpd_conf);
1066
1067 if (disable)
1068 vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
1069 else
1070 vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
1071
1072 ldp_reload(vty_conf);
1073
1074 return (CMD_SUCCESS);
1075 }
1076
1077 int
1078 ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
1079 {
1080 struct ldpd_conf *vty_conf;
1081 int disable;
1082
1083 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1084
1085 vty_conf = ldp_dup_config(ldpd_conf);
1086
1087 if (disable)
1088 vty_conf->trans_pref = DUAL_STACK_LDPOV6;
1089 else
1090 vty_conf->trans_pref = DUAL_STACK_LDPOV4;
1091
1092 ldp_reload(vty_conf);
1093
1094 return (CMD_SUCCESS);
1095 }
1096
1097 int
1098 ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
1099 {
1100 struct ldpd_conf *vty_conf;
1101 struct in_addr lsr_id;
1102 size_t password_len;
1103 struct nbr_params *nbrp;
1104 const char *lsr_id_str;
1105 const char *password_str;
1106 int disable;
1107
1108 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1109 lsr_id_str = vty_get_arg_value(args, "lsr_id");
1110 password_str = vty_get_arg_value(args, "password");
1111
1112 if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
1113 bad_addr_v4(lsr_id)) {
1114 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
1115 return (CMD_WARNING);
1116 }
1117
1118 vty_conf = ldp_dup_config(ldpd_conf);
1119 nbrp = nbr_params_find(vty_conf, lsr_id);
1120
1121 if (disable) {
1122 if (nbrp == NULL)
1123 goto cancel;
1124
1125 memset(&nbrp->auth, 0, sizeof(nbrp->auth));
1126 nbrp->auth.method = AUTH_NONE;
1127 } else {
1128 if (nbrp == NULL) {
1129 nbrp = nbr_params_new(lsr_id);
1130 LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
1131 } else if (nbrp->auth.method == AUTH_MD5SIG &&
1132 strcmp(nbrp->auth.md5key, password_str) == 0)
1133 goto cancel;
1134
1135 password_len = strlcpy(nbrp->auth.md5key, password_str,
1136 sizeof(nbrp->auth.md5key));
1137 if (password_len >= sizeof(nbrp->auth.md5key))
1138 vty_out(vty, "%% password has been truncated to %zu "
1139 "characters.", sizeof(nbrp->auth.md5key) - 1);
1140 nbrp->auth.md5key_len = password_len;
1141 nbrp->auth.method = AUTH_MD5SIG;
1142 }
1143
1144 ldp_reload(vty_conf);
1145
1146 return (CMD_SUCCESS);
1147
1148 cancel:
1149 ldp_clear_config(vty_conf);
1150 return (CMD_SUCCESS);
1151 }
1152
1153 int
1154 ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
1155 {
1156 struct ldpd_conf *vty_conf;
1157 struct in_addr lsr_id;
1158 struct nbr_params *nbrp;
1159 long int hops = 0;
1160 char *ep;
1161 const char *lsr_id_str;
1162 const char *hops_str;
1163 int disable;
1164
1165 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1166 lsr_id_str = vty_get_arg_value(args, "lsr_id");
1167 hops_str = vty_get_arg_value(args, "hops");
1168
1169 if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
1170 bad_addr_v4(lsr_id)) {
1171 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
1172 return (CMD_WARNING);
1173 }
1174
1175 if (hops_str) {
1176 hops = strtol(hops_str, &ep, 10);
1177 if (*ep != '\0' || hops < 1 || hops > 254) {
1178 vty_out(vty, "%% Invalid hop count%s", VTY_NEWLINE);
1179 return (CMD_SUCCESS);
1180 }
1181 }
1182
1183 vty_conf = ldp_dup_config(ldpd_conf);
1184 nbrp = nbr_params_find(vty_conf, lsr_id);
1185
1186 if (disable) {
1187 if (nbrp == NULL)
1188 goto cancel;
1189
1190 nbrp->flags &= ~(F_NBRP_GTSM|F_NBRP_GTSM_HOPS);
1191 nbrp->gtsm_enabled = 0;
1192 nbrp->gtsm_hops = 0;
1193 } else {
1194 if (nbrp == NULL) {
1195 nbrp = nbr_params_new(lsr_id);
1196 LIST_INSERT_HEAD(&vty_conf->nbrp_list, nbrp, entry);
1197 }
1198
1199 nbrp->flags |= F_NBRP_GTSM;
1200 nbrp->flags &= ~F_NBRP_GTSM_HOPS;
1201 if (hops_str) {
1202 nbrp->gtsm_enabled = 1;
1203 nbrp->gtsm_hops = hops;
1204 nbrp->flags |= F_NBRP_GTSM_HOPS;
1205 } else
1206 nbrp->gtsm_enabled = 0;
1207 }
1208
1209 ldp_reload(vty_conf);
1210
1211 return (CMD_SUCCESS);
1212
1213 cancel:
1214 ldp_clear_config(vty_conf);
1215 return (CMD_SUCCESS);
1216 }
1217
1218 int
1219 ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
1220 {
1221 struct ldpd_conf *vty_conf;
1222 struct l2vpn *l2vpn;
1223 const char *name_str;
1224 int disable;
1225
1226 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1227 name_str = vty_get_arg_value(args, "name");
1228
1229 vty_conf = ldp_dup_config(ldpd_conf);
1230 l2vpn = l2vpn_find(vty_conf, name_str);
1231
1232 if (disable) {
1233 if (l2vpn == NULL)
1234 goto cancel;
1235
1236 LIST_REMOVE(l2vpn, entry);
1237 l2vpn_del(l2vpn);
1238 ldp_reload(vty_conf);
1239 return (CMD_SUCCESS);
1240 }
1241
1242 vty->node = LDP_L2VPN_NODE;
1243 strlcpy(vty_l2vpn_name, name_str, sizeof(vty_l2vpn_name));
1244 if (l2vpn)
1245 goto cancel;
1246
1247 l2vpn = l2vpn_new(name_str);
1248 l2vpn->type = L2VPN_TYPE_VPLS;
1249 LIST_INSERT_HEAD(&vty_conf->l2vpn_list, l2vpn, entry);
1250
1251 ldp_reload(vty_conf);
1252
1253 return (CMD_SUCCESS);
1254
1255 cancel:
1256 ldp_clear_config(vty_conf);
1257 return (CMD_SUCCESS);
1258 }
1259
1260 int
1261 ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
1262 {
1263 struct ldpd_conf *vty_conf;
1264 struct l2vpn *l2vpn;
1265 const char *ifname;
1266 int disable;
1267
1268 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1269 ifname = vty_get_arg_value(args, "ifname");
1270
1271 vty_conf = ldp_dup_config(ldpd_conf);
1272 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1273
1274 if (disable)
1275 memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
1276 else
1277 strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
1278
1279 ldp_reload(vty_conf);
1280
1281 return (CMD_SUCCESS);
1282 }
1283
1284 int
1285 ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
1286 {
1287 struct ldpd_conf *vty_conf;
1288 struct l2vpn *l2vpn;
1289 char *ep;
1290 int mtu;
1291 const char *mtu_str;
1292 int disable;
1293
1294 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1295 mtu_str = vty_get_arg_value(args, "mtu");
1296
1297 mtu = strtol(mtu_str, &ep, 10);
1298 if (*ep != '\0' || mtu < MIN_L2VPN_MTU || mtu > MAX_L2VPN_MTU) {
1299 vty_out(vty, "%% Invalid MTU%s", VTY_NEWLINE);
1300 return (CMD_WARNING);
1301 }
1302
1303 vty_conf = ldp_dup_config(ldpd_conf);
1304 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1305
1306 if (disable)
1307 l2vpn->mtu = DEFAULT_L2VPN_MTU;
1308 else
1309 l2vpn->mtu = mtu;
1310
1311 ldp_reload(vty_conf);
1312
1313 return (CMD_SUCCESS);
1314 }
1315
1316 int
1317 ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
1318 {
1319 struct ldpd_conf *vty_conf;
1320 struct l2vpn *l2vpn;
1321 int pw_type;
1322 const char *type_str;
1323 int disable;
1324
1325 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1326 type_str = vty_get_arg_value(args, "type");
1327
1328 if (strcmp(type_str, "ethernet") == 0)
1329 pw_type = PW_TYPE_ETHERNET;
1330 else
1331 pw_type = PW_TYPE_ETHERNET_TAGGED;
1332
1333 vty_conf = ldp_dup_config(ldpd_conf);
1334 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1335
1336 if (disable)
1337 l2vpn->pw_type = DEFAULT_PW_TYPE;
1338 else
1339 l2vpn->pw_type = pw_type;
1340
1341 ldp_reload(vty_conf);
1342
1343 return (CMD_SUCCESS);
1344 }
1345
1346 int
1347 ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
1348 {
1349 struct ldpd_conf *vty_conf;
1350 struct l2vpn *l2vpn;
1351 struct l2vpn_if *lif;
1352 struct interface *ifp;
1353 struct kif kif;
1354 const char *ifname;
1355 int disable;
1356
1357 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1358 ifname = vty_get_arg_value(args, "ifname");
1359
1360 vty_conf = ldp_dup_config(ldpd_conf);
1361 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1362 lif = l2vpn_if_find_name(l2vpn, ifname);
1363
1364 if (disable) {
1365 if (lif == NULL)
1366 goto cancel;
1367
1368 LIST_REMOVE(lif, entry);
1369 free(lif);
1370 ldp_reload(vty_conf);
1371 return (CMD_SUCCESS);
1372 }
1373
1374 if (lif)
1375 goto cancel;
1376
1377 if (ldp_iface_is_configured(vty_conf, ifname)) {
1378 vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE);
1379 goto cancel;
1380 }
1381
1382 ifp = if_lookup_by_name(ifname);
1383 memset(&kif, 0, sizeof(kif));
1384 strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
1385 if (ifp) {
1386 kif.ifindex = ifp->ifindex;
1387 kif.flags = ifp->flags;
1388 }
1389
1390 lif = l2vpn_if_new(l2vpn, &kif);
1391 LIST_INSERT_HEAD(&l2vpn->if_list, lif, entry);
1392
1393 ldp_reload(vty_conf);
1394
1395 return (CMD_SUCCESS);
1396
1397 cancel:
1398 ldp_clear_config(vty_conf);
1399 return (CMD_SUCCESS);
1400 }
1401
1402 int
1403 ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
1404 {
1405 struct ldpd_conf *vty_conf;
1406 struct l2vpn *l2vpn;
1407 struct l2vpn_pw *pw;
1408 struct interface *ifp;
1409 struct kif kif;
1410 const char *ifname;
1411 int disable;
1412
1413 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1414 ifname = vty_get_arg_value(args, "ifname");
1415
1416 vty_conf = ldp_dup_config(ldpd_conf);
1417 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1418 pw = l2vpn_pw_find_name(l2vpn, ifname);
1419
1420 if (disable) {
1421 if (pw == NULL)
1422 goto cancel;
1423
1424 LIST_REMOVE(pw, entry);
1425 free(pw);
1426 ldp_reload(vty_conf);
1427 return (CMD_SUCCESS);
1428 }
1429
1430 if (pw) {
1431 vty->node = LDP_PSEUDOWIRE_NODE;
1432 strlcpy(vty_pw_ifname, ifname, sizeof(vty_pw_ifname));
1433 goto cancel;
1434 }
1435
1436 if (ldp_iface_is_configured(vty_conf, ifname)) {
1437 vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE);
1438 goto cancel;
1439 }
1440
1441 ifp = if_lookup_by_name(ifname);
1442 memset(&kif, 0, sizeof(kif));
1443 strlcpy(kif.ifname, ifname, sizeof(kif.ifname));
1444 if (ifp) {
1445 kif.ifindex = ifp->ifindex;
1446 kif.flags = ifp->flags;
1447 }
1448
1449 pw = l2vpn_pw_new(l2vpn, &kif);
1450 pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
1451 LIST_INSERT_HEAD(&l2vpn->pw_inactive_list, pw, entry);
1452
1453 ldp_reload(vty_conf);
1454
1455 vty->node = LDP_PSEUDOWIRE_NODE;
1456 strlcpy(vty_pw_ifname, ifname, sizeof(vty_pw_ifname));
1457 return (CMD_SUCCESS);
1458
1459 cancel:
1460 ldp_clear_config(vty_conf);
1461 return (CMD_SUCCESS);
1462 }
1463
1464 int
1465 ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
1466 {
1467 struct ldpd_conf *vty_conf;
1468 struct l2vpn *l2vpn;
1469 struct l2vpn_pw *pw;
1470 const char *preference_str;
1471 int disable;
1472
1473 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1474 preference_str = vty_get_arg_value(args, "preference");
1475
1476 vty_conf = ldp_dup_config(ldpd_conf);
1477 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1478 pw = l2vpn_pw_find_name(l2vpn, vty_pw_ifname);
1479
1480 if (disable)
1481 pw->flags |= F_PW_CWORD_CONF;
1482 else {
1483 if (preference_str[0] == 'e')
1484 pw->flags &= ~F_PW_CWORD_CONF;
1485 else
1486 pw->flags |= F_PW_CWORD_CONF;
1487 }
1488
1489 ldp_reload(vty_conf);
1490
1491 return (CMD_SUCCESS);
1492 }
1493
1494 int
1495 ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
1496 {
1497 struct ldpd_conf *vty_conf;
1498 struct l2vpn *l2vpn;
1499 struct l2vpn_pw *pw;
1500 int af;
1501 union ldpd_addr addr;
1502 const char *addr_str;
1503 int disable;
1504
1505 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1506 addr_str = vty_get_arg_value(args, "addr");
1507
1508 if (ldp_get_address(addr_str, &af, &addr) == -1 ||
1509 bad_addr(af, &addr)) {
1510 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
1511 return (CMD_WARNING);
1512 }
1513
1514 vty_conf = ldp_dup_config(ldpd_conf);
1515 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1516 pw = l2vpn_pw_find_name(l2vpn, vty_pw_ifname);
1517
1518 if (disable) {
1519 pw->af = AF_UNSPEC;
1520 memset(&pw->addr, 0, sizeof(pw->addr));
1521 pw->flags &= ~F_PW_STATIC_NBR_ADDR;
1522 } else {
1523 pw->af = af;
1524 pw->addr = addr;
1525 pw->flags |= F_PW_STATIC_NBR_ADDR;
1526 }
1527
1528 ldp_reload(vty_conf);
1529
1530 return (CMD_SUCCESS);
1531 }
1532
1533 int
1534 ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
1535 {
1536 struct ldpd_conf *vty_conf;
1537 struct l2vpn *l2vpn;
1538 struct l2vpn_pw *pw;
1539 struct in_addr lsr_id;
1540 const char *lsr_id_str;
1541 int disable;
1542
1543 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1544 lsr_id_str = vty_get_arg_value(args, "lsr-id");
1545
1546 if (inet_pton(AF_INET, lsr_id_str, &lsr_id) != 1 ||
1547 bad_addr_v4(lsr_id)) {
1548 vty_out(vty, "%% Malformed address%s", VTY_NEWLINE);
1549 return (CMD_WARNING);
1550 }
1551
1552 vty_conf = ldp_dup_config(ldpd_conf);
1553 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1554 pw = l2vpn_pw_find_name(l2vpn, vty_pw_ifname);
1555
1556 if (disable)
1557 pw->lsr_id.s_addr = INADDR_ANY;
1558 else
1559 pw->lsr_id = lsr_id;
1560
1561 ldp_reload(vty_conf);
1562
1563 return (CMD_SUCCESS);
1564 }
1565
1566 int
1567 ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
1568 {
1569 struct ldpd_conf *vty_conf;
1570 struct l2vpn *l2vpn;
1571 struct l2vpn_pw *pw;
1572 char *ep;
1573 uint32_t pwid;
1574 const char *pwid_str;
1575 int disable;
1576
1577 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1578 pwid_str = vty_get_arg_value(args, "pwid");
1579
1580 pwid = strtol(pwid_str, &ep, 10);
1581 if (*ep != '\0' || pwid < MIN_PWID_ID || pwid > MAX_PWID_ID) {
1582 vty_out(vty, "%% Invalid pw-id%s", VTY_NEWLINE);
1583 return (CMD_WARNING);
1584 }
1585
1586 vty_conf = ldp_dup_config(ldpd_conf);
1587 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1588 pw = l2vpn_pw_find_name(l2vpn, vty_pw_ifname);
1589
1590 if (disable)
1591 pw->pwid = 0;
1592 else
1593 pw->pwid = pwid;
1594
1595 ldp_reload(vty_conf);
1596
1597 return (CMD_SUCCESS);
1598 }
1599
1600 int
1601 ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
1602 {
1603 struct ldpd_conf *vty_conf;
1604 struct l2vpn *l2vpn;
1605 struct l2vpn_pw *pw;
1606 int disable;
1607
1608 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1609
1610 vty_conf = ldp_dup_config(ldpd_conf);
1611 l2vpn = l2vpn_find(vty_conf, vty_l2vpn_name);
1612 pw = l2vpn_pw_find_name(l2vpn, vty_pw_ifname);
1613
1614 if (disable)
1615 pw->flags |= F_PW_STATUSTLV_CONF;
1616 else
1617 pw->flags &= ~F_PW_STATUSTLV_CONF;
1618
1619 ldp_reload(vty_conf);
1620
1621 return (CMD_SUCCESS);
1622 }
1623
1624 void
1625 ldp_vty_if_init(void)
1626 {
1627 /* Install interface node. */
1628 install_node (&interface_node, interface_config_write);
1629
1630 install_element(CONFIG_NODE, &interface_cmd);
1631 install_element(CONFIG_NODE, &no_interface_cmd);
1632 install_default(INTERFACE_NODE);
1633
1634 /* "description" commands. */
1635 install_element(INTERFACE_NODE, &interface_desc_cmd);
1636 install_element(INTERFACE_NODE, &no_interface_desc_cmd);
1637 }