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