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