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