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