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