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
, " !\n");
237 vty_out(vty
, " exit-address-family\n");
241 ldp_config_write(struct vty
*vty
)
243 struct nbr_params
*nbrp
;
245 if (!(ldpd_conf
->flags
& F_LDPD_ENABLED
))
248 vty_out (vty
, "mpls ldp\n");
250 if (ldpd_conf
->rtr_id
.s_addr
!= 0)
251 vty_out (vty
, " router-id %s\n",
252 inet_ntoa(ldpd_conf
->rtr_id
));
254 if (ldpd_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
255 ldpd_conf
->lhello_holdtime
!= 0)
256 vty_out (vty
, " discovery hello holdtime %u\n",
257 ldpd_conf
->lhello_holdtime
);
258 if (ldpd_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
259 ldpd_conf
->lhello_interval
!= 0)
260 vty_out (vty
, " discovery hello interval %u\n",
261 ldpd_conf
->lhello_interval
);
263 if (ldpd_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
264 ldpd_conf
->thello_holdtime
!= 0)
265 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
266 ldpd_conf
->thello_holdtime
);
267 if (ldpd_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
268 ldpd_conf
->thello_interval
!= 0)
269 vty_out (vty
, " discovery targeted-hello interval %u\n",
270 ldpd_conf
->thello_interval
);
272 if (ldpd_conf
->trans_pref
== DUAL_STACK_LDPOV4
)
274 " dual-stack transport-connection prefer ipv4\n");
276 if (ldpd_conf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
277 vty_out (vty
, " dual-stack cisco-interop\n");
279 RB_FOREACH(nbrp
, nbrp_head
, &ldpd_conf
->nbrp_tree
) {
280 if (nbrp
->flags
& F_NBRP_KEEPALIVE
)
281 vty_out (vty
, " neighbor %s session holdtime %u\n",
282 inet_ntoa(nbrp
->lsr_id
),nbrp
->keepalive
);
284 if (nbrp
->flags
& F_NBRP_GTSM
) {
285 if (nbrp
->gtsm_enabled
)
286 vty_out (vty
, " neighbor %s ttl-security hops "
287 "%u\n", inet_ntoa(nbrp
->lsr_id
),
290 vty_out (vty
, " neighbor %s ttl-security "
291 "disable\n",inet_ntoa(nbrp
->lsr_id
));
294 if (nbrp
->auth
.method
== AUTH_MD5SIG
)
295 vty_out (vty
, " neighbor %s password %s\n",
296 inet_ntoa(nbrp
->lsr_id
),nbrp
->auth
.md5key
);
299 ldp_af_config_write(vty
, AF_INET
, ldpd_conf
, &ldpd_conf
->ipv4
);
300 ldp_af_config_write(vty
, AF_INET6
, ldpd_conf
, &ldpd_conf
->ipv6
);
301 vty_out (vty
, " !\n");
302 vty_out (vty
, "!\n");
308 ldp_l2vpn_pw_config_write(struct vty
*vty
, struct l2vpn_pw
*pw
)
310 int missing_lsrid
= 0;
311 int missing_pwid
= 0;
313 vty_out (vty
, " !\n");
314 vty_out (vty
, " member pseudowire %s\n", pw
->ifname
);
316 if (pw
->lsr_id
.s_addr
!= INADDR_ANY
)
317 vty_out (vty
, " neighbor lsr-id %s\n",inet_ntoa(pw
->lsr_id
));
321 if (pw
->flags
& F_PW_STATIC_NBR_ADDR
)
322 vty_out (vty
, " neighbor address %s\n",
323 log_addr(pw
->af
, &pw
->addr
));
326 vty_out (vty
, " pw-id %u\n", pw
->pwid
);
330 if (!(pw
->flags
& F_PW_CWORD_CONF
))
331 vty_out (vty
, " control-word exclude\n");
333 if (!(pw
->flags
& F_PW_STATUSTLV_CONF
))
334 vty_out (vty
, " pw-status disable\n");
338 " ! Incomplete config, specify a neighbor lsr-id\n");
340 vty_out (vty
," ! Incomplete config, specify a pw-id\n");
344 ldp_l2vpn_config_write(struct vty
*vty
)
347 struct l2vpn_if
*lif
;
350 RB_FOREACH(l2vpn
, l2vpn_head
, &ldpd_conf
->l2vpn_tree
) {
351 vty_out (vty
, "l2vpn %s type vpls\n", l2vpn
->name
);
353 if (l2vpn
->pw_type
!= DEFAULT_PW_TYPE
)
354 vty_out (vty
, " vc type ethernet-tagged\n");
356 if (l2vpn
->mtu
!= DEFAULT_L2VPN_MTU
)
357 vty_out (vty
, " mtu %u\n", l2vpn
->mtu
);
359 if (l2vpn
->br_ifname
[0] != '\0')
360 vty_out (vty
, " bridge %s\n",l2vpn
->br_ifname
);
362 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
363 vty_out (vty
, " member interface %s\n",lif
->ifname
);
365 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
366 ldp_l2vpn_pw_config_write(vty
, pw
);
367 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
368 ldp_l2vpn_pw_config_write(vty
, pw
);
370 vty_out (vty
, " !\n");
371 vty_out (vty
, "!\n");
378 ldp_vty_get_af(struct vty
*vty
)
382 case LDP_IPV4_IFACE_NODE
:
385 case LDP_IPV6_IFACE_NODE
:
388 fatalx("ldp_vty_get_af: unexpected node");
393 ldp_iface_is_configured(struct ldpd_conf
*xconf
, const char *ifname
)
397 if (if_lookup_name(xconf
, ifname
))
400 RB_FOREACH(l2vpn
, l2vpn_head
, &xconf
->l2vpn_tree
) {
401 if (l2vpn_if_find(l2vpn
, ifname
))
403 if (l2vpn_pw_find(l2vpn
, ifname
))
411 ldp_vty_mpls_ldp(struct vty
*vty
, const char *negate
)
414 vty_conf
->flags
&= ~F_LDPD_ENABLED
;
416 vty
->node
= LDP_NODE
;
417 vty_conf
->flags
|= F_LDPD_ENABLED
;
420 ldp_config_apply(vty
, vty_conf
);
422 return (CMD_SUCCESS
);
426 ldp_vty_address_family(struct vty
*vty
, const char *negate
, const char *af_str
)
428 struct ldpd_af_conf
*af_conf
;
432 return (CMD_WARNING_CONFIG_FAILED
);
434 if (strcmp(af_str
, "ipv4") == 0) {
436 af_conf
= &vty_conf
->ipv4
;
437 } else if (strcmp(af_str
, "ipv6") == 0) {
439 af_conf
= &vty_conf
->ipv6
;
441 return (CMD_WARNING_CONFIG_FAILED
);
444 af_conf
->flags
&= ~F_LDPD_AF_ENABLED
;
445 ldp_config_apply(vty
, vty_conf
);
446 return (CMD_SUCCESS
);
451 vty
->node
= LDP_IPV4_NODE
;
454 vty
->node
= LDP_IPV6_NODE
;
457 fatalx("ldp_vty_address_family: unknown af");
459 af_conf
->flags
|= F_LDPD_AF_ENABLED
;
461 ldp_config_apply(vty
, vty_conf
);
463 return (CMD_SUCCESS
);
466 int ldp_vty_disc_holdtime(struct vty
*vty
, const char *negate
,
467 enum hello_type hello_type
, long secs
)
469 struct ldpd_af_conf
*af_conf
;
477 switch (hello_type
) {
479 vty_conf
->lhello_holdtime
= LINK_DFLT_HOLDTIME
;
482 vty_conf
->thello_holdtime
=
483 TARGETED_DFLT_HOLDTIME
;
487 switch (hello_type
) {
489 vty_conf
->lhello_holdtime
= secs
;
492 vty_conf
->thello_holdtime
= secs
;
496 ldp_config_apply(vty
, vty_conf
);
500 af
= ldp_vty_get_af(vty
);
501 af_conf
= ldp_af_conf_get(vty_conf
, af
);
504 switch (hello_type
) {
506 af_conf
->lhello_holdtime
= 0;
509 af_conf
->thello_holdtime
= 0;
513 switch (hello_type
) {
515 af_conf
->lhello_holdtime
= secs
;
518 af_conf
->thello_holdtime
= secs
;
522 ldp_config_apply(vty
, vty_conf
);
524 case LDP_IPV4_IFACE_NODE
:
525 case LDP_IPV6_IFACE_NODE
:
526 af
= ldp_vty_get_af(vty
);
527 iface
= VTY_GET_CONTEXT(iface
);
528 VTY_CHECK_CONTEXT(iface
);
530 ia
= iface_af_get(iface
, af
);
532 ia
->hello_holdtime
= 0;
534 ia
->hello_holdtime
= secs
;
536 ldp_config_apply(vty
, vty_conf
);
539 fatalx("ldp_vty_disc_holdtime: unexpected node");
542 return (CMD_SUCCESS
);
546 ldp_vty_disc_interval(struct vty
*vty
, const char *negate
,
547 enum hello_type hello_type
, long secs
)
549 struct ldpd_af_conf
*af_conf
;
557 switch (hello_type
) {
559 vty_conf
->lhello_interval
=
560 DEFAULT_HELLO_INTERVAL
;
563 vty_conf
->thello_interval
=
564 DEFAULT_HELLO_INTERVAL
;
568 switch (hello_type
) {
570 vty_conf
->lhello_interval
= secs
;
573 vty_conf
->thello_interval
= secs
;
577 ldp_config_apply(vty
, vty_conf
);
581 af
= ldp_vty_get_af(vty
);
582 af_conf
= ldp_af_conf_get(vty_conf
, af
);
585 switch (hello_type
) {
587 af_conf
->lhello_interval
= 0;
590 af_conf
->thello_interval
= 0;
594 switch (hello_type
) {
596 af_conf
->lhello_interval
= secs
;
599 af_conf
->thello_interval
= secs
;
603 ldp_config_apply(vty
, vty_conf
);
605 case LDP_IPV4_IFACE_NODE
:
606 case LDP_IPV6_IFACE_NODE
:
607 af
= ldp_vty_get_af(vty
);
608 iface
= VTY_GET_CONTEXT(iface
);
609 VTY_CHECK_CONTEXT(iface
);
611 ia
= iface_af_get(iface
, af
);
613 ia
->hello_interval
= 0;
615 ia
->hello_interval
= secs
;
617 ldp_config_apply(vty
, vty_conf
);
620 fatalx("ldp_vty_disc_interval: unexpected node");
623 return (CMD_SUCCESS
);
627 ldp_vty_targeted_hello_accept(struct vty
*vty
, const char *negate
,
628 const char *acl_from_str
)
630 struct ldpd_af_conf
*af_conf
;
633 af
= ldp_vty_get_af(vty
);
634 af_conf
= ldp_af_conf_get(vty_conf
, af
);
637 af_conf
->flags
&= ~F_LDPD_AF_THELLO_ACCEPT
;
638 af_conf
->acl_thello_accept_from
[0] = '\0';
640 af_conf
->flags
|= F_LDPD_AF_THELLO_ACCEPT
;
642 strlcpy(af_conf
->acl_thello_accept_from
, acl_from_str
,
643 sizeof(af_conf
->acl_thello_accept_from
));
645 af_conf
->acl_thello_accept_from
[0] = '\0';
648 ldp_config_apply(vty
, vty_conf
);
650 return (CMD_SUCCESS
);
654 ldp_vty_nbr_session_holdtime(struct vty
*vty
, const char *negate
,
655 struct in_addr lsr_id
, long secs
)
657 struct nbr_params
*nbrp
;
659 if (bad_addr_v4(lsr_id
)) {
660 vty_out (vty
, "%% Malformed address\n");
661 return (CMD_WARNING_CONFIG_FAILED
);
664 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
668 return (CMD_SUCCESS
);
671 nbrp
->flags
&= ~F_NBRP_KEEPALIVE
;
674 nbrp
= nbr_params_new(lsr_id
);
675 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
676 QOBJ_REG(nbrp
, nbr_params
);
677 } else if (nbrp
->keepalive
== secs
)
678 return (CMD_SUCCESS
);
680 nbrp
->keepalive
= secs
;
681 nbrp
->flags
|= F_NBRP_KEEPALIVE
;
684 ldp_config_apply(vty
, vty_conf
);
686 return (CMD_SUCCESS
);
690 ldp_vty_af_session_holdtime(struct vty
*vty
, const char *negate
, long secs
)
692 struct ldpd_af_conf
*af_conf
;
695 af
= ldp_vty_get_af(vty
);
696 af_conf
= ldp_af_conf_get(vty_conf
, af
);
699 af_conf
->keepalive
= DEFAULT_KEEPALIVE
;
701 af_conf
->keepalive
= secs
;
703 ldp_config_apply(vty
, vty_conf
);
705 return (CMD_SUCCESS
);
709 ldp_vty_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
715 if (ifname
== NULL
) {
716 vty_out (vty
, "%% Missing IF name\n");
717 return (CMD_WARNING_CONFIG_FAILED
);
720 af
= ldp_vty_get_af(vty
);
721 iface
= if_lookup_name(vty_conf
, ifname
);
725 return (CMD_SUCCESS
);
727 ia
= iface_af_get(iface
, af
);
728 if (ia
->enabled
== 0)
729 return (CMD_SUCCESS
);
732 ia
->hello_holdtime
= 0;
733 ia
->hello_interval
= 0;
735 ldp_config_apply(vty
, vty_conf
);
737 return (CMD_SUCCESS
);
741 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
742 vty_out (vty
,"%% Interface is already in use\n");
743 return (CMD_SUCCESS
);
746 iface
= if_new(ifname
);
747 ia
= iface_af_get(iface
, af
);
749 RB_INSERT(iface_head
, &vty_conf
->iface_tree
, iface
);
750 QOBJ_REG(iface
, iface
);
752 ldp_config_apply(vty
, vty_conf
);
754 ia
= iface_af_get(iface
, af
);
757 ldp_config_apply(vty
, vty_conf
);
763 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE
, iface
);
766 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE
, iface
);
772 return (CMD_SUCCESS
);
776 ldp_vty_trans_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
778 struct ldpd_af_conf
*af_conf
;
781 af
= ldp_vty_get_af(vty
);
782 af_conf
= ldp_af_conf_get(vty_conf
, af
);
785 memset(&af_conf
->trans_addr
, 0, sizeof(af_conf
->trans_addr
));
788 || inet_pton(af
, addr_str
, &af_conf
->trans_addr
) != 1
789 || bad_addr(af
, &af_conf
->trans_addr
)) {
790 vty_out (vty
, "%% Malformed address\n");
791 return (CMD_SUCCESS
);
795 ldp_config_apply(vty
, vty_conf
);
797 return (CMD_SUCCESS
);
801 ldp_vty_neighbor_targeted(struct vty
*vty
, const char *negate
, const char *addr_str
)
804 union ldpd_addr addr
;
807 af
= ldp_vty_get_af(vty
);
809 if (addr_str
== NULL
|| inet_pton(af
, addr_str
, &addr
) != 1 ||
810 bad_addr(af
, &addr
)) {
811 vty_out (vty
, "%% Malformed address\n");
812 return (CMD_WARNING_CONFIG_FAILED
);
814 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
.v6
)) {
815 vty_out (vty
, "%% Address can not be link-local\n");
816 return (CMD_WARNING_CONFIG_FAILED
);
819 tnbr
= tnbr_find(vty_conf
, af
, &addr
);
823 return (CMD_SUCCESS
);
826 RB_REMOVE(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
829 ldp_config_apply(vty
, vty_conf
);
831 return (CMD_SUCCESS
);
835 return (CMD_SUCCESS
);
837 tnbr
= tnbr_new(af
, &addr
);
838 tnbr
->flags
|= F_TNBR_CONFIGURED
;
839 RB_INSERT(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
840 QOBJ_REG(tnbr
, tnbr
);
842 ldp_config_apply(vty
, vty_conf
);
844 return (CMD_SUCCESS
);
848 ldp_vty_label_advertise(struct vty
*vty
, const char *negate
, const char *acl_to_str
,
849 const char *acl_for_str
)
851 struct ldpd_af_conf
*af_conf
;
854 af
= ldp_vty_get_af(vty
);
855 af_conf
= ldp_af_conf_get(vty_conf
, af
);
858 af_conf
->acl_label_advertise_to
[0] = '\0';
859 af_conf
->acl_label_advertise_for
[0] = '\0';
862 strlcpy(af_conf
->acl_label_advertise_to
, acl_to_str
,
863 sizeof(af_conf
->acl_label_advertise_to
));
865 af_conf
->acl_label_advertise_to
[0] = '\0';
867 strlcpy(af_conf
->acl_label_advertise_for
, acl_for_str
,
868 sizeof(af_conf
->acl_label_advertise_for
));
870 af_conf
->acl_label_advertise_for
[0] = '\0';
873 ldp_config_apply(vty
, vty_conf
);
875 return (CMD_SUCCESS
);
879 ldp_vty_label_allocate(struct vty
*vty
, const char *negate
, const char *host_routes
,
880 const char *acl_for_str
)
882 struct ldpd_af_conf
*af_conf
;
885 af
= ldp_vty_get_af(vty
);
886 af_conf
= ldp_af_conf_get(vty_conf
, af
);
888 af_conf
->flags
&= ~F_LDPD_AF_ALLOCHOSTONLY
;
889 af_conf
->acl_label_allocate_for
[0] = '\0';
892 af_conf
->flags
|= F_LDPD_AF_ALLOCHOSTONLY
;
894 strlcpy(af_conf
->acl_label_allocate_for
, acl_for_str
,
895 sizeof(af_conf
->acl_label_allocate_for
));
898 ldp_config_apply(vty
, vty_conf
);
900 return (CMD_SUCCESS
);
904 ldp_vty_label_expnull(struct vty
*vty
, const char *negate
, const char *acl_for_str
)
906 struct ldpd_af_conf
*af_conf
;
909 af
= ldp_vty_get_af(vty
);
910 af_conf
= ldp_af_conf_get(vty_conf
, af
);
913 af_conf
->flags
&= ~F_LDPD_AF_EXPNULL
;
914 af_conf
->acl_label_expnull_for
[0] = '\0';
916 af_conf
->flags
|= F_LDPD_AF_EXPNULL
;
918 strlcpy(af_conf
->acl_label_expnull_for
, acl_for_str
,
919 sizeof(af_conf
->acl_label_expnull_for
));
921 af_conf
->acl_label_expnull_for
[0] = '\0';
924 ldp_config_apply(vty
, vty_conf
);
926 return (CMD_SUCCESS
);
930 ldp_vty_label_accept(struct vty
*vty
, const char *negate
, const char *acl_from_str
,
931 const char *acl_for_str
)
933 struct ldpd_af_conf
*af_conf
;
936 af
= ldp_vty_get_af(vty
);
937 af_conf
= ldp_af_conf_get(vty_conf
, af
);
940 af_conf
->acl_label_accept_from
[0] = '\0';
941 af_conf
->acl_label_accept_for
[0] = '\0';
944 strlcpy(af_conf
->acl_label_accept_from
, acl_from_str
,
945 sizeof(af_conf
->acl_label_accept_from
));
947 af_conf
->acl_label_accept_from
[0] = '\0';
949 strlcpy(af_conf
->acl_label_accept_for
, acl_for_str
,
950 sizeof(af_conf
->acl_label_accept_for
));
952 af_conf
->acl_label_accept_for
[0] = '\0';
955 ldp_config_apply(vty
, vty_conf
);
957 return (CMD_SUCCESS
);
961 ldp_vty_ttl_security(struct vty
*vty
, const char *negate
)
963 struct ldpd_af_conf
*af_conf
;
966 af
= ldp_vty_get_af(vty
);
967 af_conf
= ldp_af_conf_get(vty_conf
, af
);
970 af_conf
->flags
&= ~F_LDPD_AF_NO_GTSM
;
972 af_conf
->flags
|= F_LDPD_AF_NO_GTSM
;
974 ldp_config_apply(vty
, vty_conf
);
976 return (CMD_SUCCESS
);
980 ldp_vty_router_id(struct vty
*vty
, const char *negate
, struct in_addr address
)
983 vty_conf
->rtr_id
.s_addr
= INADDR_ANY
;
985 if (bad_addr_v4(address
)) {
986 vty_out (vty
, "%% Malformed address\n");
987 return (CMD_SUCCESS
);
989 vty_conf
->rtr_id
= address
;
992 ldp_config_apply(vty
, vty_conf
);
994 return (CMD_SUCCESS
);
998 ldp_vty_ds_cisco_interop(struct vty
*vty
, const char * negate
)
1001 vty_conf
->flags
&= ~F_LDPD_DS_CISCO_INTEROP
;
1003 vty_conf
->flags
|= F_LDPD_DS_CISCO_INTEROP
;
1005 ldp_config_apply(vty
, vty_conf
);
1007 return (CMD_SUCCESS
);
1011 ldp_vty_trans_pref_ipv4(struct vty
*vty
, const char *negate
)
1014 vty_conf
->trans_pref
= DUAL_STACK_LDPOV6
;
1016 vty_conf
->trans_pref
= DUAL_STACK_LDPOV4
;
1018 ldp_config_apply(vty
, vty_conf
);
1020 return (CMD_SUCCESS
);
1024 ldp_vty_neighbor_password(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
,
1025 const char *password_str
)
1027 size_t password_len
;
1028 struct nbr_params
*nbrp
;
1030 if (password_str
== NULL
) {
1031 vty_out (vty
, "%% Missing password\n");
1032 return (CMD_WARNING_CONFIG_FAILED
);
1035 if (bad_addr_v4(lsr_id
)) {
1036 vty_out (vty
, "%% Malformed address\n");
1037 return (CMD_WARNING_CONFIG_FAILED
);
1040 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1044 return (CMD_SUCCESS
);
1046 memset(&nbrp
->auth
, 0, sizeof(nbrp
->auth
));
1047 nbrp
->auth
.method
= AUTH_NONE
;
1050 nbrp
= nbr_params_new(lsr_id
);
1051 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1052 QOBJ_REG(nbrp
, nbr_params
);
1053 } else if (nbrp
->auth
.method
== AUTH_MD5SIG
&&
1054 strcmp(nbrp
->auth
.md5key
, password_str
) == 0)
1055 return (CMD_SUCCESS
);
1057 password_len
= strlcpy(nbrp
->auth
.md5key
, password_str
,
1058 sizeof(nbrp
->auth
.md5key
));
1059 if (password_len
>= sizeof(nbrp
->auth
.md5key
))
1060 vty_out(vty
, "%% password has been truncated to %zu "
1061 "characters.", sizeof(nbrp
->auth
.md5key
) - 1);
1062 nbrp
->auth
.md5key_len
= password_len
;
1063 nbrp
->auth
.method
= AUTH_MD5SIG
;
1066 ldp_config_apply(vty
, vty_conf
);
1068 return (CMD_SUCCESS
);
1072 ldp_vty_neighbor_ttl_security(struct vty
*vty
, const char *negate
,
1073 struct in_addr lsr_id
, const char *hops_str
)
1075 struct nbr_params
*nbrp
;
1079 if (bad_addr_v4(lsr_id
)) {
1080 vty_out (vty
, "%% Malformed address\n");
1081 return (CMD_WARNING_CONFIG_FAILED
);
1085 hops
= strtol(hops_str
, &ep
, 10);
1086 if (*ep
!= '\0' || hops
< 1 || hops
> 254) {
1087 vty_out (vty
, "%% Invalid hop count\n");
1088 return (CMD_SUCCESS
);
1092 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1096 return (CMD_SUCCESS
);
1098 nbrp
->flags
&= ~(F_NBRP_GTSM
|F_NBRP_GTSM_HOPS
);
1099 nbrp
->gtsm_enabled
= 0;
1100 nbrp
->gtsm_hops
= 0;
1103 nbrp
= nbr_params_new(lsr_id
);
1104 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1105 QOBJ_REG(nbrp
, nbr_params
);
1108 nbrp
->flags
|= F_NBRP_GTSM
;
1109 nbrp
->flags
&= ~F_NBRP_GTSM_HOPS
;
1111 nbrp
->gtsm_enabled
= 1;
1112 nbrp
->gtsm_hops
= hops
;
1113 nbrp
->flags
|= F_NBRP_GTSM_HOPS
;
1115 nbrp
->gtsm_enabled
= 0;
1118 ldp_config_apply(vty
, vty_conf
);
1120 return (CMD_SUCCESS
);
1124 ldp_vty_l2vpn(struct vty
*vty
, const char *negate
, const char *name_str
)
1126 struct l2vpn
*l2vpn
;
1127 struct l2vpn_if
*lif
;
1128 struct l2vpn_pw
*pw
;
1130 if (name_str
== NULL
) {
1131 vty_out (vty
, "%% Missing name\n");
1132 return (CMD_WARNING_CONFIG_FAILED
);
1135 l2vpn
= l2vpn_find(vty_conf
, name_str
);
1139 return (CMD_SUCCESS
);
1141 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
1143 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
1145 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
1148 RB_REMOVE(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1151 ldp_config_apply(vty
, vty_conf
);
1153 return (CMD_SUCCESS
);
1157 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1158 return (CMD_SUCCESS
);
1161 l2vpn
= l2vpn_new(name_str
);
1162 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1163 RB_INSERT(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1164 QOBJ_REG(l2vpn
, l2vpn
);
1166 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1168 ldp_config_apply(vty
, vty_conf
);
1170 return (CMD_SUCCESS
);
1174 ldp_vty_l2vpn_bridge(struct vty
*vty
, const char *negate
, const char *ifname
)
1176 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1179 memset(l2vpn
->br_ifname
, 0, sizeof(l2vpn
->br_ifname
));
1181 if (ifname
== NULL
) {
1182 vty_out (vty
, "%% Missing IF name\n");
1183 return (CMD_WARNING_CONFIG_FAILED
);
1185 strlcpy(l2vpn
->br_ifname
, ifname
, sizeof(l2vpn
->br_ifname
));
1188 ldp_config_apply(vty
, vty_conf
);
1190 return (CMD_SUCCESS
);
1194 ldp_vty_l2vpn_mtu(struct vty
*vty
, const char *negate
, long mtu
)
1196 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1199 l2vpn
->mtu
= DEFAULT_L2VPN_MTU
;
1203 ldp_config_apply(vty
, vty_conf
);
1205 return (CMD_SUCCESS
);
1209 ldp_vty_l2vpn_pwtype(struct vty
*vty
, const char *negate
, const char *type_str
)
1211 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1214 if (type_str
== NULL
) {
1215 vty_out (vty
, "%% Missing type\n");
1216 return (CMD_WARNING_CONFIG_FAILED
);
1219 if (strcmp(type_str
, "ethernet") == 0)
1220 pw_type
= PW_TYPE_ETHERNET
;
1222 pw_type
= PW_TYPE_ETHERNET_TAGGED
;
1225 l2vpn
->pw_type
= DEFAULT_PW_TYPE
;
1227 l2vpn
->pw_type
= pw_type
;
1229 ldp_config_apply(vty
, vty_conf
);
1231 return (CMD_SUCCESS
);
1235 ldp_vty_l2vpn_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
1237 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1238 struct l2vpn_if
*lif
;
1240 if (ifname
== NULL
) {
1241 vty_out (vty
, "%% Missing IF name\n");
1242 return (CMD_WARNING_CONFIG_FAILED
);
1245 lif
= l2vpn_if_find(l2vpn
, ifname
);
1249 return (CMD_SUCCESS
);
1252 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1255 ldp_config_apply(vty
, vty_conf
);
1257 return (CMD_SUCCESS
);
1261 return (CMD_SUCCESS
);
1263 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1264 vty_out (vty
, "%% Interface is already in use\n");
1265 return (CMD_SUCCESS
);
1268 lif
= l2vpn_if_new(l2vpn
, ifname
);
1269 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1270 QOBJ_REG(lif
, l2vpn_if
);
1272 ldp_config_apply(vty
, vty_conf
);
1274 return (CMD_SUCCESS
);
1278 ldp_vty_l2vpn_pseudowire(struct vty
*vty
, const char *negate
, const char *ifname
)
1280 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1281 struct l2vpn_pw
*pw
;
1283 if (ifname
== NULL
) {
1284 vty_out (vty
, "%% Missing IF name\n");
1285 return (CMD_WARNING_CONFIG_FAILED
);
1288 pw
= l2vpn_pw_find(l2vpn
, ifname
);
1292 return (CMD_SUCCESS
);
1295 if (pw
->lsr_id
.s_addr
== INADDR_ANY
|| pw
->pwid
== 0)
1296 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1298 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1301 ldp_config_apply(vty
, vty_conf
);
1303 return (CMD_SUCCESS
);
1307 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1308 return (CMD_SUCCESS
);
1311 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1312 vty_out (vty
, "%% Interface is already in use\n");
1313 return (CMD_SUCCESS
);
1316 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1317 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1318 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1319 QOBJ_REG(pw
, l2vpn_pw
);
1321 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1323 ldp_config_apply(vty
, vty_conf
);
1325 return (CMD_SUCCESS
);
1329 ldp_vty_l2vpn_pw_cword(struct vty
*vty
, const char *negate
, const char *preference_str
)
1331 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1334 pw
->flags
|= F_PW_CWORD_CONF
;
1336 if (!preference_str
) {
1337 vty_out (vty
, "%% Missing preference\n");
1338 return (CMD_WARNING_CONFIG_FAILED
);
1340 if (preference_str
[0] == 'e')
1341 pw
->flags
&= ~F_PW_CWORD_CONF
;
1343 pw
->flags
|= F_PW_CWORD_CONF
;
1346 ldp_config_apply(vty
, vty_conf
);
1348 return (CMD_SUCCESS
);
1352 ldp_vty_l2vpn_pw_nbr_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
1354 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1356 union ldpd_addr addr
;
1358 if (ldp_get_address(addr_str
, &af
, &addr
) == -1 ||
1359 bad_addr(af
, &addr
)) {
1360 vty_out (vty
, "%% Malformed address\n");
1361 return (CMD_WARNING_CONFIG_FAILED
);
1366 memset(&pw
->addr
, 0, sizeof(pw
->addr
));
1367 pw
->flags
&= ~F_PW_STATIC_NBR_ADDR
;
1371 pw
->flags
|= F_PW_STATIC_NBR_ADDR
;
1374 ldp_config_apply(vty
, vty_conf
);
1376 return (CMD_SUCCESS
);
1380 ldp_vty_l2vpn_pw_nbr_id(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
)
1382 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1384 if (bad_addr_v4(lsr_id
)) {
1385 vty_out (vty
, "%% Malformed address\n");
1386 return (CMD_WARNING_CONFIG_FAILED
);
1390 pw
->lsr_id
.s_addr
= INADDR_ANY
;
1392 pw
->lsr_id
= lsr_id
;
1394 ldp_config_apply(vty
, vty_conf
);
1396 return (CMD_SUCCESS
);
1400 ldp_vty_l2vpn_pw_pwid(struct vty
*vty
, const char *negate
, long pwid
)
1402 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1409 ldp_config_apply(vty
, vty_conf
);
1411 return (CMD_SUCCESS
);
1415 ldp_vty_l2vpn_pw_pwstatus(struct vty
*vty
, const char *negate
)
1417 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1420 pw
->flags
|= F_PW_STATUSTLV_CONF
;
1422 pw
->flags
&= ~F_PW_STATUSTLV_CONF
;
1424 ldp_config_apply(vty
, vty_conf
);
1426 return (CMD_SUCCESS
);
1430 iface_new_api(struct ldpd_conf
*conf
, const char *name
)
1432 const char *ifname
= name
;
1433 struct iface
*iface
;
1435 if (ldp_iface_is_configured(conf
, ifname
))
1438 iface
= if_new(name
);
1439 RB_INSERT(iface_head
, &conf
->iface_tree
, iface
);
1440 QOBJ_REG(iface
, iface
);
1445 iface_del_api(struct ldpd_conf
*conf
, struct iface
*iface
)
1448 RB_REMOVE(iface_head
, &conf
->iface_tree
, iface
);
1453 tnbr_new_api(struct ldpd_conf
*conf
, int af
, union ldpd_addr
*addr
)
1457 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
->v6
))
1460 if (tnbr_find(conf
, af
, addr
))
1463 tnbr
= tnbr_new(af
, addr
);
1464 tnbr
->flags
|= F_TNBR_CONFIGURED
;
1465 RB_INSERT(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1466 QOBJ_REG(tnbr
, tnbr
);
1471 tnbr_del_api(struct ldpd_conf
*conf
, struct tnbr
*tnbr
)
1474 RB_REMOVE(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1479 nbrp_new_api(struct ldpd_conf
*conf
, struct in_addr lsr_id
)
1481 struct nbr_params
*nbrp
;
1483 if (nbr_params_find(conf
, lsr_id
))
1486 nbrp
= nbr_params_new(lsr_id
);
1487 RB_INSERT(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1488 QOBJ_REG(nbrp
, nbr_params
);
1493 nbrp_del_api(struct ldpd_conf
*conf
, struct nbr_params
*nbrp
)
1496 RB_REMOVE(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1501 l2vpn_new_api(struct ldpd_conf
*conf
, const char *name
)
1503 struct l2vpn
*l2vpn
;
1505 if (l2vpn_find(conf
, name
))
1508 l2vpn
= l2vpn_new(name
);
1509 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1510 RB_INSERT(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1511 QOBJ_REG(l2vpn
, l2vpn
);
1516 l2vpn_del_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
)
1518 struct l2vpn_if
*lif
;
1519 struct l2vpn_pw
*pw
;
1521 while (!RB_EMPTY(l2vpn_if_head
, &l2vpn
->if_tree
)) {
1522 lif
= RB_ROOT(l2vpn_if_head
, &l2vpn
->if_tree
);
1525 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1528 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_tree
)) {
1529 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_tree
);
1532 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1535 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)) {
1536 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
);
1539 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1543 RB_REMOVE(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1548 l2vpn_if_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1551 struct l2vpn_if
*lif
;
1553 if (ldp_iface_is_configured(conf
, ifname
))
1556 lif
= l2vpn_if_new(l2vpn
, ifname
);
1557 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1558 QOBJ_REG(lif
, l2vpn_if
);
1563 l2vpn_if_del_api(struct l2vpn
*l2vpn
, struct l2vpn_if
*lif
)
1566 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1571 l2vpn_pw_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1574 struct l2vpn_pw
*pw
;
1576 if (ldp_iface_is_configured(conf
, ifname
))
1579 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1580 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1581 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1582 QOBJ_REG(pw
, l2vpn_pw
);
1587 l2vpn_pw_del_api(struct l2vpn
*l2vpn
, struct l2vpn_pw
*pw
)
1590 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);