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