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