]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_vty_conf.c
ldpd: remove variable that is not necessary anymore
[mirror_frr.git] / ldpd / ldp_vty_conf.c
CommitLineData
eac6e3f0
RW
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 *
896014f4
DL
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
eac6e3f0
RW
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
eac6e3f0
RW
34static void ldp_af_iface_config_write(struct vty *, int);
35static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *,
36 struct ldpd_af_conf *);
37static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
38static int ldp_vty_get_af(struct vty *);
39static int ldp_iface_is_configured(struct ldpd_conf *, const char *);
40static int ldp_vty_nbr_session_holdtime(struct vty *, struct vty_arg *[]);
41static int ldp_vty_af_session_holdtime(struct vty *, struct vty_arg *[]);
42
eac6e3f0
RW
43struct cmd_node ldp_node =
44{
45 LDP_NODE,
46 "%s(config-ldp)# ",
47 1,
48};
49
50struct cmd_node ldp_ipv4_node =
51{
52 LDP_IPV4_NODE,
53 "%s(config-ldp-af)# ",
54 1,
55};
56
57struct cmd_node ldp_ipv6_node =
58{
59 LDP_IPV6_NODE,
60 "%s(config-ldp-af)# ",
61 1,
62};
63
64struct cmd_node ldp_ipv4_iface_node =
65{
66 LDP_IPV4_IFACE_NODE,
67 "%s(config-ldp-af-if)# ",
68 1,
69};
70
71struct cmd_node ldp_ipv6_iface_node =
72{
73 LDP_IPV6_IFACE_NODE,
74 "%s(config-ldp-af-if)# ",
75 1,
76};
77
78struct cmd_node ldp_l2vpn_node =
79{
80 LDP_L2VPN_NODE,
81 "%s(config-l2vpn)# ",
82 1,
83};
84
85struct cmd_node ldp_pseudowire_node =
86{
87 LDP_PSEUDOWIRE_NODE,
88 "%s(config-l2vpn-pw)# ",
89 1,
90};
91
92int
93ldp_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
eac6e3f0
RW
110static void
111ldp_af_iface_config_write(struct vty *vty, int af)
112{
113 struct iface *iface;
114 struct iface_af *ia;
115
7d3d7491 116 RB_FOREACH(iface, iface_head, &ldpd_conf->iface_tree) {
eac6e3f0
RW
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
135static void
136ldp_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
45a8eba9
RW
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 }
eac6e3f0
RW
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
45a8eba9
RW
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 }
eac6e3f0
RW
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
7989cdba 230 RB_FOREACH(tnbr, tnbr_head, &ldpd_conf->tnbr_tree) {
eac6e3f0
RW
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
243int
244ldp_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
76c4abd1 282 RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
eac6e3f0
RW
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
313static void
314ldp_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
351int
352ldp_l2vpn_config_write(struct vty *vty)
353{
354 struct l2vpn *l2vpn;
355 struct l2vpn_if *lif;
356 struct l2vpn_pw *pw;
357
90d7e7bd 358 RB_FOREACH(l2vpn, l2vpn_head, &ldpd_conf->l2vpn_tree) {
eac6e3f0
RW
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
029c1958 371 RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
eac6e3f0
RW
372 vty_out(vty, " member interface %s%s", lif->ifname,
373 VTY_NEWLINE);
374
20bacaeb 375 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
eac6e3f0 376 ldp_l2vpn_pw_config_write(vty, pw);
20bacaeb 377 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
eac6e3f0
RW
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
387static int
388ldp_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
402static int
403ldp_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
90d7e7bd 410 RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
52bd4c23 411 if (l2vpn_if_find(l2vpn, ifname))
eac6e3f0 412 return (1);
52bd4c23 413 if (l2vpn_pw_find(l2vpn, ifname))
eac6e3f0
RW
414 return (1);
415 }
416
417 return (0);
418}
419
420int
421ldp_vty_mpls_ldp(struct vty *vty, struct vty_arg *args[])
422{
eac6e3f0
RW
423 int disable;
424
eac6e3f0
RW
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_reload(vty_conf);
435
436 return (CMD_SUCCESS);
437}
438
439int
440ldp_vty_address_family(struct vty *vty, struct vty_arg *args[])
441{
eac6e3f0
RW
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
eac6e3f0
RW
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;
56b8a8d2 456 } else
eac6e3f0
RW
457 return (CMD_WARNING);
458
459 if (disable) {
460 af_conf->flags &= ~F_LDPD_AF_ENABLED;
461 ldp_reload(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_reload(vty_conf);
478
479 return (CMD_SUCCESS);
480}
481
482int
483ldp_vty_disc_holdtime(struct vty *vty, struct vty_arg *args[])
484{
eac6e3f0
RW
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
eac6e3f0
RW
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 }
0b47280e 533 ldp_reload(vty_conf);
eac6e3f0
RW
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 }
0b47280e 559 ldp_reload(vty_conf);
eac6e3f0
RW
560 break;
561 case LDP_IPV4_IFACE_NODE:
562 case LDP_IPV6_IFACE_NODE:
563 af = ldp_vty_get_af(vty);
1d75a89d 564 iface = VTY_GET_CONTEXT(iface);
dbce3582 565 VTY_CHECK_CONTEXT(iface);
eac6e3f0 566
0b47280e 567 ia = iface_af_get(iface, af);
eac6e3f0
RW
568 if (disable)
569 ia->hello_holdtime = 0;
570 else
571 ia->hello_holdtime = secs;
1d75a89d 572
56b8a8d2 573 ldp_reload(vty_conf);
eac6e3f0
RW
574 break;
575 default:
576 fatalx("ldp_vty_disc_holdtime: unexpected node");
577 }
578
eac6e3f0
RW
579 return (CMD_SUCCESS);
580}
581
582int
583ldp_vty_disc_interval(struct vty *vty, struct vty_arg *args[])
584{
eac6e3f0
RW
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
eac6e3f0
RW
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 }
0b47280e 634 ldp_reload(vty_conf);
eac6e3f0
RW
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 }
0b47280e 660 ldp_reload(vty_conf);
eac6e3f0
RW
661 break;
662 case LDP_IPV4_IFACE_NODE:
663 case LDP_IPV6_IFACE_NODE:
664 af = ldp_vty_get_af(vty);
1d75a89d 665 iface = VTY_GET_CONTEXT(iface);
dbce3582 666 VTY_CHECK_CONTEXT(iface);
eac6e3f0 667
0b47280e 668 ia = iface_af_get(iface, af);
eac6e3f0
RW
669 if (disable)
670 ia->hello_interval = 0;
671 else
672 ia->hello_interval = secs;
1d75a89d 673
56b8a8d2 674 ldp_reload(vty_conf);
eac6e3f0
RW
675 break;
676 default:
677 fatalx("ldp_vty_disc_interval: unexpected node");
678 }
679
eac6e3f0
RW
680 return (CMD_SUCCESS);
681}
682
683int
684ldp_vty_targeted_hello_accept(struct vty *vty, struct vty_arg *args[])
685{
eac6e3f0
RW
686 struct ldpd_af_conf *af_conf;
687 int af;
45a8eba9 688 const char *acl_from_str;
eac6e3f0
RW
689 int disable;
690
eac6e3f0 691 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
45a8eba9 692 acl_from_str = vty_get_arg_value(args, "from_acl");
eac6e3f0
RW
693
694 af = ldp_vty_get_af(vty);
695 af_conf = ldp_af_conf_get(vty_conf, af);
696
45a8eba9 697 if (disable) {
eac6e3f0 698 af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
45a8eba9
RW
699 af_conf->acl_thello_accept_from[0] = '\0';
700 } else {
eac6e3f0 701 af_conf->flags |= F_LDPD_AF_THELLO_ACCEPT;
45a8eba9
RW
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 }
eac6e3f0
RW
708
709 ldp_reload(vty_conf);
710
711 return (CMD_SUCCESS);
712}
713
714static int
715ldp_vty_nbr_session_holdtime(struct vty *vty, struct vty_arg *args[])
716{
eac6e3f0
RW
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
eac6e3f0
RW
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);
56b8a8d2 738 return (CMD_SUCCESS);
eac6e3f0
RW
739 }
740
1d75a89d
RW
741 nbrp = nbr_params_find(vty_conf, lsr_id);
742
eac6e3f0
RW
743 if (disable) {
744 if (nbrp == NULL)
56b8a8d2 745 return (CMD_SUCCESS);
eac6e3f0
RW
746
747 nbrp->keepalive = 0;
748 nbrp->flags &= ~F_NBRP_KEEPALIVE;
749 } else {
750 if (nbrp == NULL) {
751 nbrp = nbr_params_new(lsr_id);
76c4abd1 752 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 753 QOBJ_REG(nbrp, nbr_params);
eac6e3f0 754 } else if (nbrp->keepalive == secs)
56b8a8d2 755 return (CMD_SUCCESS);
eac6e3f0
RW
756
757 nbrp->keepalive = secs;
758 nbrp->flags |= F_NBRP_KEEPALIVE;
759 }
760
761 ldp_reload(vty_conf);
762
763 return (CMD_SUCCESS);
eac6e3f0
RW
764}
765
766static int
767ldp_vty_af_session_holdtime(struct vty *vty, struct vty_arg *args[])
768{
eac6e3f0
RW
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
eac6e3f0
RW
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_reload(vty_conf);
794
795 return (CMD_SUCCESS);
796}
797
798int
799ldp_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
812int
813ldp_vty_interface(struct vty *vty, struct vty_arg *args[])
814{
eac6e3f0
RW
815 int af;
816 struct iface *iface;
817 struct iface_af *ia;
eac6e3f0
RW
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
eac6e3f0
RW
824 af = ldp_vty_get_af(vty);
825 iface = if_lookup_name(vty_conf, ifname);
826
827 if (disable) {
828 if (iface == NULL)
56b8a8d2 829 return (CMD_SUCCESS);
eac6e3f0
RW
830
831 ia = iface_af_get(iface, af);
832 if (ia->enabled == 0)
56b8a8d2 833 return (CMD_SUCCESS);
eac6e3f0
RW
834
835 ia->enabled = 0;
271327b1
RW
836 ia->hello_holdtime = 0;
837 ia->hello_interval = 0;
1d75a89d 838
eac6e3f0 839 ldp_reload(vty_conf);
1d75a89d 840
eac6e3f0
RW
841 return (CMD_SUCCESS);
842 }
843
eac6e3f0
RW
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);
56b8a8d2 848 return (CMD_SUCCESS);
eac6e3f0
RW
849 }
850
52b530fc 851 iface = if_new(ifname);
eac6e3f0
RW
852 ia = iface_af_get(iface, af);
853 ia->enabled = 1;
7d3d7491 854 RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
1d75a89d
RW
855 QOBJ_REG(iface, iface);
856
56b8a8d2 857 ldp_reload(vty_conf);
eac6e3f0 858 } else {
eac6e3f0 859 ia = iface_af_get(iface, af);
0b47280e
RW
860 if (!ia->enabled) {
861 ia->enabled = 1;
56b8a8d2
RW
862 ldp_reload(vty_conf);
863 }
0b47280e
RW
864 }
865
866 switch (af) {
867 case AF_INET:
1d75a89d 868 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE, iface);
0b47280e
RW
869 break;
870 case AF_INET6:
1d75a89d 871 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE, iface);
0b47280e
RW
872 break;
873 default:
874 break;
eac6e3f0
RW
875 }
876
eac6e3f0 877 return (CMD_SUCCESS);
eac6e3f0
RW
878}
879
880int
881ldp_vty_trans_addr(struct vty *vty, struct vty_arg *args[])
882{
eac6e3f0
RW
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
eac6e3f0
RW
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);
56b8a8d2 900 return (CMD_SUCCESS);
eac6e3f0
RW
901 }
902 }
903
904 ldp_reload(vty_conf);
905
906 return (CMD_SUCCESS);
eac6e3f0
RW
907}
908
909int
910ldp_vty_neighbor_targeted(struct vty *vty, struct vty_arg *args[])
911{
eac6e3f0
RW
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
eac6e3f0
RW
933 tnbr = tnbr_find(vty_conf, af, &addr);
934
935 if (disable) {
936 if (tnbr == NULL)
56b8a8d2 937 return (CMD_SUCCESS);
eac6e3f0 938
1d75a89d 939 QOBJ_UNREG(tnbr);
7989cdba 940 RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
eac6e3f0 941 free(tnbr);
1d75a89d 942
eac6e3f0 943 ldp_reload(vty_conf);
1d75a89d 944
eac6e3f0
RW
945 return (CMD_SUCCESS);
946 }
947
948 if (tnbr)
56b8a8d2 949 return (CMD_SUCCESS);
eac6e3f0
RW
950
951 tnbr = tnbr_new(af, &addr);
952 tnbr->flags |= F_TNBR_CONFIGURED;
7989cdba 953 RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
1d75a89d 954 QOBJ_REG(tnbr, tnbr);
eac6e3f0
RW
955
956 ldp_reload(vty_conf);
957
958 return (CMD_SUCCESS);
eac6e3f0
RW
959}
960
961int
45a8eba9 962ldp_vty_label_advertise(struct vty *vty, struct vty_arg *args[])
eac6e3f0 963{
eac6e3f0
RW
964 struct ldpd_af_conf *af_conf;
965 int af;
45a8eba9
RW
966 const char *acl_to_str;
967 const char *acl_for_str;
eac6e3f0
RW
968 int disable;
969
970 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
45a8eba9
RW
971 acl_to_str = vty_get_arg_value(args, "to_acl");
972 acl_for_str = vty_get_arg_value(args, "for_acl");
eac6e3f0 973
eac6e3f0
RW
974 af = ldp_vty_get_af(vty);
975 af_conf = ldp_af_conf_get(vty_conf, af);
976
45a8eba9
RW
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_reload(vty_conf);
994
995 return (CMD_SUCCESS);
996}
997
998int
999ldp_vty_label_allocate(struct vty *vty, struct vty_arg *args[])
1000{
45a8eba9
RW
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
45a8eba9
RW
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_reload(vty_conf);
1025
1026 return (CMD_SUCCESS);
1027}
1028
1029int
1030ldp_vty_label_expnull(struct vty *vty, struct vty_arg *args[])
1031{
45a8eba9
RW
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
45a8eba9
RW
1040 af = ldp_vty_get_af(vty);
1041 af_conf = ldp_af_conf_get(vty_conf, af);
1042
1043 if (disable) {
eac6e3f0 1044 af_conf->flags &= ~F_LDPD_AF_EXPNULL;
45a8eba9
RW
1045 af_conf->acl_label_expnull_for[0] = '\0';
1046 } else {
eac6e3f0 1047 af_conf->flags |= F_LDPD_AF_EXPNULL;
45a8eba9
RW
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_reload(vty_conf);
1056
1057 return (CMD_SUCCESS);
1058}
1059
1060int
1061ldp_vty_label_accept(struct vty *vty, struct vty_arg *args[])
1062{
45a8eba9
RW
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
45a8eba9
RW
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 }
eac6e3f0
RW
1091
1092 ldp_reload(vty_conf);
1093
1094 return (CMD_SUCCESS);
1095}
1096
1097int
1098ldp_vty_ttl_security(struct vty *vty, struct vty_arg *args[])
1099{
eac6e3f0
RW
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
eac6e3f0
RW
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_reload(vty_conf);
1115
1116 return (CMD_SUCCESS);
1117}
1118
1119int
1120ldp_vty_router_id(struct vty *vty, struct vty_arg *args[])
1121{
eac6e3f0
RW
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
eac6e3f0
RW
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);
56b8a8d2 1134 return (CMD_SUCCESS);
eac6e3f0
RW
1135 }
1136 }
1137
1138 ldp_reload(vty_conf);
1139
1140 return (CMD_SUCCESS);
eac6e3f0
RW
1141}
1142
1143int
1144ldp_vty_ds_cisco_interop(struct vty *vty, struct vty_arg *args[])
1145{
eac6e3f0
RW
1146 int disable;
1147
1148 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1149
eac6e3f0
RW
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_reload(vty_conf);
1156
1157 return (CMD_SUCCESS);
1158}
1159
1160int
1161ldp_vty_trans_pref_ipv4(struct vty *vty, struct vty_arg *args[])
1162{
eac6e3f0
RW
1163 int disable;
1164
1165 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1166
eac6e3f0
RW
1167 if (disable)
1168 vty_conf->trans_pref = DUAL_STACK_LDPOV6;
1169 else
1170 vty_conf->trans_pref = DUAL_STACK_LDPOV4;
1171
1172 ldp_reload(vty_conf);
1173
1174 return (CMD_SUCCESS);
1175}
1176
1177int
1178ldp_vty_neighbor_password(struct vty *vty, struct vty_arg *args[])
1179{
eac6e3f0
RW
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
eac6e3f0
RW
1197 nbrp = nbr_params_find(vty_conf, lsr_id);
1198
1199 if (disable) {
1200 if (nbrp == NULL)
56b8a8d2 1201 return (CMD_SUCCESS);
eac6e3f0
RW
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);
76c4abd1 1208 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 1209 QOBJ_REG(nbrp, nbr_params);
eac6e3f0
RW
1210 } else if (nbrp->auth.method == AUTH_MD5SIG &&
1211 strcmp(nbrp->auth.md5key, password_str) == 0)
56b8a8d2 1212 return (CMD_SUCCESS);
eac6e3f0
RW
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_reload(vty_conf);
1224
1225 return (CMD_SUCCESS);
eac6e3f0
RW
1226}
1227
1228int
1229ldp_vty_neighbor_ttl_security(struct vty *vty, struct vty_arg *args[])
1230{
eac6e3f0
RW
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
eac6e3f0
RW
1257 nbrp = nbr_params_find(vty_conf, lsr_id);
1258
1259 if (disable) {
1260 if (nbrp == NULL)
56b8a8d2 1261 return (CMD_SUCCESS);
eac6e3f0
RW
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);
76c4abd1 1269 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 1270 QOBJ_REG(nbrp, nbr_params);
eac6e3f0
RW
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_reload(vty_conf);
1284
1285 return (CMD_SUCCESS);
eac6e3f0
RW
1286}
1287
1288int
1289ldp_vty_l2vpn(struct vty *vty, struct vty_arg *args[])
1290{
eac6e3f0 1291 struct l2vpn *l2vpn;
1d75a89d
RW
1292 struct l2vpn_if *lif;
1293 struct l2vpn_pw *pw;
eac6e3f0
RW
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
eac6e3f0
RW
1300 l2vpn = l2vpn_find(vty_conf, name_str);
1301
1302 if (disable) {
1303 if (l2vpn == NULL)
56b8a8d2 1304 return (CMD_SUCCESS);
eac6e3f0 1305
1d75a89d
RW
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);
90d7e7bd 1313 RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
eac6e3f0 1314 l2vpn_del(l2vpn);
1d75a89d 1315
eac6e3f0 1316 ldp_reload(vty_conf);
1d75a89d 1317
eac6e3f0
RW
1318 return (CMD_SUCCESS);
1319 }
1320
0b47280e 1321 if (l2vpn) {
1d75a89d 1322 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
56b8a8d2 1323 return (CMD_SUCCESS);
0b47280e 1324 }
eac6e3f0
RW
1325
1326 l2vpn = l2vpn_new(name_str);
1327 l2vpn->type = L2VPN_TYPE_VPLS;
90d7e7bd 1328 RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
1d75a89d
RW
1329 QOBJ_REG(l2vpn, l2vpn);
1330
1331 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
eac6e3f0 1332
56b8a8d2 1333 ldp_reload(vty_conf);
eac6e3f0
RW
1334
1335 return (CMD_SUCCESS);
eac6e3f0
RW
1336}
1337
1338int
1339ldp_vty_l2vpn_bridge(struct vty *vty, struct vty_arg *args[])
1340{
1d75a89d 1341 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0
RW
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
eac6e3f0
RW
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
56b8a8d2 1353 ldp_reload(vty_conf);
eac6e3f0
RW
1354
1355 return (CMD_SUCCESS);
1356}
1357
1358int
1359ldp_vty_l2vpn_mtu(struct vty *vty, struct vty_arg *args[])
1360{
1d75a89d 1361 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0
RW
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
eac6e3f0
RW
1376 if (disable)
1377 l2vpn->mtu = DEFAULT_L2VPN_MTU;
1378 else
1379 l2vpn->mtu = mtu;
1380
56b8a8d2 1381 ldp_reload(vty_conf);
eac6e3f0
RW
1382
1383 return (CMD_SUCCESS);
1384}
1385
1386int
1387ldp_vty_l2vpn_pwtype(struct vty *vty, struct vty_arg *args[])
1388{
1d75a89d 1389 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0
RW
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
eac6e3f0
RW
1402 if (disable)
1403 l2vpn->pw_type = DEFAULT_PW_TYPE;
1404 else
1405 l2vpn->pw_type = pw_type;
1406
56b8a8d2 1407 ldp_reload(vty_conf);
eac6e3f0
RW
1408
1409 return (CMD_SUCCESS);
1410}
1411
1412int
1413ldp_vty_l2vpn_interface(struct vty *vty, struct vty_arg *args[])
1414{
1d75a89d 1415 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1416 struct l2vpn_if *lif;
eac6e3f0
RW
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
52bd4c23 1423 lif = l2vpn_if_find(l2vpn, ifname);
eac6e3f0
RW
1424
1425 if (disable) {
1426 if (lif == NULL)
56b8a8d2 1427 return (CMD_SUCCESS);
eac6e3f0 1428
1d75a89d 1429 QOBJ_UNREG(lif);
029c1958 1430 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
eac6e3f0 1431 free(lif);
1d75a89d 1432
eac6e3f0 1433 ldp_reload(vty_conf);
1d75a89d 1434
eac6e3f0
RW
1435 return (CMD_SUCCESS);
1436 }
1437
1438 if (lif)
56b8a8d2 1439 return (CMD_SUCCESS);
eac6e3f0
RW
1440
1441 if (ldp_iface_is_configured(vty_conf, ifname)) {
1442 vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE);
56b8a8d2 1443 return (CMD_SUCCESS);
eac6e3f0
RW
1444 }
1445
52b530fc 1446 lif = l2vpn_if_new(l2vpn, ifname);
029c1958 1447 RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
1d75a89d 1448 QOBJ_REG(lif, l2vpn_if);
eac6e3f0 1449
56b8a8d2 1450 ldp_reload(vty_conf);
eac6e3f0 1451
eac6e3f0
RW
1452 return (CMD_SUCCESS);
1453}
1454
1455int
1456ldp_vty_l2vpn_pseudowire(struct vty *vty, struct vty_arg *args[])
1457{
1d75a89d 1458 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1459 struct l2vpn_pw *pw;
eac6e3f0
RW
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
52bd4c23 1466 pw = l2vpn_pw_find(l2vpn, ifname);
eac6e3f0
RW
1467
1468 if (disable) {
1469 if (pw == NULL)
56b8a8d2 1470 return (CMD_SUCCESS);
eac6e3f0 1471
1d75a89d
RW
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);
eac6e3f0 1477 free(pw);
1d75a89d 1478
eac6e3f0 1479 ldp_reload(vty_conf);
1d75a89d 1480
eac6e3f0
RW
1481 return (CMD_SUCCESS);
1482 }
1483
1484 if (pw) {
1d75a89d 1485 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
56b8a8d2 1486 return (CMD_SUCCESS);
eac6e3f0
RW
1487 }
1488
1489 if (ldp_iface_is_configured(vty_conf, ifname)) {
1490 vty_out(vty, "%% Interface is already in use%s", VTY_NEWLINE);
56b8a8d2 1491 return (CMD_SUCCESS);
eac6e3f0
RW
1492 }
1493
52b530fc 1494 pw = l2vpn_pw_new(l2vpn, ifname);
eac6e3f0 1495 pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
20bacaeb 1496 RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
1d75a89d
RW
1497 QOBJ_REG(pw, l2vpn_pw);
1498
1499 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
eac6e3f0 1500
56b8a8d2 1501 ldp_reload(vty_conf);
eac6e3f0 1502
eac6e3f0 1503 return (CMD_SUCCESS);
eac6e3f0
RW
1504}
1505
1506int
1507ldp_vty_l2vpn_pw_cword(struct vty *vty, struct vty_arg *args[])
1508{
1d75a89d 1509 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
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
eac6e3f0
RW
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
56b8a8d2 1525 ldp_reload(vty_conf);
eac6e3f0
RW
1526
1527 return (CMD_SUCCESS);
1528}
1529
1530int
1531ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, struct vty_arg *args[])
1532{
1d75a89d 1533 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
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
eac6e3f0
RW
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
56b8a8d2 1558 ldp_reload(vty_conf);
eac6e3f0
RW
1559
1560 return (CMD_SUCCESS);
1561}
1562
1563int
1564ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, struct vty_arg *args[])
1565{
1d75a89d 1566 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
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
eac6e3f0
RW
1580 if (disable)
1581 pw->lsr_id.s_addr = INADDR_ANY;
1582 else
1583 pw->lsr_id = lsr_id;
1584
56b8a8d2 1585 ldp_reload(vty_conf);
eac6e3f0
RW
1586
1587 return (CMD_SUCCESS);
1588}
1589
1590int
1591ldp_vty_l2vpn_pw_pwid(struct vty *vty, struct vty_arg *args[])
1592{
1d75a89d 1593 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
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
eac6e3f0
RW
1608 if (disable)
1609 pw->pwid = 0;
1610 else
1611 pw->pwid = pwid;
1612
56b8a8d2 1613 ldp_reload(vty_conf);
eac6e3f0
RW
1614
1615 return (CMD_SUCCESS);
1616}
1617
1618int
1619ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, struct vty_arg *args[])
1620{
1d75a89d 1621 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
1622 int disable;
1623
1624 disable = (vty_get_arg_value(args, "no")) ? 1 : 0;
1625
eac6e3f0
RW
1626 if (disable)
1627 pw->flags |= F_PW_STATUSTLV_CONF;
1628 else
1629 pw->flags &= ~F_PW_STATUSTLV_CONF;
1630
56b8a8d2 1631 ldp_reload(vty_conf);
eac6e3f0
RW
1632
1633 return (CMD_SUCCESS);
1634}
1635
bbee85d2
RW
1636struct iface *
1637iface_new_api(struct ldpd_conf *conf, const char *name)
1638{
1639 const char *ifname = name;
1640 struct iface *iface;
bbee85d2
RW
1641
1642 if (ldp_iface_is_configured(conf, ifname))
5afba51d 1643 return (NULL);
bbee85d2 1644
52b530fc 1645 iface = if_new(name);
7d3d7491 1646 RB_INSERT(iface_head, &conf->iface_tree, iface);
1d75a89d 1647 QOBJ_REG(iface, iface);
bbee85d2
RW
1648 return (iface);
1649}
1650
1651void
7d3d7491 1652iface_del_api(struct ldpd_conf *conf, struct iface *iface)
bbee85d2 1653{
1d75a89d 1654 QOBJ_UNREG(iface);
7d3d7491 1655 RB_REMOVE(iface_head, &conf->iface_tree, iface);
bbee85d2
RW
1656 free(iface);
1657}
1658
1659struct tnbr *
1660tnbr_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;
7989cdba 1672 RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
1d75a89d 1673 QOBJ_REG(tnbr, tnbr);
bbee85d2
RW
1674 return (tnbr);
1675}
1676
1677void
7989cdba 1678tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
bbee85d2 1679{
1d75a89d 1680 QOBJ_UNREG(tnbr);
7989cdba 1681 RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
bbee85d2
RW
1682 free(tnbr);
1683}
1684
1685struct nbr_params *
1686nbrp_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);
76c4abd1 1694 RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
1d75a89d 1695 QOBJ_REG(nbrp, nbr_params);
bbee85d2
RW
1696 return (nbrp);
1697}
1698
1699void
76c4abd1 1700nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
bbee85d2 1701{
1d75a89d 1702 QOBJ_UNREG(nbrp);
76c4abd1 1703 RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
bbee85d2
RW
1704 free(nbrp);
1705}
1706
1707struct l2vpn *
1708l2vpn_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;
90d7e7bd 1717 RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
1d75a89d 1718 QOBJ_REG(l2vpn, l2vpn);
bbee85d2
RW
1719 return (l2vpn);
1720}
1721
1722void
90d7e7bd 1723l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
bbee85d2
RW
1724{
1725 struct l2vpn_if *lif;
1726 struct l2vpn_pw *pw;
1727
029c1958 1728 while ((lif = RB_ROOT(&l2vpn->if_tree)) != NULL) {
1d75a89d 1729 QOBJ_UNREG(lif);
029c1958 1730 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
bbee85d2
RW
1731 free(lif);
1732 }
20bacaeb 1733 while ((pw = RB_ROOT(&l2vpn->pw_tree)) != NULL) {
1d75a89d 1734 QOBJ_UNREG(pw);
20bacaeb 1735 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
bbee85d2
RW
1736 free(pw);
1737 }
20bacaeb 1738 while ((pw = RB_ROOT(&l2vpn->pw_inactive_tree)) != NULL) {
1d75a89d 1739 QOBJ_UNREG(pw);
20bacaeb 1740 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
bbee85d2
RW
1741 free(pw);
1742 }
1d75a89d 1743 QOBJ_UNREG(l2vpn);
90d7e7bd 1744 RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
bbee85d2
RW
1745 free(l2vpn);
1746}
1747
1748struct l2vpn_if *
1749l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
1750 const char *ifname)
1751{
1752 struct l2vpn_if *lif;
bbee85d2
RW
1753
1754 if (ldp_iface_is_configured(conf, ifname))
1755 return (NULL);
1756
52b530fc 1757 lif = l2vpn_if_new(l2vpn, ifname);
029c1958 1758 RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
1d75a89d 1759 QOBJ_REG(lif, l2vpn_if);
bbee85d2
RW
1760 return (lif);
1761}
1762
1763void
029c1958 1764l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
bbee85d2 1765{
1d75a89d 1766 QOBJ_UNREG(lif);
029c1958 1767 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
bbee85d2
RW
1768 free(lif);
1769}
1770
1771struct l2vpn_pw *
1772l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
1773 const char *ifname)
1774{
1775 struct l2vpn_pw *pw;
bbee85d2
RW
1776
1777 if (ldp_iface_is_configured(conf, ifname))
1778 return (NULL);
1779
52b530fc 1780 pw = l2vpn_pw_new(l2vpn, ifname);
bbee85d2 1781 pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
20bacaeb 1782 RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
1d75a89d 1783 QOBJ_REG(pw, l2vpn_pw);
bbee85d2
RW
1784 return (pw);
1785}
1786
1787void
20bacaeb 1788l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
bbee85d2 1789{
1d75a89d 1790 QOBJ_UNREG(pw);
20bacaeb 1791 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
bbee85d2
RW
1792 free(pw);
1793}