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