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