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