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
!= 0)
254 vty_out (vty
, " router-id %s\n",
255 inet_ntoa(ldpd_conf
->rtr_id
));
257 if (ldpd_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
258 ldpd_conf
->lhello_holdtime
!= 0)
259 vty_out (vty
, " discovery hello holdtime %u\n",
260 ldpd_conf
->lhello_holdtime
);
261 if (ldpd_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
262 ldpd_conf
->lhello_interval
!= 0)
263 vty_out (vty
, " discovery hello interval %u\n",
264 ldpd_conf
->lhello_interval
);
266 if (ldpd_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
267 ldpd_conf
->thello_holdtime
!= 0)
268 vty_out (vty
, " discovery targeted-hello holdtime %u\n",
269 ldpd_conf
->thello_holdtime
);
270 if (ldpd_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
271 ldpd_conf
->thello_interval
!= 0)
272 vty_out (vty
, " discovery targeted-hello interval %u\n",
273 ldpd_conf
->thello_interval
);
275 if (ldpd_conf
->trans_pref
== DUAL_STACK_LDPOV4
)
277 " dual-stack transport-connection prefer ipv4\n");
279 if (ldpd_conf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
280 vty_out (vty
, " dual-stack cisco-interop\n");
282 RB_FOREACH(nbrp
, nbrp_head
, &ldpd_conf
->nbrp_tree
) {
283 if (nbrp
->flags
& F_NBRP_KEEPALIVE
)
284 vty_out (vty
, " neighbor %s session holdtime %u\n",
285 inet_ntoa(nbrp
->lsr_id
),nbrp
->keepalive
);
287 if (nbrp
->flags
& F_NBRP_GTSM
) {
288 if (nbrp
->gtsm_enabled
)
289 vty_out (vty
, " neighbor %s ttl-security hops "
290 "%u\n", inet_ntoa(nbrp
->lsr_id
),
293 vty_out (vty
, " neighbor %s ttl-security "
294 "disable\n",inet_ntoa(nbrp
->lsr_id
));
297 if (nbrp
->auth
.method
== AUTH_MD5SIG
)
298 vty_out (vty
, " neighbor %s password %s\n",
299 inet_ntoa(nbrp
->lsr_id
),nbrp
->auth
.md5key
);
302 ldp_af_config_write(vty
, AF_INET
, ldpd_conf
, &ldpd_conf
->ipv4
);
303 ldp_af_config_write(vty
, AF_INET6
, ldpd_conf
, &ldpd_conf
->ipv6
);
304 vty_out (vty
, " !\n");
305 vty_out (vty
, "!\n");
311 ldp_l2vpn_pw_config_write(struct vty
*vty
, struct l2vpn_pw
*pw
)
313 int missing_lsrid
= 0;
314 int missing_pwid
= 0;
316 vty_out (vty
, " !\n");
317 vty_out (vty
, " member pseudowire %s\n", pw
->ifname
);
319 if (pw
->lsr_id
.s_addr
!= INADDR_ANY
)
320 vty_out (vty
, " neighbor lsr-id %s\n",inet_ntoa(pw
->lsr_id
));
324 if (pw
->flags
& F_PW_STATIC_NBR_ADDR
)
325 vty_out (vty
, " neighbor address %s\n",
326 log_addr(pw
->af
, &pw
->addr
));
329 vty_out (vty
, " pw-id %u\n", pw
->pwid
);
333 if (!(pw
->flags
& F_PW_CWORD_CONF
))
334 vty_out (vty
, " control-word exclude\n");
336 if (!(pw
->flags
& F_PW_STATUSTLV_CONF
))
337 vty_out (vty
, " pw-status disable\n");
341 " ! Incomplete config, specify a neighbor lsr-id\n");
343 vty_out (vty
," ! Incomplete config, specify a pw-id\n");
347 ldp_l2vpn_config_write(struct vty
*vty
)
350 struct l2vpn_if
*lif
;
353 RB_FOREACH(l2vpn
, l2vpn_head
, &ldpd_conf
->l2vpn_tree
) {
354 vty_out (vty
, "l2vpn %s type vpls\n", l2vpn
->name
);
356 if (l2vpn
->pw_type
!= DEFAULT_PW_TYPE
)
357 vty_out (vty
, " vc type ethernet-tagged\n");
359 if (l2vpn
->mtu
!= DEFAULT_L2VPN_MTU
)
360 vty_out (vty
, " mtu %u\n", l2vpn
->mtu
);
362 if (l2vpn
->br_ifname
[0] != '\0')
363 vty_out (vty
, " bridge %s\n",l2vpn
->br_ifname
);
365 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
366 vty_out (vty
, " member interface %s\n",lif
->ifname
);
368 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
369 ldp_l2vpn_pw_config_write(vty
, pw
);
370 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
371 ldp_l2vpn_pw_config_write(vty
, pw
);
373 vty_out (vty
, " !\n");
374 vty_out (vty
, "!\n");
381 ldp_vty_get_af(struct vty
*vty
)
385 case LDP_IPV4_IFACE_NODE
:
388 case LDP_IPV6_IFACE_NODE
:
391 fatalx("ldp_vty_get_af: unexpected node");
396 ldp_iface_is_configured(struct ldpd_conf
*xconf
, const char *ifname
)
400 if (if_lookup_name(xconf
, ifname
))
403 RB_FOREACH(l2vpn
, l2vpn_head
, &xconf
->l2vpn_tree
) {
404 if (l2vpn_if_find(l2vpn
, ifname
))
406 if (l2vpn_pw_find(l2vpn
, ifname
))
414 ldp_vty_mpls_ldp(struct vty
*vty
, const char *negate
)
417 vty_conf
->flags
&= ~F_LDPD_ENABLED
;
419 vty
->node
= LDP_NODE
;
420 vty_conf
->flags
|= F_LDPD_ENABLED
;
423 ldp_config_apply(vty
, vty_conf
);
425 return (CMD_SUCCESS
);
429 ldp_vty_address_family(struct vty
*vty
, const char *negate
, const char *af_str
)
431 struct ldpd_af_conf
*af_conf
;
435 return (CMD_WARNING_CONFIG_FAILED
);
437 if (strcmp(af_str
, "ipv4") == 0) {
439 af_conf
= &vty_conf
->ipv4
;
440 } else if (strcmp(af_str
, "ipv6") == 0) {
442 af_conf
= &vty_conf
->ipv6
;
444 return (CMD_WARNING_CONFIG_FAILED
);
447 af_conf
->flags
&= ~F_LDPD_AF_ENABLED
;
448 ldp_config_apply(vty
, vty_conf
);
449 return (CMD_SUCCESS
);
454 vty
->node
= LDP_IPV4_NODE
;
457 vty
->node
= LDP_IPV6_NODE
;
460 fatalx("ldp_vty_address_family: unknown af");
462 af_conf
->flags
|= F_LDPD_AF_ENABLED
;
464 ldp_config_apply(vty
, vty_conf
);
466 return (CMD_SUCCESS
);
469 int ldp_vty_disc_holdtime(struct vty
*vty
, const char *negate
,
470 enum hello_type hello_type
, long secs
)
472 struct ldpd_af_conf
*af_conf
;
480 switch (hello_type
) {
482 vty_conf
->lhello_holdtime
= LINK_DFLT_HOLDTIME
;
485 vty_conf
->thello_holdtime
=
486 TARGETED_DFLT_HOLDTIME
;
490 switch (hello_type
) {
492 vty_conf
->lhello_holdtime
= secs
;
495 vty_conf
->thello_holdtime
= secs
;
499 ldp_config_apply(vty
, vty_conf
);
503 af
= ldp_vty_get_af(vty
);
504 af_conf
= ldp_af_conf_get(vty_conf
, af
);
507 switch (hello_type
) {
509 af_conf
->lhello_holdtime
= 0;
512 af_conf
->thello_holdtime
= 0;
516 switch (hello_type
) {
518 af_conf
->lhello_holdtime
= secs
;
521 af_conf
->thello_holdtime
= secs
;
525 ldp_config_apply(vty
, vty_conf
);
527 case LDP_IPV4_IFACE_NODE
:
528 case LDP_IPV6_IFACE_NODE
:
529 af
= ldp_vty_get_af(vty
);
530 iface
= VTY_GET_CONTEXT(iface
);
531 VTY_CHECK_CONTEXT(iface
);
533 ia
= iface_af_get(iface
, af
);
535 ia
->hello_holdtime
= 0;
537 ia
->hello_holdtime
= secs
;
539 ldp_config_apply(vty
, vty_conf
);
542 fatalx("ldp_vty_disc_holdtime: unexpected node");
545 return (CMD_SUCCESS
);
549 ldp_vty_disc_interval(struct vty
*vty
, const char *negate
,
550 enum hello_type hello_type
, long secs
)
552 struct ldpd_af_conf
*af_conf
;
560 switch (hello_type
) {
562 vty_conf
->lhello_interval
=
563 DEFAULT_HELLO_INTERVAL
;
566 vty_conf
->thello_interval
=
567 DEFAULT_HELLO_INTERVAL
;
571 switch (hello_type
) {
573 vty_conf
->lhello_interval
= secs
;
576 vty_conf
->thello_interval
= secs
;
580 ldp_config_apply(vty
, vty_conf
);
584 af
= ldp_vty_get_af(vty
);
585 af_conf
= ldp_af_conf_get(vty_conf
, af
);
588 switch (hello_type
) {
590 af_conf
->lhello_interval
= 0;
593 af_conf
->thello_interval
= 0;
597 switch (hello_type
) {
599 af_conf
->lhello_interval
= secs
;
602 af_conf
->thello_interval
= secs
;
606 ldp_config_apply(vty
, vty_conf
);
608 case LDP_IPV4_IFACE_NODE
:
609 case LDP_IPV6_IFACE_NODE
:
610 af
= ldp_vty_get_af(vty
);
611 iface
= VTY_GET_CONTEXT(iface
);
612 VTY_CHECK_CONTEXT(iface
);
614 ia
= iface_af_get(iface
, af
);
616 ia
->hello_interval
= 0;
618 ia
->hello_interval
= secs
;
620 ldp_config_apply(vty
, vty_conf
);
623 fatalx("ldp_vty_disc_interval: unexpected node");
626 return (CMD_SUCCESS
);
630 ldp_vty_targeted_hello_accept(struct vty
*vty
, const char *negate
,
631 const char *acl_from_str
)
633 struct ldpd_af_conf
*af_conf
;
636 af
= ldp_vty_get_af(vty
);
637 af_conf
= ldp_af_conf_get(vty_conf
, af
);
640 af_conf
->flags
&= ~F_LDPD_AF_THELLO_ACCEPT
;
641 af_conf
->acl_thello_accept_from
[0] = '\0';
643 af_conf
->flags
|= F_LDPD_AF_THELLO_ACCEPT
;
645 strlcpy(af_conf
->acl_thello_accept_from
, acl_from_str
,
646 sizeof(af_conf
->acl_thello_accept_from
));
648 af_conf
->acl_thello_accept_from
[0] = '\0';
651 ldp_config_apply(vty
, vty_conf
);
653 return (CMD_SUCCESS
);
657 ldp_vty_nbr_session_holdtime(struct vty
*vty
, const char *negate
,
658 struct in_addr lsr_id
, long secs
)
660 struct nbr_params
*nbrp
;
662 if (bad_addr_v4(lsr_id
)) {
663 vty_out (vty
, "%% Malformed address\n");
664 return (CMD_WARNING_CONFIG_FAILED
);
667 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
671 return (CMD_SUCCESS
);
674 nbrp
->flags
&= ~F_NBRP_KEEPALIVE
;
677 nbrp
= nbr_params_new(lsr_id
);
678 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
679 QOBJ_REG(nbrp
, nbr_params
);
680 } else if (nbrp
->keepalive
== secs
)
681 return (CMD_SUCCESS
);
683 nbrp
->keepalive
= secs
;
684 nbrp
->flags
|= F_NBRP_KEEPALIVE
;
687 ldp_config_apply(vty
, vty_conf
);
689 return (CMD_SUCCESS
);
693 ldp_vty_af_session_holdtime(struct vty
*vty
, const char *negate
, long secs
)
695 struct ldpd_af_conf
*af_conf
;
698 af
= ldp_vty_get_af(vty
);
699 af_conf
= ldp_af_conf_get(vty_conf
, af
);
702 af_conf
->keepalive
= DEFAULT_KEEPALIVE
;
704 af_conf
->keepalive
= secs
;
706 ldp_config_apply(vty
, vty_conf
);
708 return (CMD_SUCCESS
);
712 ldp_vty_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
718 if (ifname
== NULL
) {
719 vty_out (vty
, "%% Missing IF name\n");
720 return (CMD_WARNING_CONFIG_FAILED
);
723 af
= ldp_vty_get_af(vty
);
724 iface
= if_lookup_name(vty_conf
, ifname
);
728 return (CMD_SUCCESS
);
730 ia
= iface_af_get(iface
, af
);
731 if (ia
->enabled
== 0)
732 return (CMD_SUCCESS
);
735 ia
->hello_holdtime
= 0;
736 ia
->hello_interval
= 0;
738 ldp_config_apply(vty
, vty_conf
);
740 return (CMD_SUCCESS
);
744 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
745 vty_out (vty
,"%% Interface is already in use\n");
746 return (CMD_SUCCESS
);
749 iface
= if_new(ifname
);
750 ia
= iface_af_get(iface
, af
);
752 RB_INSERT(iface_head
, &vty_conf
->iface_tree
, iface
);
753 QOBJ_REG(iface
, iface
);
755 ldp_config_apply(vty
, vty_conf
);
757 ia
= iface_af_get(iface
, af
);
760 ldp_config_apply(vty
, vty_conf
);
766 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE
, iface
);
769 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE
, iface
);
775 return (CMD_SUCCESS
);
779 ldp_vty_trans_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
781 struct ldpd_af_conf
*af_conf
;
784 af
= ldp_vty_get_af(vty
);
785 af_conf
= ldp_af_conf_get(vty_conf
, af
);
788 memset(&af_conf
->trans_addr
, 0, sizeof(af_conf
->trans_addr
));
791 || inet_pton(af
, addr_str
, &af_conf
->trans_addr
) != 1
792 || bad_addr(af
, &af_conf
->trans_addr
)) {
793 vty_out (vty
, "%% Malformed address\n");
794 return (CMD_SUCCESS
);
798 ldp_config_apply(vty
, vty_conf
);
800 return (CMD_SUCCESS
);
804 ldp_vty_neighbor_targeted(struct vty
*vty
, const char *negate
, const char *addr_str
)
807 union ldpd_addr addr
;
810 af
= ldp_vty_get_af(vty
);
812 if (addr_str
== NULL
|| inet_pton(af
, addr_str
, &addr
) != 1 ||
813 bad_addr(af
, &addr
)) {
814 vty_out (vty
, "%% Malformed address\n");
815 return (CMD_WARNING_CONFIG_FAILED
);
817 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
.v6
)) {
818 vty_out (vty
, "%% Address can not be link-local\n");
819 return (CMD_WARNING_CONFIG_FAILED
);
822 tnbr
= tnbr_find(vty_conf
, af
, &addr
);
826 return (CMD_SUCCESS
);
829 RB_REMOVE(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
832 ldp_config_apply(vty
, vty_conf
);
834 return (CMD_SUCCESS
);
838 return (CMD_SUCCESS
);
840 tnbr
= tnbr_new(af
, &addr
);
841 tnbr
->flags
|= F_TNBR_CONFIGURED
;
842 RB_INSERT(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
843 QOBJ_REG(tnbr
, tnbr
);
845 ldp_config_apply(vty
, vty_conf
);
847 return (CMD_SUCCESS
);
851 ldp_vty_label_advertise(struct vty
*vty
, const char *negate
, const char *acl_to_str
,
852 const char *acl_for_str
)
854 struct ldpd_af_conf
*af_conf
;
857 af
= ldp_vty_get_af(vty
);
858 af_conf
= ldp_af_conf_get(vty_conf
, af
);
861 af_conf
->acl_label_advertise_to
[0] = '\0';
862 af_conf
->acl_label_advertise_for
[0] = '\0';
865 strlcpy(af_conf
->acl_label_advertise_to
, acl_to_str
,
866 sizeof(af_conf
->acl_label_advertise_to
));
868 af_conf
->acl_label_advertise_to
[0] = '\0';
870 strlcpy(af_conf
->acl_label_advertise_for
, acl_for_str
,
871 sizeof(af_conf
->acl_label_advertise_for
));
873 af_conf
->acl_label_advertise_for
[0] = '\0';
876 ldp_config_apply(vty
, vty_conf
);
878 return (CMD_SUCCESS
);
882 ldp_vty_label_allocate(struct vty
*vty
, const char *negate
, const char *host_routes
,
883 const char *acl_for_str
)
885 struct ldpd_af_conf
*af_conf
;
888 af
= ldp_vty_get_af(vty
);
889 af_conf
= ldp_af_conf_get(vty_conf
, af
);
891 af_conf
->flags
&= ~F_LDPD_AF_ALLOCHOSTONLY
;
892 af_conf
->acl_label_allocate_for
[0] = '\0';
895 af_conf
->flags
|= F_LDPD_AF_ALLOCHOSTONLY
;
897 strlcpy(af_conf
->acl_label_allocate_for
, acl_for_str
,
898 sizeof(af_conf
->acl_label_allocate_for
));
901 ldp_config_apply(vty
, vty_conf
);
903 return (CMD_SUCCESS
);
907 ldp_vty_label_expnull(struct vty
*vty
, const char *negate
, const char *acl_for_str
)
909 struct ldpd_af_conf
*af_conf
;
912 af
= ldp_vty_get_af(vty
);
913 af_conf
= ldp_af_conf_get(vty_conf
, af
);
916 af_conf
->flags
&= ~F_LDPD_AF_EXPNULL
;
917 af_conf
->acl_label_expnull_for
[0] = '\0';
919 af_conf
->flags
|= F_LDPD_AF_EXPNULL
;
921 strlcpy(af_conf
->acl_label_expnull_for
, acl_for_str
,
922 sizeof(af_conf
->acl_label_expnull_for
));
924 af_conf
->acl_label_expnull_for
[0] = '\0';
927 ldp_config_apply(vty
, vty_conf
);
929 return (CMD_SUCCESS
);
933 ldp_vty_label_accept(struct vty
*vty
, const char *negate
, const char *acl_from_str
,
934 const char *acl_for_str
)
936 struct ldpd_af_conf
*af_conf
;
939 af
= ldp_vty_get_af(vty
);
940 af_conf
= ldp_af_conf_get(vty_conf
, af
);
943 af_conf
->acl_label_accept_from
[0] = '\0';
944 af_conf
->acl_label_accept_for
[0] = '\0';
947 strlcpy(af_conf
->acl_label_accept_from
, acl_from_str
,
948 sizeof(af_conf
->acl_label_accept_from
));
950 af_conf
->acl_label_accept_from
[0] = '\0';
952 strlcpy(af_conf
->acl_label_accept_for
, acl_for_str
,
953 sizeof(af_conf
->acl_label_accept_for
));
955 af_conf
->acl_label_accept_for
[0] = '\0';
958 ldp_config_apply(vty
, vty_conf
);
960 return (CMD_SUCCESS
);
964 ldp_vty_ttl_security(struct vty
*vty
, const char *negate
)
966 struct ldpd_af_conf
*af_conf
;
969 af
= ldp_vty_get_af(vty
);
970 af_conf
= ldp_af_conf_get(vty_conf
, af
);
973 af_conf
->flags
&= ~F_LDPD_AF_NO_GTSM
;
975 af_conf
->flags
|= F_LDPD_AF_NO_GTSM
;
977 ldp_config_apply(vty
, vty_conf
);
979 return (CMD_SUCCESS
);
983 ldp_vty_router_id(struct vty
*vty
, const char *negate
, struct in_addr address
)
986 vty_conf
->rtr_id
.s_addr
= INADDR_ANY
;
988 if (bad_addr_v4(address
)) {
989 vty_out (vty
, "%% Malformed address\n");
990 return (CMD_SUCCESS
);
992 vty_conf
->rtr_id
= address
;
995 ldp_config_apply(vty
, vty_conf
);
997 return (CMD_SUCCESS
);
1001 ldp_vty_ds_cisco_interop(struct vty
*vty
, const char * negate
)
1004 vty_conf
->flags
&= ~F_LDPD_DS_CISCO_INTEROP
;
1006 vty_conf
->flags
|= F_LDPD_DS_CISCO_INTEROP
;
1008 ldp_config_apply(vty
, vty_conf
);
1010 return (CMD_SUCCESS
);
1014 ldp_vty_trans_pref_ipv4(struct vty
*vty
, const char *negate
)
1017 vty_conf
->trans_pref
= DUAL_STACK_LDPOV6
;
1019 vty_conf
->trans_pref
= DUAL_STACK_LDPOV4
;
1021 ldp_config_apply(vty
, vty_conf
);
1023 return (CMD_SUCCESS
);
1027 ldp_vty_neighbor_password(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
,
1028 const char *password_str
)
1030 size_t password_len
;
1031 struct nbr_params
*nbrp
;
1033 if (password_str
== NULL
) {
1034 vty_out (vty
, "%% Missing password\n");
1035 return (CMD_WARNING_CONFIG_FAILED
);
1038 if (bad_addr_v4(lsr_id
)) {
1039 vty_out (vty
, "%% Malformed address\n");
1040 return (CMD_WARNING_CONFIG_FAILED
);
1043 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1047 return (CMD_SUCCESS
);
1049 memset(&nbrp
->auth
, 0, sizeof(nbrp
->auth
));
1050 nbrp
->auth
.method
= AUTH_NONE
;
1053 nbrp
= nbr_params_new(lsr_id
);
1054 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1055 QOBJ_REG(nbrp
, nbr_params
);
1056 } else if (nbrp
->auth
.method
== AUTH_MD5SIG
&&
1057 strcmp(nbrp
->auth
.md5key
, password_str
) == 0)
1058 return (CMD_SUCCESS
);
1060 password_len
= strlcpy(nbrp
->auth
.md5key
, password_str
,
1061 sizeof(nbrp
->auth
.md5key
));
1062 if (password_len
>= sizeof(nbrp
->auth
.md5key
))
1063 vty_out(vty
, "%% password has been truncated to %zu "
1064 "characters.", sizeof(nbrp
->auth
.md5key
) - 1);
1065 nbrp
->auth
.md5key_len
= password_len
;
1066 nbrp
->auth
.method
= AUTH_MD5SIG
;
1069 ldp_config_apply(vty
, vty_conf
);
1071 return (CMD_SUCCESS
);
1075 ldp_vty_neighbor_ttl_security(struct vty
*vty
, const char *negate
,
1076 struct in_addr lsr_id
, const char *hops_str
)
1078 struct nbr_params
*nbrp
;
1082 if (bad_addr_v4(lsr_id
)) {
1083 vty_out (vty
, "%% Malformed address\n");
1084 return (CMD_WARNING_CONFIG_FAILED
);
1088 hops
= strtol(hops_str
, &ep
, 10);
1089 if (*ep
!= '\0' || hops
< 1 || hops
> 254) {
1090 vty_out (vty
, "%% Invalid hop count\n");
1091 return (CMD_SUCCESS
);
1095 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1099 return (CMD_SUCCESS
);
1101 nbrp
->flags
&= ~(F_NBRP_GTSM
|F_NBRP_GTSM_HOPS
);
1102 nbrp
->gtsm_enabled
= 0;
1103 nbrp
->gtsm_hops
= 0;
1106 nbrp
= nbr_params_new(lsr_id
);
1107 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1108 QOBJ_REG(nbrp
, nbr_params
);
1111 nbrp
->flags
|= F_NBRP_GTSM
;
1112 nbrp
->flags
&= ~F_NBRP_GTSM_HOPS
;
1114 nbrp
->gtsm_enabled
= 1;
1115 nbrp
->gtsm_hops
= hops
;
1116 nbrp
->flags
|= F_NBRP_GTSM_HOPS
;
1118 nbrp
->gtsm_enabled
= 0;
1121 ldp_config_apply(vty
, vty_conf
);
1123 return (CMD_SUCCESS
);
1127 ldp_vty_l2vpn(struct vty
*vty
, const char *negate
, const char *name_str
)
1129 struct l2vpn
*l2vpn
;
1130 struct l2vpn_if
*lif
;
1131 struct l2vpn_pw
*pw
;
1133 if (name_str
== NULL
) {
1134 vty_out (vty
, "%% Missing name\n");
1135 return (CMD_WARNING_CONFIG_FAILED
);
1138 l2vpn
= l2vpn_find(vty_conf
, name_str
);
1142 return (CMD_SUCCESS
);
1144 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
1146 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
1148 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
1151 RB_REMOVE(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1154 ldp_config_apply(vty
, vty_conf
);
1156 return (CMD_SUCCESS
);
1160 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1161 return (CMD_SUCCESS
);
1164 l2vpn
= l2vpn_new(name_str
);
1165 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1166 RB_INSERT(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1167 QOBJ_REG(l2vpn
, l2vpn
);
1169 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1171 ldp_config_apply(vty
, vty_conf
);
1173 return (CMD_SUCCESS
);
1177 ldp_vty_l2vpn_bridge(struct vty
*vty
, const char *negate
, const char *ifname
)
1179 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1182 memset(l2vpn
->br_ifname
, 0, sizeof(l2vpn
->br_ifname
));
1184 if (ifname
== NULL
) {
1185 vty_out (vty
, "%% Missing IF name\n");
1186 return (CMD_WARNING_CONFIG_FAILED
);
1188 strlcpy(l2vpn
->br_ifname
, ifname
, sizeof(l2vpn
->br_ifname
));
1191 ldp_config_apply(vty
, vty_conf
);
1193 return (CMD_SUCCESS
);
1197 ldp_vty_l2vpn_mtu(struct vty
*vty
, const char *negate
, long mtu
)
1199 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1202 l2vpn
->mtu
= DEFAULT_L2VPN_MTU
;
1206 ldp_config_apply(vty
, vty_conf
);
1208 return (CMD_SUCCESS
);
1212 ldp_vty_l2vpn_pwtype(struct vty
*vty
, const char *negate
, const char *type_str
)
1214 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1217 if (type_str
== NULL
) {
1218 vty_out (vty
, "%% Missing type\n");
1219 return (CMD_WARNING_CONFIG_FAILED
);
1222 if (strcmp(type_str
, "ethernet") == 0)
1223 pw_type
= PW_TYPE_ETHERNET
;
1225 pw_type
= PW_TYPE_ETHERNET_TAGGED
;
1228 l2vpn
->pw_type
= DEFAULT_PW_TYPE
;
1230 l2vpn
->pw_type
= pw_type
;
1232 ldp_config_apply(vty
, vty_conf
);
1234 return (CMD_SUCCESS
);
1238 ldp_vty_l2vpn_interface(struct vty
*vty
, const char *negate
, const char *ifname
)
1240 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1241 struct l2vpn_if
*lif
;
1243 if (ifname
== NULL
) {
1244 vty_out (vty
, "%% Missing IF name\n");
1245 return (CMD_WARNING_CONFIG_FAILED
);
1248 lif
= l2vpn_if_find(l2vpn
, ifname
);
1252 return (CMD_SUCCESS
);
1255 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1258 ldp_config_apply(vty
, vty_conf
);
1260 return (CMD_SUCCESS
);
1264 return (CMD_SUCCESS
);
1266 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1267 vty_out (vty
, "%% Interface is already in use\n");
1268 return (CMD_SUCCESS
);
1271 lif
= l2vpn_if_new(l2vpn
, ifname
);
1272 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1273 QOBJ_REG(lif
, l2vpn_if
);
1275 ldp_config_apply(vty
, vty_conf
);
1277 return (CMD_SUCCESS
);
1281 ldp_vty_l2vpn_pseudowire(struct vty
*vty
, const char *negate
, const char *ifname
)
1283 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1284 struct l2vpn_pw
*pw
;
1286 if (ifname
== NULL
) {
1287 vty_out (vty
, "%% Missing IF name\n");
1288 return (CMD_WARNING_CONFIG_FAILED
);
1291 pw
= l2vpn_pw_find(l2vpn
, ifname
);
1295 return (CMD_SUCCESS
);
1298 if (pw
->lsr_id
.s_addr
== INADDR_ANY
|| pw
->pwid
== 0)
1299 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1301 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1304 ldp_config_apply(vty
, vty_conf
);
1306 return (CMD_SUCCESS
);
1310 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1311 return (CMD_SUCCESS
);
1314 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1315 vty_out (vty
, "%% Interface is already in use\n");
1316 return (CMD_SUCCESS
);
1319 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1320 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1321 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1322 QOBJ_REG(pw
, l2vpn_pw
);
1324 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1326 ldp_config_apply(vty
, vty_conf
);
1328 return (CMD_SUCCESS
);
1332 ldp_vty_l2vpn_pw_cword(struct vty
*vty
, const char *negate
, const char *preference_str
)
1334 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1337 pw
->flags
|= F_PW_CWORD_CONF
;
1339 if (!preference_str
) {
1340 vty_out (vty
, "%% Missing preference\n");
1341 return (CMD_WARNING_CONFIG_FAILED
);
1343 if (preference_str
[0] == 'e')
1344 pw
->flags
&= ~F_PW_CWORD_CONF
;
1346 pw
->flags
|= F_PW_CWORD_CONF
;
1349 ldp_config_apply(vty
, vty_conf
);
1351 return (CMD_SUCCESS
);
1355 ldp_vty_l2vpn_pw_nbr_addr(struct vty
*vty
, const char *negate
, const char *addr_str
)
1357 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1359 union ldpd_addr addr
;
1361 if (ldp_get_address(addr_str
, &af
, &addr
) == -1 ||
1362 bad_addr(af
, &addr
)) {
1363 vty_out (vty
, "%% Malformed address\n");
1364 return (CMD_WARNING_CONFIG_FAILED
);
1369 memset(&pw
->addr
, 0, sizeof(pw
->addr
));
1370 pw
->flags
&= ~F_PW_STATIC_NBR_ADDR
;
1374 pw
->flags
|= F_PW_STATIC_NBR_ADDR
;
1377 ldp_config_apply(vty
, vty_conf
);
1379 return (CMD_SUCCESS
);
1383 ldp_vty_l2vpn_pw_nbr_id(struct vty
*vty
, const char *negate
, struct in_addr lsr_id
)
1385 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1387 if (bad_addr_v4(lsr_id
)) {
1388 vty_out (vty
, "%% Malformed address\n");
1389 return (CMD_WARNING_CONFIG_FAILED
);
1393 pw
->lsr_id
.s_addr
= INADDR_ANY
;
1395 pw
->lsr_id
= lsr_id
;
1397 ldp_config_apply(vty
, vty_conf
);
1399 return (CMD_SUCCESS
);
1403 ldp_vty_l2vpn_pw_pwid(struct vty
*vty
, const char *negate
, long pwid
)
1405 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1412 ldp_config_apply(vty
, vty_conf
);
1414 return (CMD_SUCCESS
);
1418 ldp_vty_l2vpn_pw_pwstatus(struct vty
*vty
, const char *negate
)
1420 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1423 pw
->flags
|= F_PW_STATUSTLV_CONF
;
1425 pw
->flags
&= ~F_PW_STATUSTLV_CONF
;
1427 ldp_config_apply(vty
, vty_conf
);
1429 return (CMD_SUCCESS
);
1433 iface_new_api(struct ldpd_conf
*conf
, const char *name
)
1435 const char *ifname
= name
;
1436 struct iface
*iface
;
1438 if (ldp_iface_is_configured(conf
, ifname
))
1441 iface
= if_new(name
);
1442 RB_INSERT(iface_head
, &conf
->iface_tree
, iface
);
1443 QOBJ_REG(iface
, iface
);
1448 iface_del_api(struct ldpd_conf
*conf
, struct iface
*iface
)
1451 RB_REMOVE(iface_head
, &conf
->iface_tree
, iface
);
1456 tnbr_new_api(struct ldpd_conf
*conf
, int af
, union ldpd_addr
*addr
)
1460 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
->v6
))
1463 if (tnbr_find(conf
, af
, addr
))
1466 tnbr
= tnbr_new(af
, addr
);
1467 tnbr
->flags
|= F_TNBR_CONFIGURED
;
1468 RB_INSERT(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1469 QOBJ_REG(tnbr
, tnbr
);
1474 tnbr_del_api(struct ldpd_conf
*conf
, struct tnbr
*tnbr
)
1477 RB_REMOVE(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1482 nbrp_new_api(struct ldpd_conf
*conf
, struct in_addr lsr_id
)
1484 struct nbr_params
*nbrp
;
1486 if (nbr_params_find(conf
, lsr_id
))
1489 nbrp
= nbr_params_new(lsr_id
);
1490 RB_INSERT(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1491 QOBJ_REG(nbrp
, nbr_params
);
1496 nbrp_del_api(struct ldpd_conf
*conf
, struct nbr_params
*nbrp
)
1499 RB_REMOVE(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1504 l2vpn_new_api(struct ldpd_conf
*conf
, const char *name
)
1506 struct l2vpn
*l2vpn
;
1508 if (l2vpn_find(conf
, name
))
1511 l2vpn
= l2vpn_new(name
);
1512 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1513 RB_INSERT(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1514 QOBJ_REG(l2vpn
, l2vpn
);
1519 l2vpn_del_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
)
1521 struct l2vpn_if
*lif
;
1522 struct l2vpn_pw
*pw
;
1524 while (!RB_EMPTY(l2vpn_if_head
, &l2vpn
->if_tree
)) {
1525 lif
= RB_ROOT(l2vpn_if_head
, &l2vpn
->if_tree
);
1528 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1531 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_tree
)) {
1532 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_tree
);
1535 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1538 while (!RB_EMPTY(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)) {
1539 pw
= RB_ROOT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
);
1542 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1546 RB_REMOVE(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1551 l2vpn_if_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1554 struct l2vpn_if
*lif
;
1556 if (ldp_iface_is_configured(conf
, ifname
))
1559 lif
= l2vpn_if_new(l2vpn
, ifname
);
1560 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1561 QOBJ_REG(lif
, l2vpn_if
);
1566 l2vpn_if_del_api(struct l2vpn
*l2vpn
, struct l2vpn_if
*lif
)
1569 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1574 l2vpn_pw_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1577 struct l2vpn_pw
*pw
;
1579 if (ldp_iface_is_configured(conf
, ifname
))
1582 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1583 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1584 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1585 QOBJ_REG(pw
, l2vpn_pw
);
1590 l2vpn_pw_del_api(struct l2vpn
*l2vpn
, struct l2vpn_pw
*pw
)
1593 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);