2 * Copyright (C) 2016 by Open Source Routing.
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.
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.
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,
33 static void ldp_af_iface_config_write(struct vty
*, int);
34 static void ldp_af_config_write(struct vty
*, int, struct ldpd_conf
*,
35 struct ldpd_af_conf
*);
36 static void ldp_l2vpn_pw_config_write(struct vty
*, struct l2vpn_pw
*);
37 static int ldp_vty_get_af(struct vty
*);
38 static int ldp_iface_is_configured(struct ldpd_conf
*, const char *);
40 struct cmd_node ldp_node
=
47 struct cmd_node ldp_ipv4_node
=
50 "%s(config-ldp-af)# ",
54 struct cmd_node ldp_ipv6_node
=
57 "%s(config-ldp-af)# ",
61 struct cmd_node ldp_ipv4_iface_node
=
64 "%s(config-ldp-af-if)# ",
68 struct cmd_node ldp_ipv6_iface_node
=
71 "%s(config-ldp-af-if)# ",
75 struct cmd_node ldp_l2vpn_node
=
82 struct cmd_node ldp_pseudowire_node
=
85 "%s(config-l2vpn-pw)# ",
90 ldp_get_address(const char *str
, int *af
, union ldpd_addr
*addr
)
92 memset(addr
, 0, sizeof(*addr
));
94 if (inet_pton(AF_INET
, str
, &addr
->v4
) == 1) {
99 if (inet_pton(AF_INET6
, str
, &addr
->v6
) == 1) {
108 ldp_af_iface_config_write(struct vty
*vty
, int af
)
113 RB_FOREACH(iface
, iface_head
, &ldpd_conf
->iface_tree
) {
114 ia
= iface_af_get(iface
, af
);
118 vty_out (vty
, " !\n");
119 vty_out (vty
, " interface %s\n", iface
->name
);
121 if (ia
->hello_holdtime
!= LINK_DFLT_HOLDTIME
&&
122 ia
->hello_holdtime
!= 0)
123 vty_out (vty
, " discovery hello holdtime %u\n",
125 if (ia
->hello_interval
!= DEFAULT_HELLO_INTERVAL
&&
126 ia
->hello_interval
!= 0)
127 vty_out (vty
, " discovery hello interval %u\n",
133 ldp_af_config_write(struct vty
*vty
, int af
, struct ldpd_conf
*conf
,
134 struct ldpd_af_conf
*af_conf
)
138 if (!(af_conf
->flags
& F_LDPD_AF_ENABLED
))
141 vty_out (vty
, " !\n");
142 vty_out (vty
, " address-family %s\n", af_name(af
));
144 if (af_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
145 af_conf
->lhello_holdtime
!= 0 )
146 vty_out (vty
, " discovery hello holdtime %u\n",
147 af_conf
->lhello_holdtime
);
148 if (af_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
149 af_conf
->lhello_interval
!= 0)
150 vty_out (vty
, " discovery hello interval %u\n",
151 af_conf
->lhello_interval
);
153 if (af_conf
->flags
& F_LDPD_AF_THELLO_ACCEPT
) {
154 vty_out(vty
, " discovery targeted-hello accept");
155 if (af_conf
->acl_thello_accept_from
[0] != '\0')
156 vty_out(vty
, " from %s",
157 af_conf
->acl_thello_accept_from
);
161 if (af_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
162 af_conf
->thello_holdtime
!= 0)
163 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
164 af_conf
->thello_holdtime
);
165 if (af_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
166 af_conf
->thello_interval
!= 0)
167 vty_out (vty
, " discovery targeted-hello interval %u\n",
168 af_conf
->thello_interval
);
170 if (ldp_addrisset(af
, &af_conf
->trans_addr
))
171 vty_out (vty
, " discovery transport-address %s\n",
172 log_addr(af
, &af_conf
->trans_addr
));
175 " ! Incomplete config, specify a discovery transport-address\n");
177 if ((af_conf
->flags
& F_LDPD_AF_ALLOCHOSTONLY
) ||
178 af_conf
->acl_label_allocate_for
[0] != '\0') {
179 vty_out(vty
, " label local allocate");
180 if (af_conf
->flags
& F_LDPD_AF_ALLOCHOSTONLY
)
181 vty_out(vty
, " host-routes");
183 vty_out(vty
, " for %s",
184 af_conf
->acl_label_allocate_for
);
188 if (af_conf
->acl_label_advertise_for
[0] != '\0' ||
189 af_conf
->acl_label_advertise_to
[0] != '\0') {
190 vty_out(vty
, " label local advertise");
191 if (af_conf
->acl_label_advertise_to
[0] != '\0')
192 vty_out(vty
, " to %s",
193 af_conf
->acl_label_advertise_to
);
194 if (af_conf
->acl_label_advertise_for
[0] != '\0')
195 vty_out(vty
, " for %s",
196 af_conf
->acl_label_advertise_for
);
200 if (af_conf
->flags
& F_LDPD_AF_EXPNULL
) {
201 vty_out(vty
, " label local advertise explicit-null");
202 if (af_conf
->acl_label_expnull_for
[0] != '\0')
203 vty_out(vty
, " for %s",
204 af_conf
->acl_label_expnull_for
);
208 if (af_conf
->acl_label_accept_for
[0] != '\0' ||
209 af_conf
->acl_label_accept_from
[0] != '\0') {
210 vty_out(vty
, " label remote accept");
211 if (af_conf
->acl_label_accept_from
[0] != '\0')
212 vty_out(vty
, " from %s",
213 af_conf
->acl_label_accept_from
);
214 if (af_conf
->acl_label_accept_for
[0] != '\0')
215 vty_out(vty
, " for %s",
216 af_conf
->acl_label_accept_for
);
220 if (af_conf
->flags
& F_LDPD_AF_NO_GTSM
)
221 vty_out (vty
, " ttl-security disable\n");
223 if (af_conf
->keepalive
!= DEFAULT_KEEPALIVE
)
224 vty_out (vty
, " session holdtime %u\n",af_conf
->keepalive
);
226 RB_FOREACH(tnbr
, tnbr_head
, &ldpd_conf
->tnbr_tree
) {
227 if (tnbr
->af
== af
) {
228 vty_out (vty
, " !\n");
229 vty_out (vty
, " neighbor %s targeted\n",
230 log_addr(tnbr
->af
, &tnbr
->addr
));
234 ldp_af_iface_config_write(vty
, af
);
236 vty_out(vty
, " exit-address-family\n");
240 ldp_config_write(struct vty
*vty
)
242 struct nbr_params
*nbrp
;
244 if (!(ldpd_conf
->flags
& F_LDPD_ENABLED
))
247 vty_out (vty
, "mpls ldp\n");
249 if (ldpd_conf
->rtr_id
.s_addr
!= 0)
250 vty_out (vty
, " router-id %s\n",
251 inet_ntoa(ldpd_conf
->rtr_id
));
253 if (ldpd_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
254 ldpd_conf
->lhello_holdtime
!= 0)
255 vty_out (vty
, " discovery hello holdtime %u\n",
256 ldpd_conf
->lhello_holdtime
);
257 if (ldpd_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
258 ldpd_conf
->lhello_interval
!= 0)
259 vty_out (vty
, " discovery hello interval %u\n",
260 ldpd_conf
->lhello_interval
);
262 if (ldpd_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
263 ldpd_conf
->thello_holdtime
!= 0)
264 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
265 ldpd_conf
->thello_holdtime
);
266 if (ldpd_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
267 ldpd_conf
->thello_interval
!= 0)
268 vty_out (vty
, " discovery targeted-hello interval %u\n",
269 ldpd_conf
->thello_interval
);
271 if (ldpd_conf
->trans_pref
== DUAL_STACK_LDPOV4
)
273 " dual-stack transport-connection prefer ipv4\n");
275 if (ldpd_conf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
276 vty_out (vty
, " dual-stack cisco-interop\n");
278 RB_FOREACH(nbrp
, nbrp_head
, &ldpd_conf
->nbrp_tree
) {
279 if (nbrp
->flags
& F_NBRP_KEEPALIVE
)
280 vty_out (vty
, " neighbor %s session holdtime %u\n",
281 inet_ntoa(nbrp
->lsr_id
),nbrp
->keepalive
);
283 if (nbrp
->flags
& F_NBRP_GTSM
) {
284 if (nbrp
->gtsm_enabled
)
285 vty_out (vty
, " neighbor %s ttl-security hops "
286 "%u\n", inet_ntoa(nbrp
->lsr_id
),
289 vty_out (vty
, " neighbor %s ttl-security "
290 "disable\n",inet_ntoa(nbrp
->lsr_id
));
293 if (nbrp
->auth
.method
== AUTH_MD5SIG
)
294 vty_out (vty
, " neighbor %s password %s\n",
295 inet_ntoa(nbrp
->lsr_id
),nbrp
->auth
.md5key
);
298 ldp_af_config_write(vty
, AF_INET
, ldpd_conf
, &ldpd_conf
->ipv4
);
299 ldp_af_config_write(vty
, AF_INET6
, ldpd_conf
, &ldpd_conf
->ipv6
);
300 vty_out (vty
, " !\n");
301 vty_out (vty
, "!\n");
307 ldp_l2vpn_pw_config_write(struct vty
*vty
, struct l2vpn_pw
*pw
)
309 int missing_lsrid
= 0;
310 int missing_pwid
= 0;
312 vty_out (vty
, " !\n");
313 vty_out (vty
, " member pseudowire %s\n", pw
->ifname
);
315 if (pw
->lsr_id
.s_addr
!= INADDR_ANY
)
316 vty_out (vty
, " neighbor lsr-id %s\n",inet_ntoa(pw
->lsr_id
));
320 if (pw
->flags
& F_PW_STATIC_NBR_ADDR
)
321 vty_out (vty
, " neighbor address %s\n",
322 log_addr(pw
->af
, &pw
->addr
));
325 vty_out (vty
, " pw-id %u\n", pw
->pwid
);
329 if (!(pw
->flags
& F_PW_CWORD_CONF
))
330 vty_out (vty
, " control-word exclude\n");
332 if (!(pw
->flags
& F_PW_STATUSTLV_CONF
))
333 vty_out (vty
, " pw-status disable\n");
337 " ! Incomplete config, specify a neighbor lsr-id\n");
339 vty_out (vty
," ! Incomplete config, specify a pw-id\n");
343 ldp_l2vpn_config_write(struct vty
*vty
)
346 struct l2vpn_if
*lif
;
349 RB_FOREACH(l2vpn
, l2vpn_head
, &ldpd_conf
->l2vpn_tree
) {
350 vty_out (vty
, "l2vpn %s type vpls\n", l2vpn
->name
);
352 if (l2vpn
->pw_type
!= DEFAULT_PW_TYPE
)
353 vty_out (vty
, " vc type ethernet-tagged\n");
355 if (l2vpn
->mtu
!= DEFAULT_L2VPN_MTU
)
356 vty_out (vty
, " mtu %u\n", l2vpn
->mtu
);
358 if (l2vpn
->br_ifname
[0] != '\0')
359 vty_out (vty
, " bridge %s\n",l2vpn
->br_ifname
);
361 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
362 vty_out (vty
, " member interface %s\n",lif
->ifname
);
364 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
365 ldp_l2vpn_pw_config_write(vty
, pw
);
366 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
367 ldp_l2vpn_pw_config_write(vty
, pw
);
369 vty_out (vty
, " !\n");
370 vty_out (vty
, "!\n");
377 ldp_vty_get_af(struct vty
*vty
)
381 case LDP_IPV4_IFACE_NODE
:
384 case LDP_IPV6_IFACE_NODE
:
387 fatalx("ldp_vty_get_af: unexpected node");
392 ldp_iface_is_configured(struct ldpd_conf
*xconf
, const char *ifname
)
396 if (if_lookup_name(xconf
, ifname
))
399 RB_FOREACH(l2vpn
, l2vpn_head
, &xconf
->l2vpn_tree
) {
400 if (l2vpn_if_find(l2vpn
, ifname
))
402 if (l2vpn_pw_find(l2vpn
, ifname
))
410 ldp_vty_mpls_ldp(struct vty
*vty
, const char *negate
)
413 vty_conf
->flags
&= ~F_LDPD_ENABLED
;
415 vty
->node
= LDP_NODE
;
416 vty_conf
->flags
|= F_LDPD_ENABLED
;
419 ldp_config_apply(vty
, vty_conf
);
421 return (CMD_SUCCESS
);
425 ldp_vty_address_family(struct vty
*vty
, const char *negate
, const char *af_str
)
427 struct ldpd_af_conf
*af_conf
;
430 if (strcmp(af_str
, "ipv4") == 0) {
432 af_conf
= &vty_conf
->ipv4
;
433 } else if (strcmp(af_str
, "ipv6") == 0) {
435 af_conf
= &vty_conf
->ipv6
;
437 return (CMD_WARNING_CONFIG_FAILED
);
440 af_conf
->flags
&= ~F_LDPD_AF_ENABLED
;
441 ldp_config_apply(vty
, vty_conf
);
442 return (CMD_SUCCESS
);
447 vty
->node
= LDP_IPV4_NODE
;
450 vty
->node
= LDP_IPV6_NODE
;
453 fatalx("ldp_vty_address_family: unknown af");
455 af_conf
->flags
|= F_LDPD_AF_ENABLED
;
457 ldp_config_apply(vty
, vty_conf
);
459 return (CMD_SUCCESS
);
462 int ldp_vty_disc_holdtime(struct vty
*vty
, const char *negate
,
463 enum hello_type hello_type
, long secs
)
465 struct ldpd_af_conf
*af_conf
;
473 switch (hello_type
) {
475 vty_conf
->lhello_holdtime
= LINK_DFLT_HOLDTIME
;
478 vty_conf
->thello_holdtime
=
479 TARGETED_DFLT_HOLDTIME
;
483 switch (hello_type
) {
485 vty_conf
->lhello_holdtime
= secs
;
488 vty_conf
->thello_holdtime
= secs
;
492 ldp_config_apply(vty
, vty_conf
);
496 af
= ldp_vty_get_af(vty
);
497 af_conf
= ldp_af_conf_get(vty_conf
, af
);
500 switch (hello_type
) {
502 af_conf
->lhello_holdtime
= 0;
505 af_conf
->thello_holdtime
= 0;
509 switch (hello_type
) {
511 af_conf
->lhello_holdtime
= secs
;
514 af_conf
->thello_holdtime
= secs
;
518 ldp_config_apply(vty
, vty_conf
);
520 case LDP_IPV4_IFACE_NODE
:
521 case LDP_IPV6_IFACE_NODE
:
522 af
= ldp_vty_get_af(vty
);
523 iface
= VTY_GET_CONTEXT(iface
);
524 VTY_CHECK_CONTEXT(iface
);
526 ia
= iface_af_get(iface
, af
);
528 ia
->hello_holdtime
= 0;
530 ia
->hello_holdtime
= secs
;
532 ldp_config_apply(vty
, vty_conf
);
535 fatalx("ldp_vty_disc_holdtime: unexpected node");
538 return (CMD_SUCCESS
);
542 ldp_vty_disc_interval(struct vty
*vty
, const char *negate
,
543 enum hello_type hello_type
, long secs
)
545 struct ldpd_af_conf
*af_conf
;
553 switch (hello_type
) {
555 vty_conf
->lhello_interval
=
556 DEFAULT_HELLO_INTERVAL
;
559 vty_conf
->thello_interval
=
560 DEFAULT_HELLO_INTERVAL
;
564 switch (hello_type
) {
566 vty_conf
->lhello_interval
= secs
;
569 vty_conf
->thello_interval
= secs
;
573 ldp_config_apply(vty
, vty_conf
);
577 af
= ldp_vty_get_af(vty
);
578 af_conf
= ldp_af_conf_get(vty_conf
, af
);
581 switch (hello_type
) {
583 af_conf
->lhello_interval
= 0;
586 af_conf
->thello_interval
= 0;
590 switch (hello_type
) {
592 af_conf
->lhello_interval
= secs
;
595 af_conf
->thello_interval
= secs
;
599 ldp_config_apply(vty
, vty_conf
);
601 case LDP_IPV4_IFACE_NODE
:
602 case LDP_IPV6_IFACE_NODE
:
603 af
= ldp_vty_get_af(vty
);
604 iface
= VTY_GET_CONTEXT(iface
);
605 VTY_CHECK_CONTEXT(iface
);
607 ia
= iface_af_get(iface
, af
);
609 ia
->hello_interval
= 0;
611 ia
->hello_interval
= secs
;
613 ldp_config_apply(vty
, vty_conf
);
616 fatalx("ldp_vty_disc_interval: unexpected node");
619 return (CMD_SUCCESS
);
623 ldp_vty_targeted_hello_accept(struct vty
*vty
, const char *negate
,
624 const char *acl_from_str
)
626 struct ldpd_af_conf
*af_conf
;
629 af
= ldp_vty_get_af(vty
);
630 af_conf
= ldp_af_conf_get(vty_conf
, af
);
633 af_conf
->flags
&= ~F_LDPD_AF_THELLO_ACCEPT
;
634 af_conf
->acl_thello_accept_from
[0] = '\0';
636 af_conf
->flags
|= F_LDPD_AF_THELLO_ACCEPT
;
638 strlcpy(af_conf
->acl_thello_accept_from
, acl_from_str
,
639 sizeof(af_conf
->acl_thello_accept_from
));
641 af_conf
->acl_thello_accept_from
[0] = '\0';
644 ldp_config_apply(vty
, vty_conf
);
646 return (CMD_SUCCESS
);
650 ldp_vty_nbr_session_holdtime(struct vty
*vty
, const char *negate
,
651 struct in_addr lsr_id
, long secs
)
653 struct nbr_params
*nbrp
;
655 if (bad_addr_v4(lsr_id
)) {
656 vty_out (vty
, "%% Malformed address\n");
657 return (CMD_WARNING_CONFIG_FAILED
);
660 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
664 return (CMD_SUCCESS
);
667 nbrp
->flags
&= ~F_NBRP_KEEPALIVE
;
670 nbrp
= nbr_params_new(lsr_id
);
671 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
672 QOBJ_REG(nbrp
, nbr_params
);
673 } else if (nbrp
->keepalive
== secs
)
674 return (CMD_SUCCESS
);
676 nbrp
->keepalive
= secs
;
677 nbrp
->flags
|= F_NBRP_KEEPALIVE
;
680 ldp_config_apply(vty
, vty_conf
);
682 return (CMD_SUCCESS
);
686 ldp_vty_af_session_holdtime(struct vty
*vty
, const char *negate
, long secs
)
688 struct ldpd_af_conf
*af_conf
;
691 af
= ldp_vty_get_af(vty
);
692 af_conf
= ldp_af_conf_get(vty_conf
, af
);
695 af_conf
->keepalive
= DEFAULT_KEEPALIVE
;
697 af_conf
->keepalive
= secs
;
699 ldp_config_apply(vty
, vty_conf
);
701 return (CMD_SUCCESS
);
705 ldp_vty_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
711 af
= ldp_vty_get_af(vty
);
712 iface
= if_lookup_name(vty_conf
, ifname
);
716 return (CMD_SUCCESS
);
718 ia
= iface_af_get(iface
, af
);
719 if (ia
->enabled
== 0)
720 return (CMD_SUCCESS
);
723 ia
->hello_holdtime
= 0;
724 ia
->hello_interval
= 0;
726 ldp_config_apply(vty
, vty_conf
);
728 return (CMD_SUCCESS
);
732 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
733 vty_out (vty
,"%% Interface is already in use\n");
734 return (CMD_SUCCESS
);
737 iface
= if_new(ifname
);
738 ia
= iface_af_get(iface
, af
);
740 RB_INSERT(iface_head
, &vty_conf
->iface_tree
, iface
);
741 QOBJ_REG(iface
, iface
);
743 ldp_config_apply(vty
, vty_conf
);
745 ia
= iface_af_get(iface
, af
);
748 ldp_config_apply(vty
, vty_conf
);
754 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE
, iface
);
757 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE
, iface
);
763 return (CMD_SUCCESS
);
767 ldp_vty_trans_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
769 struct ldpd_af_conf
*af_conf
;
772 af
= ldp_vty_get_af(vty
);
773 af_conf
= ldp_af_conf_get(vty_conf
, af
);
776 memset(&af_conf
->trans_addr
, 0, sizeof(af_conf
->trans_addr
));
778 if (inet_pton(af
, addr_str
, &af_conf
->trans_addr
) != 1 ||
779 bad_addr(af
, &af_conf
->trans_addr
)) {
780 vty_out (vty
, "%% Malformed address\n");
781 return (CMD_SUCCESS
);
785 ldp_config_apply(vty
, vty_conf
);
787 return (CMD_SUCCESS
);
791 ldp_vty_neighbor_targeted(struct vty
*vty
, const char *negate
, const char *addr_str
)
794 union ldpd_addr addr
;
797 af
= ldp_vty_get_af(vty
);
799 if (inet_pton(af
, addr_str
, &addr
) != 1 ||
800 bad_addr(af
, &addr
)) {
801 vty_out (vty
, "%% Malformed address\n");
802 return (CMD_WARNING_CONFIG_FAILED
);
804 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
.v6
)) {
805 vty_out (vty
, "%% Address can not be link-local\n");
806 return (CMD_WARNING_CONFIG_FAILED
);
809 tnbr
= tnbr_find(vty_conf
, af
, &addr
);
813 return (CMD_SUCCESS
);
816 RB_REMOVE(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
819 ldp_config_apply(vty
, vty_conf
);
821 return (CMD_SUCCESS
);
825 return (CMD_SUCCESS
);
827 tnbr
= tnbr_new(af
, &addr
);
828 tnbr
->flags
|= F_TNBR_CONFIGURED
;
829 RB_INSERT(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
830 QOBJ_REG(tnbr
, tnbr
);
832 ldp_config_apply(vty
, vty_conf
);
834 return (CMD_SUCCESS
);
838 ldp_vty_label_advertise(struct vty
*vty
, const char *negate
, const char *acl_to_str
,
839 const char *acl_for_str
)
841 struct ldpd_af_conf
*af_conf
;
844 af
= ldp_vty_get_af(vty
);
845 af_conf
= ldp_af_conf_get(vty_conf
, af
);
848 af_conf
->acl_label_advertise_to
[0] = '\0';
849 af_conf
->acl_label_advertise_for
[0] = '\0';
852 strlcpy(af_conf
->acl_label_advertise_to
, acl_to_str
,
853 sizeof(af_conf
->acl_label_advertise_to
));
855 af_conf
->acl_label_advertise_to
[0] = '\0';
857 strlcpy(af_conf
->acl_label_advertise_for
, acl_for_str
,
858 sizeof(af_conf
->acl_label_advertise_for
));
860 af_conf
->acl_label_advertise_for
[0] = '\0';
863 ldp_config_apply(vty
, vty_conf
);
865 return (CMD_SUCCESS
);
869 ldp_vty_label_allocate(struct vty
*vty
, const char *negate
, const char *host_routes
,
870 const char *acl_for_str
)
872 struct ldpd_af_conf
*af_conf
;
875 af
= ldp_vty_get_af(vty
);
876 af_conf
= ldp_af_conf_get(vty_conf
, af
);
878 af_conf
->flags
&= ~F_LDPD_AF_ALLOCHOSTONLY
;
879 af_conf
->acl_label_allocate_for
[0] = '\0';
882 af_conf
->flags
|= F_LDPD_AF_ALLOCHOSTONLY
;
884 strlcpy(af_conf
->acl_label_allocate_for
, acl_for_str
,
885 sizeof(af_conf
->acl_label_allocate_for
));
888 ldp_config_apply(vty
, vty_conf
);
890 return (CMD_SUCCESS
);
894 ldp_vty_label_expnull(struct vty
*vty
, const char *negate
, const char *acl_for_str
)
896 struct ldpd_af_conf
*af_conf
;
899 af
= ldp_vty_get_af(vty
);
900 af_conf
= ldp_af_conf_get(vty_conf
, af
);
903 af_conf
->flags
&= ~F_LDPD_AF_EXPNULL
;
904 af_conf
->acl_label_expnull_for
[0] = '\0';
906 af_conf
->flags
|= F_LDPD_AF_EXPNULL
;
908 strlcpy(af_conf
->acl_label_expnull_for
, acl_for_str
,
909 sizeof(af_conf
->acl_label_expnull_for
));
911 af_conf
->acl_label_expnull_for
[0] = '\0';
914 ldp_config_apply(vty
, vty_conf
);
916 return (CMD_SUCCESS
);
920 ldp_vty_label_accept(struct vty
*vty
, const char *negate
, const char *acl_from_str
,
921 const char *acl_for_str
)
923 struct ldpd_af_conf
*af_conf
;
926 af
= ldp_vty_get_af(vty
);
927 af_conf
= ldp_af_conf_get(vty_conf
, af
);
930 af_conf
->acl_label_accept_from
[0] = '\0';
931 af_conf
->acl_label_accept_for
[0] = '\0';
934 strlcpy(af_conf
->acl_label_accept_from
, acl_from_str
,
935 sizeof(af_conf
->acl_label_accept_from
));
937 af_conf
->acl_label_accept_from
[0] = '\0';
939 strlcpy(af_conf
->acl_label_accept_for
, acl_for_str
,
940 sizeof(af_conf
->acl_label_accept_for
));
942 af_conf
->acl_label_accept_for
[0] = '\0';
945 ldp_config_apply(vty
, vty_conf
);
947 return (CMD_SUCCESS
);
951 ldp_vty_ttl_security(struct vty
*vty
, const char *negate
)
953 struct ldpd_af_conf
*af_conf
;
956 af
= ldp_vty_get_af(vty
);
957 af_conf
= ldp_af_conf_get(vty_conf
, af
);
960 af_conf
->flags
&= ~F_LDPD_AF_NO_GTSM
;
962 af_conf
->flags
|= F_LDPD_AF_NO_GTSM
;
964 ldp_config_apply(vty
, vty_conf
);
966 return (CMD_SUCCESS
);
970 ldp_vty_router_id(struct vty
*vty
, const char *negate
, struct in_addr address
)
973 vty_conf
->rtr_id
.s_addr
= INADDR_ANY
;
975 if (bad_addr_v4(address
)) {
976 vty_out (vty
, "%% Malformed address\n");
977 return (CMD_SUCCESS
);
979 vty_conf
->rtr_id
= address
;
982 ldp_config_apply(vty
, vty_conf
);
984 return (CMD_SUCCESS
);
988 ldp_vty_ds_cisco_interop(struct vty
*vty
, const char * negate
)
991 vty_conf
->flags
&= ~F_LDPD_DS_CISCO_INTEROP
;
993 vty_conf
->flags
|= F_LDPD_DS_CISCO_INTEROP
;
995 ldp_config_apply(vty
, vty_conf
);
997 return (CMD_SUCCESS
);
1001 ldp_vty_trans_pref_ipv4(struct vty
*vty
, const char *negate
)
1004 vty_conf
->trans_pref
= DUAL_STACK_LDPOV6
;
1006 vty_conf
->trans_pref
= DUAL_STACK_LDPOV4
;
1008 ldp_config_apply(vty
, vty_conf
);
1010 return (CMD_SUCCESS
);
1014 ldp_vty_neighbor_password(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
,
1015 const char *password_str
)
1017 size_t password_len
;
1018 struct nbr_params
*nbrp
;
1020 if (bad_addr_v4(lsr_id
)) {
1021 vty_out (vty
, "%% Malformed address\n");
1022 return (CMD_WARNING_CONFIG_FAILED
);
1025 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1029 return (CMD_SUCCESS
);
1031 memset(&nbrp
->auth
, 0, sizeof(nbrp
->auth
));
1032 nbrp
->auth
.method
= AUTH_NONE
;
1035 nbrp
= nbr_params_new(lsr_id
);
1036 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1037 QOBJ_REG(nbrp
, nbr_params
);
1038 } else if (nbrp
->auth
.method
== AUTH_MD5SIG
&&
1039 strcmp(nbrp
->auth
.md5key
, password_str
) == 0)
1040 return (CMD_SUCCESS
);
1042 password_len
= strlcpy(nbrp
->auth
.md5key
, password_str
,
1043 sizeof(nbrp
->auth
.md5key
));
1044 if (password_len
>= sizeof(nbrp
->auth
.md5key
))
1045 vty_out(vty
, "%% password has been truncated to %zu "
1046 "characters.", sizeof(nbrp
->auth
.md5key
) - 1);
1047 nbrp
->auth
.md5key_len
= password_len
;
1048 nbrp
->auth
.method
= AUTH_MD5SIG
;
1051 ldp_config_apply(vty
, vty_conf
);
1053 return (CMD_SUCCESS
);
1057 ldp_vty_neighbor_ttl_security(struct vty
*vty
, const char *negate
,
1058 struct in_addr lsr_id
, const char *hops_str
)
1060 struct nbr_params
*nbrp
;
1064 if (bad_addr_v4(lsr_id
)) {
1065 vty_out (vty
, "%% Malformed address\n");
1066 return (CMD_WARNING_CONFIG_FAILED
);
1070 hops
= strtol(hops_str
, &ep
, 10);
1071 if (*ep
!= '\0' || hops
< 1 || hops
> 254) {
1072 vty_out (vty
, "%% Invalid hop count\n");
1073 return (CMD_SUCCESS
);
1077 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1081 return (CMD_SUCCESS
);
1083 nbrp
->flags
&= ~(F_NBRP_GTSM
|F_NBRP_GTSM_HOPS
);
1084 nbrp
->gtsm_enabled
= 0;
1085 nbrp
->gtsm_hops
= 0;
1088 nbrp
= nbr_params_new(lsr_id
);
1089 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1090 QOBJ_REG(nbrp
, nbr_params
);
1093 nbrp
->flags
|= F_NBRP_GTSM
;
1094 nbrp
->flags
&= ~F_NBRP_GTSM_HOPS
;
1096 nbrp
->gtsm_enabled
= 1;
1097 nbrp
->gtsm_hops
= hops
;
1098 nbrp
->flags
|= F_NBRP_GTSM_HOPS
;
1100 nbrp
->gtsm_enabled
= 0;
1103 ldp_config_apply(vty
, vty_conf
);
1105 return (CMD_SUCCESS
);
1109 ldp_vty_l2vpn(struct vty
*vty
, const char *negate
, const char *name_str
)
1111 struct l2vpn
*l2vpn
;
1112 struct l2vpn_if
*lif
;
1113 struct l2vpn_pw
*pw
;
1115 l2vpn
= l2vpn_find(vty_conf
, name_str
);
1119 return (CMD_SUCCESS
);
1121 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
1123 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
1125 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
1128 RB_REMOVE(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1131 ldp_config_apply(vty
, vty_conf
);
1133 return (CMD_SUCCESS
);
1137 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1138 return (CMD_SUCCESS
);
1141 l2vpn
= l2vpn_new(name_str
);
1142 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1143 RB_INSERT(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1144 QOBJ_REG(l2vpn
, l2vpn
);
1146 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1148 ldp_config_apply(vty
, vty_conf
);
1150 return (CMD_SUCCESS
);
1154 ldp_vty_l2vpn_bridge(struct vty
*vty
, const char *negate
, const char *ifname
)
1156 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1159 memset(l2vpn
->br_ifname
, 0, sizeof(l2vpn
->br_ifname
));
1161 strlcpy(l2vpn
->br_ifname
, ifname
, sizeof(l2vpn
->br_ifname
));
1163 ldp_config_apply(vty
, vty_conf
);
1165 return (CMD_SUCCESS
);
1169 ldp_vty_l2vpn_mtu(struct vty
*vty
, const char *negate
, long mtu
)
1171 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1174 l2vpn
->mtu
= DEFAULT_L2VPN_MTU
;
1178 ldp_config_apply(vty
, vty_conf
);
1180 return (CMD_SUCCESS
);
1184 ldp_vty_l2vpn_pwtype(struct vty
*vty
, const char *negate
, const char *type_str
)
1186 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1189 if (strcmp(type_str
, "ethernet") == 0)
1190 pw_type
= PW_TYPE_ETHERNET
;
1192 pw_type
= PW_TYPE_ETHERNET_TAGGED
;
1195 l2vpn
->pw_type
= DEFAULT_PW_TYPE
;
1197 l2vpn
->pw_type
= pw_type
;
1199 ldp_config_apply(vty
, vty_conf
);
1201 return (CMD_SUCCESS
);
1205 ldp_vty_l2vpn_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
1207 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1208 struct l2vpn_if
*lif
;
1210 lif
= l2vpn_if_find(l2vpn
, ifname
);
1214 return (CMD_SUCCESS
);
1217 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1220 ldp_config_apply(vty
, vty_conf
);
1222 return (CMD_SUCCESS
);
1226 return (CMD_SUCCESS
);
1228 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1229 vty_out (vty
, "%% Interface is already in use\n");
1230 return (CMD_SUCCESS
);
1233 lif
= l2vpn_if_new(l2vpn
, ifname
);
1234 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1235 QOBJ_REG(lif
, l2vpn_if
);
1237 ldp_config_apply(vty
, vty_conf
);
1239 return (CMD_SUCCESS
);
1243 ldp_vty_l2vpn_pseudowire(struct vty
*vty
, const char *negate
, const char *ifname
)
1245 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1246 struct l2vpn_pw
*pw
;
1248 pw
= l2vpn_pw_find(l2vpn
, ifname
);
1252 return (CMD_SUCCESS
);
1255 if (pw
->lsr_id
.s_addr
== INADDR_ANY
|| pw
->pwid
== 0)
1256 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1258 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1261 ldp_config_apply(vty
, vty_conf
);
1263 return (CMD_SUCCESS
);
1267 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1268 return (CMD_SUCCESS
);
1271 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1272 vty_out (vty
, "%% Interface is already in use\n");
1273 return (CMD_SUCCESS
);
1276 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1277 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1278 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1279 QOBJ_REG(pw
, l2vpn_pw
);
1281 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1283 ldp_config_apply(vty
, vty_conf
);
1285 return (CMD_SUCCESS
);
1289 ldp_vty_l2vpn_pw_cword(struct vty
*vty
, const char *negate
, const char *preference_str
)
1291 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1294 pw
->flags
|= F_PW_CWORD_CONF
;
1296 if (preference_str
[0] == 'e')
1297 pw
->flags
&= ~F_PW_CWORD_CONF
;
1299 pw
->flags
|= F_PW_CWORD_CONF
;
1302 ldp_config_apply(vty
, vty_conf
);
1304 return (CMD_SUCCESS
);
1308 ldp_vty_l2vpn_pw_nbr_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
1310 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1312 union ldpd_addr addr
;
1314 if (ldp_get_address(addr_str
, &af
, &addr
) == -1 ||
1315 bad_addr(af
, &addr
)) {
1316 vty_out (vty
, "%% Malformed address\n");
1317 return (CMD_WARNING_CONFIG_FAILED
);
1322 memset(&pw
->addr
, 0, sizeof(pw
->addr
));
1323 pw
->flags
&= ~F_PW_STATIC_NBR_ADDR
;
1327 pw
->flags
|= F_PW_STATIC_NBR_ADDR
;
1330 ldp_config_apply(vty
, vty_conf
);
1332 return (CMD_SUCCESS
);
1336 ldp_vty_l2vpn_pw_nbr_id(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
)
1338 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1340 if (bad_addr_v4(lsr_id
)) {
1341 vty_out (vty
, "%% Malformed address\n");
1342 return (CMD_WARNING_CONFIG_FAILED
);
1346 pw
->lsr_id
.s_addr
= INADDR_ANY
;
1348 pw
->lsr_id
= lsr_id
;
1350 ldp_config_apply(vty
, vty_conf
);
1352 return (CMD_SUCCESS
);
1356 ldp_vty_l2vpn_pw_pwid(struct vty
*vty
, const char *negate
, long pwid
)
1358 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1365 ldp_config_apply(vty
, vty_conf
);
1367 return (CMD_SUCCESS
);
1371 ldp_vty_l2vpn_pw_pwstatus(struct vty
*vty
, const char *negate
)
1373 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1376 pw
->flags
|= F_PW_STATUSTLV_CONF
;
1378 pw
->flags
&= ~F_PW_STATUSTLV_CONF
;
1380 ldp_config_apply(vty
, vty_conf
);
1382 return (CMD_SUCCESS
);
1386 iface_new_api(struct ldpd_conf
*conf
, const char *name
)
1388 const char *ifname
= name
;
1389 struct iface
*iface
;
1391 if (ldp_iface_is_configured(conf
, ifname
))
1394 iface
= if_new(name
);
1395 RB_INSERT(iface_head
, &conf
->iface_tree
, iface
);
1396 QOBJ_REG(iface
, iface
);
1401 iface_del_api(struct ldpd_conf
*conf
, struct iface
*iface
)
1404 RB_REMOVE(iface_head
, &conf
->iface_tree
, iface
);
1409 tnbr_new_api(struct ldpd_conf
*conf
, int af
, union ldpd_addr
*addr
)
1413 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
->v6
))
1416 if (tnbr_find(conf
, af
, addr
))
1419 tnbr
= tnbr_new(af
, addr
);
1420 tnbr
->flags
|= F_TNBR_CONFIGURED
;
1421 RB_INSERT(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1422 QOBJ_REG(tnbr
, tnbr
);
1427 tnbr_del_api(struct ldpd_conf
*conf
, struct tnbr
*tnbr
)
1430 RB_REMOVE(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1435 nbrp_new_api(struct ldpd_conf
*conf
, struct in_addr lsr_id
)
1437 struct nbr_params
*nbrp
;
1439 if (nbr_params_find(conf
, lsr_id
))
1442 nbrp
= nbr_params_new(lsr_id
);
1443 RB_INSERT(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1444 QOBJ_REG(nbrp
, nbr_params
);
1449 nbrp_del_api(struct ldpd_conf
*conf
, struct nbr_params
*nbrp
)
1452 RB_REMOVE(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1457 l2vpn_new_api(struct ldpd_conf
*conf
, const char *name
)
1459 struct l2vpn
*l2vpn
;
1461 if (l2vpn_find(conf
, name
))
1464 l2vpn
= l2vpn_new(name
);
1465 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1466 RB_INSERT(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1467 QOBJ_REG(l2vpn
, l2vpn
);
1472 l2vpn_del_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
)
1474 struct l2vpn_if
*lif
;
1475 struct l2vpn_pw
*pw
;
1477 while ((lif
= RB_ROOT(l2vpn_if_head
, &l2vpn
->if_tree
)) != NULL
) {
1479 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1482 while ((pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_tree
)) != NULL
) {
1484 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1487 while ((pw
= RB_ROOT(l2vpn_pw_head
,
1488 &l2vpn
->pw_inactive_tree
)) != NULL
) {
1490 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1494 RB_REMOVE(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1499 l2vpn_if_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1502 struct l2vpn_if
*lif
;
1504 if (ldp_iface_is_configured(conf
, ifname
))
1507 lif
= l2vpn_if_new(l2vpn
, ifname
);
1508 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1509 QOBJ_REG(lif
, l2vpn_if
);
1514 l2vpn_if_del_api(struct l2vpn
*l2vpn
, struct l2vpn_if
*lif
)
1517 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1522 l2vpn_pw_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1525 struct l2vpn_pw
*pw
;
1527 if (ldp_iface_is_configured(conf
, ifname
))
1530 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1531 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1532 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1533 QOBJ_REG(pw
, l2vpn_pw
);
1538 l2vpn_pw_del_api(struct l2vpn
*l2vpn
, struct l2vpn_pw
*pw
)
1541 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);