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