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 if (!str
|| !af
|| !addr
)
95 memset(addr
, 0, sizeof(*addr
));
97 if (inet_pton(AF_INET
, str
, &addr
->v4
) == 1) {
102 if (inet_pton(AF_INET6
, str
, &addr
->v6
) == 1) {
111 ldp_af_iface_config_write(struct vty
*vty
, int af
)
116 RB_FOREACH(iface
, iface_head
, &ldpd_conf
->iface_tree
) {
117 ia
= iface_af_get(iface
, af
);
121 vty_out (vty
, " !\n");
122 vty_out (vty
, " interface %s\n", iface
->name
);
124 if (ia
->hello_holdtime
!= LINK_DFLT_HOLDTIME
&&
125 ia
->hello_holdtime
!= 0)
126 vty_out (vty
, " discovery hello holdtime %u\n",
128 if (ia
->hello_interval
!= DEFAULT_HELLO_INTERVAL
&&
129 ia
->hello_interval
!= 0)
130 vty_out (vty
, " discovery hello interval %u\n",
136 ldp_af_config_write(struct vty
*vty
, int af
, struct ldpd_conf
*conf
,
137 struct ldpd_af_conf
*af_conf
)
141 if (!(af_conf
->flags
& F_LDPD_AF_ENABLED
))
144 vty_out (vty
, " !\n");
145 vty_out (vty
, " address-family %s\n", af_name(af
));
147 if (af_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
148 af_conf
->lhello_holdtime
!= 0 )
149 vty_out (vty
, " discovery hello holdtime %u\n",
150 af_conf
->lhello_holdtime
);
151 if (af_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
152 af_conf
->lhello_interval
!= 0)
153 vty_out (vty
, " discovery hello interval %u\n",
154 af_conf
->lhello_interval
);
156 if (af_conf
->flags
& F_LDPD_AF_THELLO_ACCEPT
) {
157 vty_out(vty
, " discovery targeted-hello accept");
158 if (af_conf
->acl_thello_accept_from
[0] != '\0')
159 vty_out(vty
, " from %s",
160 af_conf
->acl_thello_accept_from
);
164 if (af_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
165 af_conf
->thello_holdtime
!= 0)
166 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
167 af_conf
->thello_holdtime
);
168 if (af_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
169 af_conf
->thello_interval
!= 0)
170 vty_out (vty
, " discovery targeted-hello interval %u\n",
171 af_conf
->thello_interval
);
173 if (ldp_addrisset(af
, &af_conf
->trans_addr
))
174 vty_out (vty
, " discovery transport-address %s\n",
175 log_addr(af
, &af_conf
->trans_addr
));
178 " ! Incomplete config, specify a discovery transport-address\n");
180 if ((af_conf
->flags
& F_LDPD_AF_ALLOCHOSTONLY
) ||
181 af_conf
->acl_label_allocate_for
[0] != '\0') {
182 vty_out(vty
, " label local allocate");
183 if (af_conf
->flags
& F_LDPD_AF_ALLOCHOSTONLY
)
184 vty_out(vty
, " host-routes");
186 vty_out(vty
, " for %s",
187 af_conf
->acl_label_allocate_for
);
191 if (af_conf
->acl_label_advertise_for
[0] != '\0' ||
192 af_conf
->acl_label_advertise_to
[0] != '\0') {
193 vty_out(vty
, " label local advertise");
194 if (af_conf
->acl_label_advertise_to
[0] != '\0')
195 vty_out(vty
, " to %s",
196 af_conf
->acl_label_advertise_to
);
197 if (af_conf
->acl_label_advertise_for
[0] != '\0')
198 vty_out(vty
, " for %s",
199 af_conf
->acl_label_advertise_for
);
203 if (af_conf
->flags
& F_LDPD_AF_EXPNULL
) {
204 vty_out(vty
, " label local advertise explicit-null");
205 if (af_conf
->acl_label_expnull_for
[0] != '\0')
206 vty_out(vty
, " for %s",
207 af_conf
->acl_label_expnull_for
);
211 if (af_conf
->acl_label_accept_for
[0] != '\0' ||
212 af_conf
->acl_label_accept_from
[0] != '\0') {
213 vty_out(vty
, " label remote accept");
214 if (af_conf
->acl_label_accept_from
[0] != '\0')
215 vty_out(vty
, " from %s",
216 af_conf
->acl_label_accept_from
);
217 if (af_conf
->acl_label_accept_for
[0] != '\0')
218 vty_out(vty
, " for %s",
219 af_conf
->acl_label_accept_for
);
223 if (af_conf
->flags
& F_LDPD_AF_NO_GTSM
)
224 vty_out (vty
, " ttl-security disable\n");
226 if (af_conf
->keepalive
!= DEFAULT_KEEPALIVE
)
227 vty_out (vty
, " session holdtime %u\n",af_conf
->keepalive
);
229 RB_FOREACH(tnbr
, tnbr_head
, &ldpd_conf
->tnbr_tree
) {
230 if (tnbr
->af
== af
) {
231 vty_out (vty
, " !\n");
232 vty_out (vty
, " neighbor %s targeted\n",
233 log_addr(tnbr
->af
, &tnbr
->addr
));
237 ldp_af_iface_config_write(vty
, af
);
239 vty_out(vty
, " !\n");
240 vty_out(vty
, " exit-address-family\n");
244 ldp_config_write(struct vty
*vty
)
246 struct nbr_params
*nbrp
;
248 if (!(ldpd_conf
->flags
& F_LDPD_ENABLED
))
251 vty_out (vty
, "mpls ldp\n");
253 if (ldpd_conf
->rtr_id
.s_addr
!= INADDR_ANY
)
254 vty_out(vty
, " router-id %s\n", inet_ntoa(ldpd_conf
->rtr_id
));
256 if (ldpd_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
257 ldpd_conf
->lhello_holdtime
!= 0)
258 vty_out (vty
, " discovery hello holdtime %u\n",
259 ldpd_conf
->lhello_holdtime
);
260 if (ldpd_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
261 ldpd_conf
->lhello_interval
!= 0)
262 vty_out (vty
, " discovery hello interval %u\n",
263 ldpd_conf
->lhello_interval
);
265 if (ldpd_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
266 ldpd_conf
->thello_holdtime
!= 0)
267 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
268 ldpd_conf
->thello_holdtime
);
269 if (ldpd_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
270 ldpd_conf
->thello_interval
!= 0)
271 vty_out (vty
, " discovery targeted-hello interval %u\n",
272 ldpd_conf
->thello_interval
);
274 if (ldpd_conf
->trans_pref
== DUAL_STACK_LDPOV4
)
276 " dual-stack transport-connection prefer ipv4\n");
278 if (ldpd_conf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
279 vty_out (vty
, " dual-stack cisco-interop\n");
281 if (ldpd_conf
->flags
& F_LDPD_ORDERED_CONTROL
)
282 vty_out (vty
, " ordered-control\n");
284 RB_FOREACH(nbrp
, nbrp_head
, &ldpd_conf
->nbrp_tree
) {
285 if (nbrp
->flags
& F_NBRP_KEEPALIVE
)
286 vty_out (vty
, " neighbor %s session holdtime %u\n",
287 inet_ntoa(nbrp
->lsr_id
),nbrp
->keepalive
);
289 if (nbrp
->flags
& F_NBRP_GTSM
) {
290 if (nbrp
->gtsm_enabled
)
291 vty_out (vty
, " neighbor %s ttl-security hops "
292 "%u\n", inet_ntoa(nbrp
->lsr_id
),
295 vty_out (vty
, " neighbor %s ttl-security "
296 "disable\n",inet_ntoa(nbrp
->lsr_id
));
299 if (nbrp
->auth
.method
== AUTH_MD5SIG
)
300 vty_out (vty
, " neighbor %s password %s\n",
301 inet_ntoa(nbrp
->lsr_id
),nbrp
->auth
.md5key
);
304 ldp_af_config_write(vty
, AF_INET
, ldpd_conf
, &ldpd_conf
->ipv4
);
305 ldp_af_config_write(vty
, AF_INET6
, ldpd_conf
, &ldpd_conf
->ipv6
);
306 vty_out (vty
, " !\n");
307 vty_out (vty
, "!\n");
313 ldp_l2vpn_pw_config_write(struct vty
*vty
, struct l2vpn_pw
*pw
)
315 int missing_lsrid
= 0;
316 int missing_pwid
= 0;
318 vty_out (vty
, " !\n");
319 vty_out (vty
, " member pseudowire %s\n", pw
->ifname
);
321 if (pw
->lsr_id
.s_addr
!= INADDR_ANY
)
322 vty_out (vty
, " neighbor lsr-id %s\n",inet_ntoa(pw
->lsr_id
));
326 if (pw
->flags
& F_PW_STATIC_NBR_ADDR
)
327 vty_out (vty
, " neighbor address %s\n",
328 log_addr(pw
->af
, &pw
->addr
));
331 vty_out (vty
, " pw-id %u\n", pw
->pwid
);
335 if (!(pw
->flags
& F_PW_CWORD_CONF
))
336 vty_out (vty
, " control-word exclude\n");
338 if (!(pw
->flags
& F_PW_STATUSTLV_CONF
))
339 vty_out (vty
, " pw-status disable\n");
343 " ! Incomplete config, specify a neighbor lsr-id\n");
345 vty_out (vty
," ! Incomplete config, specify a pw-id\n");
349 ldp_l2vpn_config_write(struct vty
*vty
)
352 struct l2vpn_if
*lif
;
355 RB_FOREACH(l2vpn
, l2vpn_head
, &ldpd_conf
->l2vpn_tree
) {
356 vty_out (vty
, "l2vpn %s type vpls\n", l2vpn
->name
);
358 if (l2vpn
->pw_type
!= DEFAULT_PW_TYPE
)
359 vty_out (vty
, " vc type ethernet-tagged\n");
361 if (l2vpn
->mtu
!= DEFAULT_L2VPN_MTU
)
362 vty_out (vty
, " mtu %u\n", l2vpn
->mtu
);
364 if (l2vpn
->br_ifname
[0] != '\0')
365 vty_out (vty
, " bridge %s\n",l2vpn
->br_ifname
);
367 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
368 vty_out (vty
, " member interface %s\n",lif
->ifname
);
370 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
371 ldp_l2vpn_pw_config_write(vty
, pw
);
372 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
373 ldp_l2vpn_pw_config_write(vty
, pw
);
375 vty_out (vty
, " !\n");
376 vty_out (vty
, "!\n");
383 ldp_vty_get_af(struct vty
*vty
)
387 case LDP_IPV4_IFACE_NODE
:
390 case LDP_IPV6_IFACE_NODE
:
393 fatalx("ldp_vty_get_af: unexpected node");
398 ldp_iface_is_configured(struct ldpd_conf
*xconf
, const char *ifname
)
402 if (if_lookup_name(xconf
, ifname
))
405 RB_FOREACH(l2vpn
, l2vpn_head
, &xconf
->l2vpn_tree
) {
406 if (l2vpn_if_find(l2vpn
, ifname
))
408 if (l2vpn_pw_find(l2vpn
, ifname
))
416 ldp_vty_mpls_ldp(struct vty
*vty
, const char *negate
)
419 vty_conf
->flags
&= ~F_LDPD_ENABLED
;
421 vty
->node
= LDP_NODE
;
422 vty_conf
->flags
|= F_LDPD_ENABLED
;
425 ldp_config_apply(vty
, vty_conf
);
427 return (CMD_SUCCESS
);
431 ldp_vty_address_family(struct vty
*vty
, const char *negate
, const char *af_str
)
433 struct ldpd_af_conf
*af_conf
;
437 return (CMD_WARNING_CONFIG_FAILED
);
439 if (strcmp(af_str
, "ipv4") == 0) {
441 af_conf
= &vty_conf
->ipv4
;
442 } else if (strcmp(af_str
, "ipv6") == 0) {
444 af_conf
= &vty_conf
->ipv6
;
446 return (CMD_WARNING_CONFIG_FAILED
);
449 af_conf
->flags
&= ~F_LDPD_AF_ENABLED
;
450 ldp_config_apply(vty
, vty_conf
);
451 return (CMD_SUCCESS
);
456 vty
->node
= LDP_IPV4_NODE
;
459 vty
->node
= LDP_IPV6_NODE
;
462 fatalx("ldp_vty_address_family: unknown af");
464 af_conf
->flags
|= F_LDPD_AF_ENABLED
;
466 ldp_config_apply(vty
, vty_conf
);
468 return (CMD_SUCCESS
);
471 int ldp_vty_disc_holdtime(struct vty
*vty
, const char *negate
,
472 enum hello_type hello_type
, long secs
)
474 struct ldpd_af_conf
*af_conf
;
482 switch (hello_type
) {
484 vty_conf
->lhello_holdtime
= LINK_DFLT_HOLDTIME
;
487 vty_conf
->thello_holdtime
=
488 TARGETED_DFLT_HOLDTIME
;
492 switch (hello_type
) {
494 vty_conf
->lhello_holdtime
= secs
;
497 vty_conf
->thello_holdtime
= secs
;
501 ldp_config_apply(vty
, vty_conf
);
505 af
= ldp_vty_get_af(vty
);
506 af_conf
= ldp_af_conf_get(vty_conf
, af
);
509 switch (hello_type
) {
511 af_conf
->lhello_holdtime
= 0;
514 af_conf
->thello_holdtime
= 0;
518 switch (hello_type
) {
520 af_conf
->lhello_holdtime
= secs
;
523 af_conf
->thello_holdtime
= secs
;
527 ldp_config_apply(vty
, vty_conf
);
529 case LDP_IPV4_IFACE_NODE
:
530 case LDP_IPV6_IFACE_NODE
:
531 af
= ldp_vty_get_af(vty
);
532 iface
= VTY_GET_CONTEXT(iface
);
533 VTY_CHECK_CONTEXT(iface
);
535 ia
= iface_af_get(iface
, af
);
537 ia
->hello_holdtime
= 0;
539 ia
->hello_holdtime
= secs
;
541 ldp_config_apply(vty
, vty_conf
);
544 fatalx("ldp_vty_disc_holdtime: unexpected node");
547 return (CMD_SUCCESS
);
551 ldp_vty_disc_interval(struct vty
*vty
, const char *negate
,
552 enum hello_type hello_type
, long secs
)
554 struct ldpd_af_conf
*af_conf
;
562 switch (hello_type
) {
564 vty_conf
->lhello_interval
=
565 DEFAULT_HELLO_INTERVAL
;
568 vty_conf
->thello_interval
=
569 DEFAULT_HELLO_INTERVAL
;
573 switch (hello_type
) {
575 vty_conf
->lhello_interval
= secs
;
578 vty_conf
->thello_interval
= secs
;
582 ldp_config_apply(vty
, vty_conf
);
586 af
= ldp_vty_get_af(vty
);
587 af_conf
= ldp_af_conf_get(vty_conf
, af
);
590 switch (hello_type
) {
592 af_conf
->lhello_interval
= 0;
595 af_conf
->thello_interval
= 0;
599 switch (hello_type
) {
601 af_conf
->lhello_interval
= secs
;
604 af_conf
->thello_interval
= secs
;
608 ldp_config_apply(vty
, vty_conf
);
610 case LDP_IPV4_IFACE_NODE
:
611 case LDP_IPV6_IFACE_NODE
:
612 af
= ldp_vty_get_af(vty
);
613 iface
= VTY_GET_CONTEXT(iface
);
614 VTY_CHECK_CONTEXT(iface
);
616 ia
= iface_af_get(iface
, af
);
618 ia
->hello_interval
= 0;
620 ia
->hello_interval
= secs
;
622 ldp_config_apply(vty
, vty_conf
);
625 fatalx("ldp_vty_disc_interval: unexpected node");
628 return (CMD_SUCCESS
);
632 ldp_vty_targeted_hello_accept(struct vty
*vty
, const char *negate
,
633 const char *acl_from_str
)
635 struct ldpd_af_conf
*af_conf
;
638 af
= ldp_vty_get_af(vty
);
639 af_conf
= ldp_af_conf_get(vty_conf
, af
);
642 af_conf
->flags
&= ~F_LDPD_AF_THELLO_ACCEPT
;
643 af_conf
->acl_thello_accept_from
[0] = '\0';
645 af_conf
->flags
|= F_LDPD_AF_THELLO_ACCEPT
;
647 strlcpy(af_conf
->acl_thello_accept_from
, acl_from_str
,
648 sizeof(af_conf
->acl_thello_accept_from
));
650 af_conf
->acl_thello_accept_from
[0] = '\0';
653 ldp_config_apply(vty
, vty_conf
);
655 return (CMD_SUCCESS
);
659 ldp_vty_nbr_session_holdtime(struct vty
*vty
, const char *negate
,
660 struct in_addr lsr_id
, long secs
)
662 struct nbr_params
*nbrp
;
664 if (bad_addr_v4(lsr_id
)) {
665 vty_out (vty
, "%% Malformed address\n");
666 return (CMD_WARNING_CONFIG_FAILED
);
669 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
673 return (CMD_SUCCESS
);
676 nbrp
->flags
&= ~F_NBRP_KEEPALIVE
;
679 nbrp
= nbr_params_new(lsr_id
);
680 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
681 QOBJ_REG(nbrp
, nbr_params
);
682 } else if (nbrp
->keepalive
== secs
)
683 return (CMD_SUCCESS
);
685 nbrp
->keepalive
= secs
;
686 nbrp
->flags
|= F_NBRP_KEEPALIVE
;
689 ldp_config_apply(vty
, vty_conf
);
691 return (CMD_SUCCESS
);
695 ldp_vty_af_session_holdtime(struct vty
*vty
, const char *negate
, long secs
)
697 struct ldpd_af_conf
*af_conf
;
700 af
= ldp_vty_get_af(vty
);
701 af_conf
= ldp_af_conf_get(vty_conf
, af
);
704 af_conf
->keepalive
= DEFAULT_KEEPALIVE
;
706 af_conf
->keepalive
= secs
;
708 ldp_config_apply(vty
, vty_conf
);
710 return (CMD_SUCCESS
);
714 ldp_vty_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
720 if (ifname
== NULL
) {
721 vty_out (vty
, "%% Missing IF name\n");
722 return (CMD_WARNING_CONFIG_FAILED
);
725 af
= ldp_vty_get_af(vty
);
726 iface
= if_lookup_name(vty_conf
, ifname
);
730 return (CMD_SUCCESS
);
732 ia
= iface_af_get(iface
, af
);
733 if (ia
->enabled
== 0)
734 return (CMD_SUCCESS
);
737 ia
->hello_holdtime
= 0;
738 ia
->hello_interval
= 0;
740 ldp_config_apply(vty
, vty_conf
);
742 return (CMD_SUCCESS
);
746 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
747 vty_out (vty
,"%% Interface is already in use\n");
748 return (CMD_SUCCESS
);
751 iface
= if_new(ifname
);
752 ia
= iface_af_get(iface
, af
);
754 RB_INSERT(iface_head
, &vty_conf
->iface_tree
, iface
);
755 QOBJ_REG(iface
, iface
);
757 ldp_config_apply(vty
, vty_conf
);
759 ia
= iface_af_get(iface
, af
);
762 ldp_config_apply(vty
, vty_conf
);
768 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE
, iface
);
771 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE
, iface
);
777 return (CMD_SUCCESS
);
781 ldp_vty_trans_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
783 struct ldpd_af_conf
*af_conf
;
786 af
= ldp_vty_get_af(vty
);
787 af_conf
= ldp_af_conf_get(vty_conf
, af
);
790 memset(&af_conf
->trans_addr
, 0, sizeof(af_conf
->trans_addr
));
793 || inet_pton(af
, addr_str
, &af_conf
->trans_addr
) != 1
794 || bad_addr(af
, &af_conf
->trans_addr
)) {
795 vty_out (vty
, "%% Malformed address\n");
796 return (CMD_SUCCESS
);
800 ldp_config_apply(vty
, vty_conf
);
802 return (CMD_SUCCESS
);
806 ldp_vty_neighbor_targeted(struct vty
*vty
, const char *negate
, const char *addr_str
)
809 union ldpd_addr addr
;
812 af
= ldp_vty_get_af(vty
);
814 if (addr_str
== NULL
|| inet_pton(af
, addr_str
, &addr
) != 1 ||
815 bad_addr(af
, &addr
)) {
816 vty_out (vty
, "%% Malformed address\n");
817 return (CMD_WARNING_CONFIG_FAILED
);
819 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
.v6
)) {
820 vty_out (vty
, "%% Address can not be link-local\n");
821 return (CMD_WARNING_CONFIG_FAILED
);
824 tnbr
= tnbr_find(vty_conf
, af
, &addr
);
828 return (CMD_SUCCESS
);
831 RB_REMOVE(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
834 ldp_config_apply(vty
, vty_conf
);
836 return (CMD_SUCCESS
);
840 return (CMD_SUCCESS
);
842 tnbr
= tnbr_new(af
, &addr
);
843 tnbr
->flags
|= F_TNBR_CONFIGURED
;
844 RB_INSERT(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
845 QOBJ_REG(tnbr
, tnbr
);
847 ldp_config_apply(vty
, vty_conf
);
849 return (CMD_SUCCESS
);
853 ldp_vty_label_advertise(struct vty
*vty
, const char *negate
, const char *acl_to_str
,
854 const char *acl_for_str
)
856 struct ldpd_af_conf
*af_conf
;
859 af
= ldp_vty_get_af(vty
);
860 af_conf
= ldp_af_conf_get(vty_conf
, af
);
863 af_conf
->acl_label_advertise_to
[0] = '\0';
864 af_conf
->acl_label_advertise_for
[0] = '\0';
867 strlcpy(af_conf
->acl_label_advertise_to
, acl_to_str
,
868 sizeof(af_conf
->acl_label_advertise_to
));
870 af_conf
->acl_label_advertise_to
[0] = '\0';
872 strlcpy(af_conf
->acl_label_advertise_for
, acl_for_str
,
873 sizeof(af_conf
->acl_label_advertise_for
));
875 af_conf
->acl_label_advertise_for
[0] = '\0';
878 ldp_config_apply(vty
, vty_conf
);
880 return (CMD_SUCCESS
);
884 ldp_vty_label_allocate(struct vty
*vty
, const char *negate
, const char *host_routes
,
885 const char *acl_for_str
)
887 struct ldpd_af_conf
*af_conf
;
890 af
= ldp_vty_get_af(vty
);
891 af_conf
= ldp_af_conf_get(vty_conf
, af
);
893 af_conf
->flags
&= ~F_LDPD_AF_ALLOCHOSTONLY
;
894 af_conf
->acl_label_allocate_for
[0] = '\0';
897 af_conf
->flags
|= F_LDPD_AF_ALLOCHOSTONLY
;
899 strlcpy(af_conf
->acl_label_allocate_for
, acl_for_str
,
900 sizeof(af_conf
->acl_label_allocate_for
));
903 ldp_config_apply(vty
, vty_conf
);
905 return (CMD_SUCCESS
);
909 ldp_vty_label_expnull(struct vty
*vty
, const char *negate
, const char *acl_for_str
)
911 struct ldpd_af_conf
*af_conf
;
914 af
= ldp_vty_get_af(vty
);
915 af_conf
= ldp_af_conf_get(vty_conf
, af
);
918 af_conf
->flags
&= ~F_LDPD_AF_EXPNULL
;
919 af_conf
->acl_label_expnull_for
[0] = '\0';
921 af_conf
->flags
|= F_LDPD_AF_EXPNULL
;
923 strlcpy(af_conf
->acl_label_expnull_for
, acl_for_str
,
924 sizeof(af_conf
->acl_label_expnull_for
));
926 af_conf
->acl_label_expnull_for
[0] = '\0';
929 ldp_config_apply(vty
, vty_conf
);
931 return (CMD_SUCCESS
);
935 ldp_vty_label_accept(struct vty
*vty
, const char *negate
, const char *acl_from_str
,
936 const char *acl_for_str
)
938 struct ldpd_af_conf
*af_conf
;
941 af
= ldp_vty_get_af(vty
);
942 af_conf
= ldp_af_conf_get(vty_conf
, af
);
945 af_conf
->acl_label_accept_from
[0] = '\0';
946 af_conf
->acl_label_accept_for
[0] = '\0';
949 strlcpy(af_conf
->acl_label_accept_from
, acl_from_str
,
950 sizeof(af_conf
->acl_label_accept_from
));
952 af_conf
->acl_label_accept_from
[0] = '\0';
954 strlcpy(af_conf
->acl_label_accept_for
, acl_for_str
,
955 sizeof(af_conf
->acl_label_accept_for
));
957 af_conf
->acl_label_accept_for
[0] = '\0';
960 ldp_config_apply(vty
, vty_conf
);
962 return (CMD_SUCCESS
);
966 ldp_vty_ttl_security(struct vty
*vty
, const char *negate
)
968 struct ldpd_af_conf
*af_conf
;
971 af
= ldp_vty_get_af(vty
);
972 af_conf
= ldp_af_conf_get(vty_conf
, af
);
975 af_conf
->flags
&= ~F_LDPD_AF_NO_GTSM
;
977 af_conf
->flags
|= F_LDPD_AF_NO_GTSM
;
979 ldp_config_apply(vty
, vty_conf
);
981 return (CMD_SUCCESS
);
985 ldp_vty_router_id(struct vty
*vty
, const char *negate
, struct in_addr address
)
988 vty_conf
->rtr_id
.s_addr
= INADDR_ANY
;
990 if (bad_addr_v4(address
)) {
991 vty_out (vty
, "%% Malformed address\n");
992 return (CMD_SUCCESS
);
994 vty_conf
->rtr_id
= address
;
997 ldp_config_apply(vty
, vty_conf
);
999 return (CMD_SUCCESS
);
1003 ldp_vty_ordered_control(struct vty
*vty
, const char *negate
)
1006 vty_conf
->flags
&= ~F_LDPD_ORDERED_CONTROL
;
1008 vty_conf
->flags
|= F_LDPD_ORDERED_CONTROL
;
1010 ldp_config_apply(vty
, vty_conf
);
1012 return (CMD_SUCCESS
);
1016 ldp_vty_ds_cisco_interop(struct vty
*vty
, const char * negate
)
1019 vty_conf
->flags
&= ~F_LDPD_DS_CISCO_INTEROP
;
1021 vty_conf
->flags
|= F_LDPD_DS_CISCO_INTEROP
;
1023 ldp_config_apply(vty
, vty_conf
);
1025 return (CMD_SUCCESS
);
1029 ldp_vty_trans_pref_ipv4(struct vty
*vty
, const char *negate
)
1032 vty_conf
->trans_pref
= DUAL_STACK_LDPOV6
;
1034 vty_conf
->trans_pref
= DUAL_STACK_LDPOV4
;
1036 ldp_config_apply(vty
, vty_conf
);
1038 return (CMD_SUCCESS
);
1042 ldp_vty_neighbor_password(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
,
1043 const char *password_str
)
1045 size_t password_len
;
1046 struct nbr_params
*nbrp
;
1048 if (password_str
== NULL
) {
1049 vty_out (vty
, "%% Missing password\n");
1050 return (CMD_WARNING_CONFIG_FAILED
);
1053 if (bad_addr_v4(lsr_id
)) {
1054 vty_out (vty
, "%% Malformed address\n");
1055 return (CMD_WARNING_CONFIG_FAILED
);
1058 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1062 return (CMD_SUCCESS
);
1064 memset(&nbrp
->auth
, 0, sizeof(nbrp
->auth
));
1065 nbrp
->auth
.method
= AUTH_NONE
;
1068 nbrp
= nbr_params_new(lsr_id
);
1069 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1070 QOBJ_REG(nbrp
, nbr_params
);
1071 } else if (nbrp
->auth
.method
== AUTH_MD5SIG
&&
1072 strcmp(nbrp
->auth
.md5key
, password_str
) == 0)
1073 return (CMD_SUCCESS
);
1075 password_len
= strlcpy(nbrp
->auth
.md5key
, password_str
,
1076 sizeof(nbrp
->auth
.md5key
));
1077 if (password_len
>= sizeof(nbrp
->auth
.md5key
))
1078 vty_out(vty
, "%% password has been truncated to %zu "
1079 "characters.", sizeof(nbrp
->auth
.md5key
) - 1);
1080 nbrp
->auth
.md5key_len
= password_len
;
1081 nbrp
->auth
.method
= AUTH_MD5SIG
;
1084 ldp_config_apply(vty
, vty_conf
);
1086 return (CMD_SUCCESS
);
1090 ldp_vty_neighbor_ttl_security(struct vty
*vty
, const char *negate
,
1091 struct in_addr lsr_id
, const char *hops_str
)
1093 struct nbr_params
*nbrp
;
1097 if (bad_addr_v4(lsr_id
)) {
1098 vty_out (vty
, "%% Malformed address\n");
1099 return (CMD_WARNING_CONFIG_FAILED
);
1103 hops
= strtol(hops_str
, &ep
, 10);
1104 if (*ep
!= '\0' || hops
< 1 || hops
> 254) {
1105 vty_out (vty
, "%% Invalid hop count\n");
1106 return (CMD_SUCCESS
);
1110 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1114 return (CMD_SUCCESS
);
1116 nbrp
->flags
&= ~(F_NBRP_GTSM
|F_NBRP_GTSM_HOPS
);
1117 nbrp
->gtsm_enabled
= 0;
1118 nbrp
->gtsm_hops
= 0;
1121 nbrp
= nbr_params_new(lsr_id
);
1122 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1123 QOBJ_REG(nbrp
, nbr_params
);
1126 nbrp
->flags
|= F_NBRP_GTSM
;
1127 nbrp
->flags
&= ~F_NBRP_GTSM_HOPS
;
1129 nbrp
->gtsm_enabled
= 1;
1130 nbrp
->gtsm_hops
= hops
;
1131 nbrp
->flags
|= F_NBRP_GTSM_HOPS
;
1133 nbrp
->gtsm_enabled
= 0;
1136 ldp_config_apply(vty
, vty_conf
);
1138 return (CMD_SUCCESS
);
1142 ldp_vty_l2vpn(struct vty
*vty
, const char *negate
, const char *name_str
)
1144 struct l2vpn
*l2vpn
;
1145 struct l2vpn_if
*lif
;
1146 struct l2vpn_pw
*pw
;
1148 if (name_str
== NULL
) {
1149 vty_out (vty
, "%% Missing name\n");
1150 return (CMD_WARNING_CONFIG_FAILED
);
1153 l2vpn
= l2vpn_find(vty_conf
, name_str
);
1157 return (CMD_SUCCESS
);
1159 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
1161 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
1163 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
1166 RB_REMOVE(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1169 ldp_config_apply(vty
, vty_conf
);
1171 return (CMD_SUCCESS
);
1175 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1176 return (CMD_SUCCESS
);
1179 l2vpn
= l2vpn_new(name_str
);
1180 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1181 RB_INSERT(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1182 QOBJ_REG(l2vpn
, l2vpn
);
1184 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1186 ldp_config_apply(vty
, vty_conf
);
1188 return (CMD_SUCCESS
);
1192 ldp_vty_l2vpn_bridge(struct vty
*vty
, const char *negate
, const char *ifname
)
1194 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1197 memset(l2vpn
->br_ifname
, 0, sizeof(l2vpn
->br_ifname
));
1199 if (ifname
== NULL
) {
1200 vty_out (vty
, "%% Missing IF name\n");
1201 return (CMD_WARNING_CONFIG_FAILED
);
1203 strlcpy(l2vpn
->br_ifname
, ifname
, sizeof(l2vpn
->br_ifname
));
1206 ldp_config_apply(vty
, vty_conf
);
1208 return (CMD_SUCCESS
);
1212 ldp_vty_l2vpn_mtu(struct vty
*vty
, const char *negate
, long mtu
)
1214 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1217 l2vpn
->mtu
= DEFAULT_L2VPN_MTU
;
1221 ldp_config_apply(vty
, vty_conf
);
1223 return (CMD_SUCCESS
);
1227 ldp_vty_l2vpn_pwtype(struct vty
*vty
, const char *negate
, const char *type_str
)
1229 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1232 if (type_str
== NULL
) {
1233 vty_out (vty
, "%% Missing type\n");
1234 return (CMD_WARNING_CONFIG_FAILED
);
1237 if (strcmp(type_str
, "ethernet") == 0)
1238 pw_type
= PW_TYPE_ETHERNET
;
1240 pw_type
= PW_TYPE_ETHERNET_TAGGED
;
1243 l2vpn
->pw_type
= DEFAULT_PW_TYPE
;
1245 l2vpn
->pw_type
= pw_type
;
1247 ldp_config_apply(vty
, vty_conf
);
1249 return (CMD_SUCCESS
);
1253 ldp_vty_l2vpn_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
1255 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1256 struct l2vpn_if
*lif
;
1258 if (ifname
== NULL
) {
1259 vty_out (vty
, "%% Missing IF name\n");
1260 return (CMD_WARNING_CONFIG_FAILED
);
1263 lif
= l2vpn_if_find(l2vpn
, ifname
);
1267 return (CMD_SUCCESS
);
1270 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1273 ldp_config_apply(vty
, vty_conf
);
1275 return (CMD_SUCCESS
);
1279 return (CMD_SUCCESS
);
1281 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1282 vty_out (vty
, "%% Interface is already in use\n");
1283 return (CMD_SUCCESS
);
1286 lif
= l2vpn_if_new(l2vpn
, ifname
);
1287 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1288 QOBJ_REG(lif
, l2vpn_if
);
1290 ldp_config_apply(vty
, vty_conf
);
1292 return (CMD_SUCCESS
);
1296 ldp_vty_l2vpn_pseudowire(struct vty
*vty
, const char *negate
, const char *ifname
)
1298 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1299 struct l2vpn_pw
*pw
;
1301 if (ifname
== NULL
) {
1302 vty_out (vty
, "%% Missing IF name\n");
1303 return (CMD_WARNING_CONFIG_FAILED
);
1306 pw
= l2vpn_pw_find(l2vpn
, ifname
);
1310 return (CMD_SUCCESS
);
1313 if (pw
->lsr_id
.s_addr
== INADDR_ANY
|| pw
->pwid
== 0)
1314 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1316 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1319 ldp_config_apply(vty
, vty_conf
);
1321 return (CMD_SUCCESS
);
1325 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1326 return (CMD_SUCCESS
);
1329 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1330 vty_out (vty
, "%% Interface is already in use\n");
1331 return (CMD_SUCCESS
);
1334 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1335 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1336 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1337 QOBJ_REG(pw
, l2vpn_pw
);
1339 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1341 ldp_config_apply(vty
, vty_conf
);
1343 return (CMD_SUCCESS
);
1347 ldp_vty_l2vpn_pw_cword(struct vty
*vty
, const char *negate
, const char *preference_str
)
1349 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1352 pw
->flags
|= F_PW_CWORD_CONF
;
1354 if (!preference_str
) {
1355 vty_out (vty
, "%% Missing preference\n");
1356 return (CMD_WARNING_CONFIG_FAILED
);
1358 if (preference_str
[0] == 'e')
1359 pw
->flags
&= ~F_PW_CWORD_CONF
;
1361 pw
->flags
|= F_PW_CWORD_CONF
;
1364 ldp_config_apply(vty
, vty_conf
);
1366 return (CMD_SUCCESS
);
1370 ldp_vty_l2vpn_pw_nbr_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
1372 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1374 union ldpd_addr addr
;
1376 if (ldp_get_address(addr_str
, &af
, &addr
) == -1 ||
1377 bad_addr(af
, &addr
)) {
1378 vty_out (vty
, "%% Malformed address\n");
1379 return (CMD_WARNING_CONFIG_FAILED
);
1384 memset(&pw
->addr
, 0, sizeof(pw
->addr
));
1385 pw
->flags
&= ~F_PW_STATIC_NBR_ADDR
;
1389 pw
->flags
|= F_PW_STATIC_NBR_ADDR
;
1392 ldp_config_apply(vty
, vty_conf
);
1394 return (CMD_SUCCESS
);
1398 ldp_vty_l2vpn_pw_nbr_id(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
)
1400 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1402 if (bad_addr_v4(lsr_id
)) {
1403 vty_out (vty
, "%% Malformed address\n");
1404 return (CMD_WARNING_CONFIG_FAILED
);
1408 pw
->lsr_id
.s_addr
= INADDR_ANY
;
1410 pw
->lsr_id
= lsr_id
;
1412 ldp_config_apply(vty
, vty_conf
);
1414 return (CMD_SUCCESS
);
1418 ldp_vty_l2vpn_pw_pwid(struct vty
*vty
, const char *negate
, long pwid
)
1420 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1427 ldp_config_apply(vty
, vty_conf
);
1429 return (CMD_SUCCESS
);
1433 ldp_vty_l2vpn_pw_pwstatus(struct vty
*vty
, const char *negate
)
1435 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1438 pw
->flags
|= F_PW_STATUSTLV_CONF
;
1440 pw
->flags
&= ~F_PW_STATUSTLV_CONF
;
1442 ldp_config_apply(vty
, vty_conf
);
1444 return (CMD_SUCCESS
);
1448 iface_new_api(struct ldpd_conf
*conf
, const char *name
)
1450 const char *ifname
= name
;
1451 struct iface
*iface
;
1453 if (ldp_iface_is_configured(conf
, ifname
))
1456 iface
= if_new(name
);
1457 RB_INSERT(iface_head
, &conf
->iface_tree
, iface
);
1458 QOBJ_REG(iface
, iface
);
1463 iface_del_api(struct ldpd_conf
*conf
, struct iface
*iface
)
1466 RB_REMOVE(iface_head
, &conf
->iface_tree
, iface
);
1471 tnbr_new_api(struct ldpd_conf
*conf
, int af
, union ldpd_addr
*addr
)
1475 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
->v6
))
1478 if (tnbr_find(conf
, af
, addr
))
1481 tnbr
= tnbr_new(af
, addr
);
1482 tnbr
->flags
|= F_TNBR_CONFIGURED
;
1483 RB_INSERT(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1484 QOBJ_REG(tnbr
, tnbr
);
1489 tnbr_del_api(struct ldpd_conf
*conf
, struct tnbr
*tnbr
)
1492 RB_REMOVE(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1497 nbrp_new_api(struct ldpd_conf
*conf
, struct in_addr lsr_id
)
1499 struct nbr_params
*nbrp
;
1501 if (nbr_params_find(conf
, lsr_id
))
1504 nbrp
= nbr_params_new(lsr_id
);
1505 RB_INSERT(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1506 QOBJ_REG(nbrp
, nbr_params
);
1511 nbrp_del_api(struct ldpd_conf
*conf
, struct nbr_params
*nbrp
)
1514 RB_REMOVE(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1519 l2vpn_new_api(struct ldpd_conf
*conf
, const char *name
)
1521 struct l2vpn
*l2vpn
;
1523 if (l2vpn_find(conf
, name
))
1526 l2vpn
= l2vpn_new(name
);
1527 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1528 RB_INSERT(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1529 QOBJ_REG(l2vpn
, l2vpn
);
1534 l2vpn_del_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
)
1536 struct l2vpn_if
*lif
;
1537 struct l2vpn_pw
*pw
;
1539 while (!RB_EMPTY(l2vpn_if_head
, &l2vpn
->if_tree
)) {
1540 lif
= RB_ROOT(l2vpn_if_head
, &l2vpn
->if_tree
);
1543 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1546 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_tree
)) {
1547 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_tree
);
1550 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1553 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)) {
1554 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
);
1557 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1561 RB_REMOVE(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1566 l2vpn_if_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1569 struct l2vpn_if
*lif
;
1571 if (ldp_iface_is_configured(conf
, ifname
))
1574 lif
= l2vpn_if_new(l2vpn
, ifname
);
1575 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1576 QOBJ_REG(lif
, l2vpn_if
);
1581 l2vpn_if_del_api(struct l2vpn
*l2vpn
, struct l2vpn_if
*lif
)
1584 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1589 l2vpn_pw_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1592 struct l2vpn_pw
*pw
;
1594 if (ldp_iface_is_configured(conf
, ifname
))
1597 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1598 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1599 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1600 QOBJ_REG(pw
, l2vpn_pw
);
1605 l2vpn_pw_del_api(struct l2vpn
*l2vpn
, struct l2vpn_pw
*pw
)
1608 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);