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