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