2 * Copyright (C) 2016 by Open Source Routing.
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 static void ldp_af_iface_config_write(struct vty
*, int);
35 static void ldp_af_config_write(struct vty
*, int, struct ldpd_conf
*,
36 struct ldpd_af_conf
*);
37 static void ldp_l2vpn_pw_config_write(struct vty
*, struct l2vpn_pw
*);
38 static int ldp_vty_get_af(struct vty
*);
39 static int ldp_iface_is_configured(struct ldpd_conf
*, const char *);
40 static int ldp_vty_nbr_session_holdtime(struct vty
*, struct vty_arg
*[]);
41 static int ldp_vty_af_session_holdtime(struct vty
*, struct vty_arg
*[]);
43 struct cmd_node ldp_node
=
50 struct cmd_node ldp_ipv4_node
=
53 "%s(config-ldp-af)# ",
57 struct cmd_node ldp_ipv6_node
=
60 "%s(config-ldp-af)# ",
64 struct cmd_node ldp_ipv4_iface_node
=
67 "%s(config-ldp-af-if)# ",
71 struct cmd_node ldp_ipv6_iface_node
=
74 "%s(config-ldp-af-if)# ",
78 struct cmd_node ldp_l2vpn_node
=
85 struct cmd_node ldp_pseudowire_node
=
88 "%s(config-l2vpn-pw)# ",
93 ldp_get_address(const char *str
, int *af
, union ldpd_addr
*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
, " !%s", VTY_NEWLINE
);
122 vty_out(vty
, " interface %s%s", iface
->name
, VTY_NEWLINE
);
124 if (ia
->hello_holdtime
!= LINK_DFLT_HOLDTIME
&&
125 ia
->hello_holdtime
!= 0)
126 vty_out(vty
, " discovery hello holdtime %u%s",
127 ia
->hello_holdtime
, VTY_NEWLINE
);
128 if (ia
->hello_interval
!= DEFAULT_HELLO_INTERVAL
&&
129 ia
->hello_interval
!= 0)
130 vty_out(vty
, " discovery hello interval %u%s",
131 ia
->hello_interval
, VTY_NEWLINE
);
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
, " !%s", VTY_NEWLINE
);
145 vty_out(vty
, " address-family %s%s", af_name(af
), VTY_NEWLINE
);
147 if (af_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
148 af_conf
->lhello_holdtime
!= 0 )
149 vty_out(vty
, " discovery hello holdtime %u%s",
150 af_conf
->lhello_holdtime
, VTY_NEWLINE
);
151 if (af_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
152 af_conf
->lhello_interval
!= 0)
153 vty_out(vty
, " discovery hello interval %u%s",
154 af_conf
->lhello_interval
, VTY_NEWLINE
);
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
);
161 vty_out(vty
, "%s", VTY_NEWLINE
);
164 if (af_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
165 af_conf
->thello_holdtime
!= 0)
166 vty_out(vty
, " discovery targeted-hello holdtime %u%s",
167 af_conf
->thello_holdtime
, VTY_NEWLINE
);
168 if (af_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
169 af_conf
->thello_interval
!= 0)
170 vty_out(vty
, " discovery targeted-hello interval %u%s",
171 af_conf
->thello_interval
, VTY_NEWLINE
);
173 if (ldp_addrisset(af
, &af_conf
->trans_addr
))
174 vty_out(vty
, " discovery transport-address %s%s",
175 log_addr(af
, &af_conf
->trans_addr
), VTY_NEWLINE
);
177 vty_out(vty
, " ! Incomplete config, specify a discovery "
178 "transport-address%s", VTY_NEWLINE
);
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
);
188 vty_out(vty
, "%s", VTY_NEWLINE
);
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
);
200 vty_out(vty
, "%s", VTY_NEWLINE
);
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
);
208 vty_out(vty
, "%s", VTY_NEWLINE
);
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
);
220 vty_out(vty
, "%s", VTY_NEWLINE
);
223 if (af_conf
->flags
& F_LDPD_AF_NO_GTSM
)
224 vty_out(vty
, " ttl-security disable%s", VTY_NEWLINE
);
226 if (af_conf
->keepalive
!= DEFAULT_KEEPALIVE
)
227 vty_out(vty
, " session holdtime %u%s", af_conf
->keepalive
,
230 RB_FOREACH(tnbr
, tnbr_head
, &ldpd_conf
->tnbr_tree
) {
231 if (tnbr
->af
== af
) {
232 vty_out(vty
, " !%s", VTY_NEWLINE
);
233 vty_out(vty
, " neighbor %s targeted%s",
234 log_addr(tnbr
->af
, &tnbr
->addr
), VTY_NEWLINE
);
238 ldp_af_iface_config_write(vty
, af
);
240 vty_out(vty
, " !%s", VTY_NEWLINE
);
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%s", VTY_NEWLINE
);
253 if (ldpd_conf
->rtr_id
.s_addr
!= 0)
254 vty_out(vty
, " router-id %s%s",
255 inet_ntoa(ldpd_conf
->rtr_id
), VTY_NEWLINE
);
257 if (ldpd_conf
->lhello_holdtime
!= LINK_DFLT_HOLDTIME
&&
258 ldpd_conf
->lhello_holdtime
!= 0)
259 vty_out(vty
, " discovery hello holdtime %u%s",
260 ldpd_conf
->lhello_holdtime
, VTY_NEWLINE
);
261 if (ldpd_conf
->lhello_interval
!= DEFAULT_HELLO_INTERVAL
&&
262 ldpd_conf
->lhello_interval
!= 0)
263 vty_out(vty
, " discovery hello interval %u%s",
264 ldpd_conf
->lhello_interval
, VTY_NEWLINE
);
266 if (ldpd_conf
->thello_holdtime
!= TARGETED_DFLT_HOLDTIME
&&
267 ldpd_conf
->thello_holdtime
!= 0)
268 vty_out(vty
, " discovery targeted-hello holdtime %u%s",
269 ldpd_conf
->thello_holdtime
, VTY_NEWLINE
);
270 if (ldpd_conf
->thello_interval
!= DEFAULT_HELLO_INTERVAL
&&
271 ldpd_conf
->thello_interval
!= 0)
272 vty_out(vty
, " discovery targeted-hello interval %u%s",
273 ldpd_conf
->thello_interval
, VTY_NEWLINE
);
275 if (ldpd_conf
->trans_pref
== DUAL_STACK_LDPOV4
)
276 vty_out(vty
, " dual-stack transport-connection prefer ipv4%s",
279 if (ldpd_conf
->flags
& F_LDPD_DS_CISCO_INTEROP
)
280 vty_out(vty
, " dual-stack cisco-interop%s", VTY_NEWLINE
);
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%s",
285 inet_ntoa(nbrp
->lsr_id
), nbrp
->keepalive
,
288 if (nbrp
->flags
& F_NBRP_GTSM
) {
289 if (nbrp
->gtsm_enabled
)
290 vty_out(vty
, " neighbor %s ttl-security hops "
291 "%u%s", inet_ntoa(nbrp
->lsr_id
),
292 nbrp
->gtsm_hops
, VTY_NEWLINE
);
294 vty_out(vty
, " neighbor %s ttl-security "
295 "disable%s", inet_ntoa(nbrp
->lsr_id
),
299 if (nbrp
->auth
.method
== AUTH_MD5SIG
)
300 vty_out(vty
, " neighbor %s password %s%s",
301 inet_ntoa(nbrp
->lsr_id
), nbrp
->auth
.md5key
,
305 ldp_af_config_write(vty
, AF_INET
, ldpd_conf
, &ldpd_conf
->ipv4
);
306 ldp_af_config_write(vty
, AF_INET6
, ldpd_conf
, &ldpd_conf
->ipv6
);
307 vty_out(vty
, " !%s", VTY_NEWLINE
);
308 vty_out(vty
, "!%s", VTY_NEWLINE
);
314 ldp_l2vpn_pw_config_write(struct vty
*vty
, struct l2vpn_pw
*pw
)
316 int missing_lsrid
= 0;
317 int missing_pwid
= 0;
319 vty_out(vty
, " !%s", VTY_NEWLINE
);
320 vty_out(vty
, " member pseudowire %s%s", pw
->ifname
, VTY_NEWLINE
);
322 if (pw
->lsr_id
.s_addr
!= INADDR_ANY
)
323 vty_out(vty
, " neighbor lsr-id %s%s", inet_ntoa(pw
->lsr_id
),
328 if (pw
->flags
& F_PW_STATIC_NBR_ADDR
)
329 vty_out(vty
, " neighbor address %s%s", log_addr(pw
->af
,
330 &pw
->addr
), VTY_NEWLINE
);
333 vty_out(vty
, " pw-id %u%s", pw
->pwid
, VTY_NEWLINE
);
337 if (!(pw
->flags
& F_PW_CWORD_CONF
))
338 vty_out(vty
, " control-word exclude%s", VTY_NEWLINE
);
340 if (!(pw
->flags
& F_PW_STATUSTLV_CONF
))
341 vty_out(vty
, " pw-status disable%s", VTY_NEWLINE
);
344 vty_out(vty
, " ! Incomplete config, specify a neighbor "
345 "lsr-id%s", VTY_NEWLINE
);
347 vty_out(vty
, " ! Incomplete config, specify a pw-id%s",
352 ldp_l2vpn_config_write(struct vty
*vty
)
355 struct l2vpn_if
*lif
;
358 RB_FOREACH(l2vpn
, l2vpn_head
, &ldpd_conf
->l2vpn_tree
) {
359 vty_out(vty
, "l2vpn %s type vpls%s", l2vpn
->name
, VTY_NEWLINE
);
361 if (l2vpn
->pw_type
!= DEFAULT_PW_TYPE
)
362 vty_out(vty
, " vc type ethernet-tagged%s", VTY_NEWLINE
);
364 if (l2vpn
->mtu
!= DEFAULT_L2VPN_MTU
)
365 vty_out(vty
, " mtu %u%s", l2vpn
->mtu
, VTY_NEWLINE
);
367 if (l2vpn
->br_ifname
[0] != '\0')
368 vty_out(vty
, " bridge %s%s", l2vpn
->br_ifname
,
371 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
372 vty_out(vty
, " member interface %s%s", lif
->ifname
,
375 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
376 ldp_l2vpn_pw_config_write(vty
, pw
);
377 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
378 ldp_l2vpn_pw_config_write(vty
, pw
);
380 vty_out(vty
, " !%s", VTY_NEWLINE
);
381 vty_out(vty
, "!%s", VTY_NEWLINE
);
388 ldp_vty_get_af(struct vty
*vty
)
392 case LDP_IPV4_IFACE_NODE
:
395 case LDP_IPV6_IFACE_NODE
:
398 fatalx("ldp_vty_get_af: unexpected node");
403 ldp_iface_is_configured(struct ldpd_conf
*xconf
, const char *ifname
)
407 if (if_lookup_name(xconf
, ifname
))
410 RB_FOREACH(l2vpn
, l2vpn_head
, &xconf
->l2vpn_tree
) {
411 if (l2vpn_if_find(l2vpn
, ifname
))
413 if (l2vpn_pw_find(l2vpn
, ifname
))
421 ldp_vty_mpls_ldp(struct vty
*vty
, struct vty_arg
*args
[])
425 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
428 vty_conf
->flags
&= ~F_LDPD_ENABLED
;
430 vty
->node
= LDP_NODE
;
431 vty_conf
->flags
|= F_LDPD_ENABLED
;
434 ldp_config_apply(vty
, vty_conf
);
436 return (CMD_SUCCESS
);
440 ldp_vty_address_family(struct vty
*vty
, struct vty_arg
*args
[])
442 struct ldpd_af_conf
*af_conf
;
447 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
448 af_str
= vty_get_arg_value(args
, "address-family");
450 if (strcmp(af_str
, "ipv4") == 0) {
452 af_conf
= &vty_conf
->ipv4
;
453 } else if (strcmp(af_str
, "ipv6") == 0) {
455 af_conf
= &vty_conf
->ipv6
;
457 return (CMD_WARNING
);
460 af_conf
->flags
&= ~F_LDPD_AF_ENABLED
;
461 ldp_config_apply(vty
, vty_conf
);
462 return (CMD_SUCCESS
);
467 vty
->node
= LDP_IPV4_NODE
;
470 vty
->node
= LDP_IPV6_NODE
;
473 fatalx("ldp_vty_address_family: unknown af");
475 af_conf
->flags
|= F_LDPD_AF_ENABLED
;
477 ldp_config_apply(vty
, vty_conf
);
479 return (CMD_SUCCESS
);
483 ldp_vty_disc_holdtime(struct vty
*vty
, struct vty_arg
*args
[])
485 struct ldpd_af_conf
*af_conf
;
491 enum hello_type hello_type
;
492 const char *seconds_str
;
493 const char *hello_type_str
;
496 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
497 seconds_str
= vty_get_arg_value(args
, "seconds");
498 hello_type_str
= vty_get_arg_value(args
, "hello_type");
500 secs
= strtol(seconds_str
, &ep
, 10);
501 if (*ep
!= '\0' || secs
< MIN_HOLDTIME
|| secs
> MAX_HOLDTIME
) {
502 vty_out(vty
, "%% Invalid holdtime%s", VTY_NEWLINE
);
503 return (CMD_WARNING
);
506 if (hello_type_str
[0] == 'h')
507 hello_type
= HELLO_LINK
;
509 hello_type
= HELLO_TARGETED
;
514 switch (hello_type
) {
516 vty_conf
->lhello_holdtime
= LINK_DFLT_HOLDTIME
;
519 vty_conf
->thello_holdtime
=
520 TARGETED_DFLT_HOLDTIME
;
524 switch (hello_type
) {
526 vty_conf
->lhello_holdtime
= secs
;
529 vty_conf
->thello_holdtime
= secs
;
533 ldp_config_apply(vty
, vty_conf
);
537 af
= ldp_vty_get_af(vty
);
538 af_conf
= ldp_af_conf_get(vty_conf
, af
);
541 switch (hello_type
) {
543 af_conf
->lhello_holdtime
= 0;
546 af_conf
->thello_holdtime
= 0;
550 switch (hello_type
) {
552 af_conf
->lhello_holdtime
= secs
;
555 af_conf
->thello_holdtime
= secs
;
559 ldp_config_apply(vty
, vty_conf
);
561 case LDP_IPV4_IFACE_NODE
:
562 case LDP_IPV6_IFACE_NODE
:
563 af
= ldp_vty_get_af(vty
);
564 iface
= VTY_GET_CONTEXT(iface
);
565 VTY_CHECK_CONTEXT(iface
);
567 ia
= iface_af_get(iface
, af
);
569 ia
->hello_holdtime
= 0;
571 ia
->hello_holdtime
= secs
;
573 ldp_config_apply(vty
, vty_conf
);
576 fatalx("ldp_vty_disc_holdtime: unexpected node");
579 return (CMD_SUCCESS
);
583 ldp_vty_disc_interval(struct vty
*vty
, struct vty_arg
*args
[])
585 struct ldpd_af_conf
*af_conf
;
591 enum hello_type hello_type
;
592 const char *seconds_str
;
593 const char *hello_type_str
;
596 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
597 seconds_str
= vty_get_arg_value(args
, "seconds");
598 hello_type_str
= vty_get_arg_value(args
, "hello_type");
600 secs
= strtol(seconds_str
, &ep
, 10);
601 if (*ep
!= '\0' || secs
< MIN_HELLO_INTERVAL
||
602 secs
> MAX_HELLO_INTERVAL
) {
603 vty_out(vty
, "%% Invalid interval%s", VTY_NEWLINE
);
604 return (CMD_WARNING
);
607 if (hello_type_str
[0] == 'h')
608 hello_type
= HELLO_LINK
;
610 hello_type
= HELLO_TARGETED
;
615 switch (hello_type
) {
617 vty_conf
->lhello_interval
= LINK_DFLT_HOLDTIME
;
620 vty_conf
->thello_interval
=
621 TARGETED_DFLT_HOLDTIME
;
625 switch (hello_type
) {
627 vty_conf
->lhello_interval
= secs
;
630 vty_conf
->thello_interval
= secs
;
634 ldp_config_apply(vty
, vty_conf
);
638 af
= ldp_vty_get_af(vty
);
639 af_conf
= ldp_af_conf_get(vty_conf
, af
);
642 switch (hello_type
) {
644 af_conf
->lhello_interval
= 0;
647 af_conf
->thello_interval
= 0;
651 switch (hello_type
) {
653 af_conf
->lhello_interval
= secs
;
656 af_conf
->thello_interval
= secs
;
660 ldp_config_apply(vty
, vty_conf
);
662 case LDP_IPV4_IFACE_NODE
:
663 case LDP_IPV6_IFACE_NODE
:
664 af
= ldp_vty_get_af(vty
);
665 iface
= VTY_GET_CONTEXT(iface
);
666 VTY_CHECK_CONTEXT(iface
);
668 ia
= iface_af_get(iface
, af
);
670 ia
->hello_interval
= 0;
672 ia
->hello_interval
= secs
;
674 ldp_config_apply(vty
, vty_conf
);
677 fatalx("ldp_vty_disc_interval: unexpected node");
680 return (CMD_SUCCESS
);
684 ldp_vty_targeted_hello_accept(struct vty
*vty
, struct vty_arg
*args
[])
686 struct ldpd_af_conf
*af_conf
;
688 const char *acl_from_str
;
691 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
692 acl_from_str
= vty_get_arg_value(args
, "from_acl");
694 af
= ldp_vty_get_af(vty
);
695 af_conf
= ldp_af_conf_get(vty_conf
, af
);
698 af_conf
->flags
&= ~F_LDPD_AF_THELLO_ACCEPT
;
699 af_conf
->acl_thello_accept_from
[0] = '\0';
701 af_conf
->flags
|= F_LDPD_AF_THELLO_ACCEPT
;
703 strlcpy(af_conf
->acl_thello_accept_from
, acl_from_str
,
704 sizeof(af_conf
->acl_thello_accept_from
));
706 af_conf
->acl_thello_accept_from
[0] = '\0';
709 ldp_config_apply(vty
, vty_conf
);
711 return (CMD_SUCCESS
);
715 ldp_vty_nbr_session_holdtime(struct vty
*vty
, struct vty_arg
*args
[])
719 struct in_addr lsr_id
;
720 struct nbr_params
*nbrp
;
721 const char *seconds_str
;
722 const char *lsr_id_str
;
725 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
726 seconds_str
= vty_get_arg_value(args
, "seconds");
727 lsr_id_str
= vty_get_arg_value(args
, "lsr_id");
729 if (inet_pton(AF_INET
, lsr_id_str
, &lsr_id
) != 1 ||
730 bad_addr_v4(lsr_id
)) {
731 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
732 return (CMD_WARNING
);
735 secs
= strtol(seconds_str
, &ep
, 10);
736 if (*ep
!= '\0' || secs
< MIN_KEEPALIVE
|| secs
> MAX_KEEPALIVE
) {
737 vty_out(vty
, "%% Invalid holdtime%s", VTY_NEWLINE
);
738 return (CMD_SUCCESS
);
741 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
745 return (CMD_SUCCESS
);
748 nbrp
->flags
&= ~F_NBRP_KEEPALIVE
;
751 nbrp
= nbr_params_new(lsr_id
);
752 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
753 QOBJ_REG(nbrp
, nbr_params
);
754 } else if (nbrp
->keepalive
== secs
)
755 return (CMD_SUCCESS
);
757 nbrp
->keepalive
= secs
;
758 nbrp
->flags
|= F_NBRP_KEEPALIVE
;
761 ldp_config_apply(vty
, vty_conf
);
763 return (CMD_SUCCESS
);
767 ldp_vty_af_session_holdtime(struct vty
*vty
, struct vty_arg
*args
[])
769 struct ldpd_af_conf
*af_conf
;
773 const char *seconds_str
;
776 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
777 seconds_str
= vty_get_arg_value(args
, "seconds");
779 secs
= strtol(seconds_str
, &ep
, 10);
780 if (*ep
!= '\0' || secs
< MIN_KEEPALIVE
|| secs
> MAX_KEEPALIVE
) {
781 vty_out(vty
, "%% Invalid holdtime%s", VTY_NEWLINE
);
782 return (CMD_SUCCESS
);
785 af
= ldp_vty_get_af(vty
);
786 af_conf
= ldp_af_conf_get(vty_conf
, af
);
789 af_conf
->keepalive
= DEFAULT_KEEPALIVE
;
791 af_conf
->keepalive
= secs
;
793 ldp_config_apply(vty
, vty_conf
);
795 return (CMD_SUCCESS
);
799 ldp_vty_session_holdtime(struct vty
*vty
, struct vty_arg
*args
[])
803 return (ldp_vty_nbr_session_holdtime(vty
, args
));
806 return (ldp_vty_af_session_holdtime(vty
, args
));
808 fatalx("ldp_vty_session_holdtime: unexpected node");
813 ldp_vty_interface(struct vty
*vty
, struct vty_arg
*args
[])
821 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
822 ifname
= vty_get_arg_value(args
, "ifname");
824 af
= ldp_vty_get_af(vty
);
825 iface
= if_lookup_name(vty_conf
, ifname
);
829 return (CMD_SUCCESS
);
831 ia
= iface_af_get(iface
, af
);
832 if (ia
->enabled
== 0)
833 return (CMD_SUCCESS
);
836 ia
->hello_holdtime
= 0;
837 ia
->hello_interval
= 0;
839 ldp_config_apply(vty
, vty_conf
);
841 return (CMD_SUCCESS
);
845 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
846 vty_out(vty
, "%% Interface is already in use%s",
848 return (CMD_SUCCESS
);
851 iface
= if_new(ifname
);
852 ia
= iface_af_get(iface
, af
);
854 RB_INSERT(iface_head
, &vty_conf
->iface_tree
, iface
);
855 QOBJ_REG(iface
, iface
);
857 ldp_config_apply(vty
, vty_conf
);
859 ia
= iface_af_get(iface
, af
);
862 ldp_config_apply(vty
, vty_conf
);
868 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE
, iface
);
871 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE
, iface
);
877 return (CMD_SUCCESS
);
881 ldp_vty_trans_addr(struct vty
*vty
, struct vty_arg
*args
[])
883 struct ldpd_af_conf
*af_conf
;
885 const char *addr_str
;
888 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
889 addr_str
= vty_get_arg_value(args
, "addr");
891 af
= ldp_vty_get_af(vty
);
892 af_conf
= ldp_af_conf_get(vty_conf
, af
);
895 memset(&af_conf
->trans_addr
, 0, sizeof(af_conf
->trans_addr
));
897 if (inet_pton(af
, addr_str
, &af_conf
->trans_addr
) != 1 ||
898 bad_addr(af
, &af_conf
->trans_addr
)) {
899 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
900 return (CMD_SUCCESS
);
904 ldp_config_apply(vty
, vty_conf
);
906 return (CMD_SUCCESS
);
910 ldp_vty_neighbor_targeted(struct vty
*vty
, struct vty_arg
*args
[])
913 union ldpd_addr addr
;
915 const char *addr_str
;
918 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
919 addr_str
= vty_get_arg_value(args
, "addr");
921 af
= ldp_vty_get_af(vty
);
923 if (inet_pton(af
, addr_str
, &addr
) != 1 ||
924 bad_addr(af
, &addr
)) {
925 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
926 return (CMD_WARNING
);
928 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
.v6
)) {
929 vty_out(vty
, "%% Address can not be link-local%s", VTY_NEWLINE
);
930 return (CMD_WARNING
);
933 tnbr
= tnbr_find(vty_conf
, af
, &addr
);
937 return (CMD_SUCCESS
);
940 RB_REMOVE(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
943 ldp_config_apply(vty
, vty_conf
);
945 return (CMD_SUCCESS
);
949 return (CMD_SUCCESS
);
951 tnbr
= tnbr_new(af
, &addr
);
952 tnbr
->flags
|= F_TNBR_CONFIGURED
;
953 RB_INSERT(tnbr_head
, &vty_conf
->tnbr_tree
, tnbr
);
954 QOBJ_REG(tnbr
, tnbr
);
956 ldp_config_apply(vty
, vty_conf
);
958 return (CMD_SUCCESS
);
962 ldp_vty_label_advertise(struct vty
*vty
, struct vty_arg
*args
[])
964 struct ldpd_af_conf
*af_conf
;
966 const char *acl_to_str
;
967 const char *acl_for_str
;
970 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
971 acl_to_str
= vty_get_arg_value(args
, "to_acl");
972 acl_for_str
= vty_get_arg_value(args
, "for_acl");
974 af
= ldp_vty_get_af(vty
);
975 af_conf
= ldp_af_conf_get(vty_conf
, af
);
978 af_conf
->acl_label_advertise_to
[0] = '\0';
979 af_conf
->acl_label_advertise_for
[0] = '\0';
982 strlcpy(af_conf
->acl_label_advertise_to
, acl_to_str
,
983 sizeof(af_conf
->acl_label_advertise_to
));
985 af_conf
->acl_label_advertise_to
[0] = '\0';
987 strlcpy(af_conf
->acl_label_advertise_for
, acl_for_str
,
988 sizeof(af_conf
->acl_label_advertise_for
));
990 af_conf
->acl_label_advertise_for
[0] = '\0';
993 ldp_config_apply(vty
, vty_conf
);
995 return (CMD_SUCCESS
);
999 ldp_vty_label_allocate(struct vty
*vty
, struct vty_arg
*args
[])
1001 struct ldpd_af_conf
*af_conf
;
1003 const char *acl_for_str
;
1004 const char *host_routes_str
;
1007 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1008 acl_for_str
= vty_get_arg_value(args
, "for_acl");
1009 host_routes_str
= vty_get_arg_value(args
, "host-routes");
1011 af
= ldp_vty_get_af(vty
);
1012 af_conf
= ldp_af_conf_get(vty_conf
, af
);
1014 af_conf
->flags
&= ~F_LDPD_AF_ALLOCHOSTONLY
;
1015 af_conf
->acl_label_allocate_for
[0] = '\0';
1017 if (host_routes_str
)
1018 af_conf
->flags
|= F_LDPD_AF_ALLOCHOSTONLY
;
1020 strlcpy(af_conf
->acl_label_allocate_for
, acl_for_str
,
1021 sizeof(af_conf
->acl_label_allocate_for
));
1024 ldp_config_apply(vty
, vty_conf
);
1026 return (CMD_SUCCESS
);
1030 ldp_vty_label_expnull(struct vty
*vty
, struct vty_arg
*args
[])
1032 struct ldpd_af_conf
*af_conf
;
1034 const char *acl_for_str
;
1037 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1038 acl_for_str
= vty_get_arg_value(args
, "for_acl");
1040 af
= ldp_vty_get_af(vty
);
1041 af_conf
= ldp_af_conf_get(vty_conf
, af
);
1044 af_conf
->flags
&= ~F_LDPD_AF_EXPNULL
;
1045 af_conf
->acl_label_expnull_for
[0] = '\0';
1047 af_conf
->flags
|= F_LDPD_AF_EXPNULL
;
1049 strlcpy(af_conf
->acl_label_expnull_for
, acl_for_str
,
1050 sizeof(af_conf
->acl_label_expnull_for
));
1052 af_conf
->acl_label_expnull_for
[0] = '\0';
1055 ldp_config_apply(vty
, vty_conf
);
1057 return (CMD_SUCCESS
);
1061 ldp_vty_label_accept(struct vty
*vty
, struct vty_arg
*args
[])
1063 struct ldpd_af_conf
*af_conf
;
1065 const char *acl_from_str
;
1066 const char *acl_for_str
;
1069 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1070 acl_from_str
= vty_get_arg_value(args
, "from_acl");
1071 acl_for_str
= vty_get_arg_value(args
, "for_acl");
1073 af
= ldp_vty_get_af(vty
);
1074 af_conf
= ldp_af_conf_get(vty_conf
, af
);
1077 af_conf
->acl_label_accept_from
[0] = '\0';
1078 af_conf
->acl_label_accept_for
[0] = '\0';
1081 strlcpy(af_conf
->acl_label_accept_from
, acl_from_str
,
1082 sizeof(af_conf
->acl_label_accept_from
));
1084 af_conf
->acl_label_accept_from
[0] = '\0';
1086 strlcpy(af_conf
->acl_label_accept_for
, acl_for_str
,
1087 sizeof(af_conf
->acl_label_accept_for
));
1089 af_conf
->acl_label_accept_for
[0] = '\0';
1092 ldp_config_apply(vty
, vty_conf
);
1094 return (CMD_SUCCESS
);
1098 ldp_vty_ttl_security(struct vty
*vty
, struct vty_arg
*args
[])
1100 struct ldpd_af_conf
*af_conf
;
1104 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1106 af
= ldp_vty_get_af(vty
);
1107 af_conf
= ldp_af_conf_get(vty_conf
, af
);
1110 af_conf
->flags
&= ~F_LDPD_AF_NO_GTSM
;
1112 af_conf
->flags
|= F_LDPD_AF_NO_GTSM
;
1114 ldp_config_apply(vty
, vty_conf
);
1116 return (CMD_SUCCESS
);
1120 ldp_vty_router_id(struct vty
*vty
, struct vty_arg
*args
[])
1122 const char *addr_str
;
1125 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1126 addr_str
= vty_get_arg_value(args
, "addr");
1129 vty_conf
->rtr_id
.s_addr
= INADDR_ANY
;
1131 if (inet_pton(AF_INET
, addr_str
, &vty_conf
->rtr_id
) != 1 ||
1132 bad_addr_v4(vty_conf
->rtr_id
)) {
1133 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
1134 return (CMD_SUCCESS
);
1138 ldp_config_apply(vty
, vty_conf
);
1140 return (CMD_SUCCESS
);
1144 ldp_vty_ds_cisco_interop(struct vty
*vty
, struct vty_arg
*args
[])
1148 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1151 vty_conf
->flags
&= ~F_LDPD_DS_CISCO_INTEROP
;
1153 vty_conf
->flags
|= F_LDPD_DS_CISCO_INTEROP
;
1155 ldp_config_apply(vty
, vty_conf
);
1157 return (CMD_SUCCESS
);
1161 ldp_vty_trans_pref_ipv4(struct vty
*vty
, struct vty_arg
*args
[])
1165 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1168 vty_conf
->trans_pref
= DUAL_STACK_LDPOV6
;
1170 vty_conf
->trans_pref
= DUAL_STACK_LDPOV4
;
1172 ldp_config_apply(vty
, vty_conf
);
1174 return (CMD_SUCCESS
);
1178 ldp_vty_neighbor_password(struct vty
*vty
, struct vty_arg
*args
[])
1180 struct in_addr lsr_id
;
1181 size_t password_len
;
1182 struct nbr_params
*nbrp
;
1183 const char *lsr_id_str
;
1184 const char *password_str
;
1187 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1188 lsr_id_str
= vty_get_arg_value(args
, "lsr_id");
1189 password_str
= vty_get_arg_value(args
, "password");
1191 if (inet_pton(AF_INET
, lsr_id_str
, &lsr_id
) != 1 ||
1192 bad_addr_v4(lsr_id
)) {
1193 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
1194 return (CMD_WARNING
);
1197 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1201 return (CMD_SUCCESS
);
1203 memset(&nbrp
->auth
, 0, sizeof(nbrp
->auth
));
1204 nbrp
->auth
.method
= AUTH_NONE
;
1207 nbrp
= nbr_params_new(lsr_id
);
1208 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1209 QOBJ_REG(nbrp
, nbr_params
);
1210 } else if (nbrp
->auth
.method
== AUTH_MD5SIG
&&
1211 strcmp(nbrp
->auth
.md5key
, password_str
) == 0)
1212 return (CMD_SUCCESS
);
1214 password_len
= strlcpy(nbrp
->auth
.md5key
, password_str
,
1215 sizeof(nbrp
->auth
.md5key
));
1216 if (password_len
>= sizeof(nbrp
->auth
.md5key
))
1217 vty_out(vty
, "%% password has been truncated to %zu "
1218 "characters.", sizeof(nbrp
->auth
.md5key
) - 1);
1219 nbrp
->auth
.md5key_len
= password_len
;
1220 nbrp
->auth
.method
= AUTH_MD5SIG
;
1223 ldp_config_apply(vty
, vty_conf
);
1225 return (CMD_SUCCESS
);
1229 ldp_vty_neighbor_ttl_security(struct vty
*vty
, struct vty_arg
*args
[])
1231 struct in_addr lsr_id
;
1232 struct nbr_params
*nbrp
;
1235 const char *lsr_id_str
;
1236 const char *hops_str
;
1239 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1240 lsr_id_str
= vty_get_arg_value(args
, "lsr_id");
1241 hops_str
= vty_get_arg_value(args
, "hops");
1243 if (inet_pton(AF_INET
, lsr_id_str
, &lsr_id
) != 1 ||
1244 bad_addr_v4(lsr_id
)) {
1245 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
1246 return (CMD_WARNING
);
1250 hops
= strtol(hops_str
, &ep
, 10);
1251 if (*ep
!= '\0' || hops
< 1 || hops
> 254) {
1252 vty_out(vty
, "%% Invalid hop count%s", VTY_NEWLINE
);
1253 return (CMD_SUCCESS
);
1257 nbrp
= nbr_params_find(vty_conf
, lsr_id
);
1261 return (CMD_SUCCESS
);
1263 nbrp
->flags
&= ~(F_NBRP_GTSM
|F_NBRP_GTSM_HOPS
);
1264 nbrp
->gtsm_enabled
= 0;
1265 nbrp
->gtsm_hops
= 0;
1268 nbrp
= nbr_params_new(lsr_id
);
1269 RB_INSERT(nbrp_head
, &vty_conf
->nbrp_tree
, nbrp
);
1270 QOBJ_REG(nbrp
, nbr_params
);
1273 nbrp
->flags
|= F_NBRP_GTSM
;
1274 nbrp
->flags
&= ~F_NBRP_GTSM_HOPS
;
1276 nbrp
->gtsm_enabled
= 1;
1277 nbrp
->gtsm_hops
= hops
;
1278 nbrp
->flags
|= F_NBRP_GTSM_HOPS
;
1280 nbrp
->gtsm_enabled
= 0;
1283 ldp_config_apply(vty
, vty_conf
);
1285 return (CMD_SUCCESS
);
1289 ldp_vty_l2vpn(struct vty
*vty
, struct vty_arg
*args
[])
1291 struct l2vpn
*l2vpn
;
1292 struct l2vpn_if
*lif
;
1293 struct l2vpn_pw
*pw
;
1294 const char *name_str
;
1297 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1298 name_str
= vty_get_arg_value(args
, "name");
1300 l2vpn
= l2vpn_find(vty_conf
, name_str
);
1304 return (CMD_SUCCESS
);
1306 RB_FOREACH(lif
, l2vpn_if_head
, &l2vpn
->if_tree
)
1308 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_tree
)
1310 RB_FOREACH(pw
, l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
)
1313 RB_REMOVE(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1316 ldp_config_apply(vty
, vty_conf
);
1318 return (CMD_SUCCESS
);
1322 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1323 return (CMD_SUCCESS
);
1326 l2vpn
= l2vpn_new(name_str
);
1327 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1328 RB_INSERT(l2vpn_head
, &vty_conf
->l2vpn_tree
, l2vpn
);
1329 QOBJ_REG(l2vpn
, l2vpn
);
1331 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE
, l2vpn
);
1333 ldp_config_apply(vty
, vty_conf
);
1335 return (CMD_SUCCESS
);
1339 ldp_vty_l2vpn_bridge(struct vty
*vty
, struct vty_arg
*args
[])
1341 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1345 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1346 ifname
= vty_get_arg_value(args
, "ifname");
1349 memset(l2vpn
->br_ifname
, 0, sizeof(l2vpn
->br_ifname
));
1351 strlcpy(l2vpn
->br_ifname
, ifname
, sizeof(l2vpn
->br_ifname
));
1353 ldp_config_apply(vty
, vty_conf
);
1355 return (CMD_SUCCESS
);
1359 ldp_vty_l2vpn_mtu(struct vty
*vty
, struct vty_arg
*args
[])
1361 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1364 const char *mtu_str
;
1367 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1368 mtu_str
= vty_get_arg_value(args
, "mtu");
1370 mtu
= strtol(mtu_str
, &ep
, 10);
1371 if (*ep
!= '\0' || mtu
< MIN_L2VPN_MTU
|| mtu
> MAX_L2VPN_MTU
) {
1372 vty_out(vty
, "%% Invalid MTU%s", VTY_NEWLINE
);
1373 return (CMD_WARNING
);
1377 l2vpn
->mtu
= DEFAULT_L2VPN_MTU
;
1381 ldp_config_apply(vty
, vty_conf
);
1383 return (CMD_SUCCESS
);
1387 ldp_vty_l2vpn_pwtype(struct vty
*vty
, struct vty_arg
*args
[])
1389 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1391 const char *type_str
;
1394 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1395 type_str
= vty_get_arg_value(args
, "type");
1397 if (strcmp(type_str
, "ethernet") == 0)
1398 pw_type
= PW_TYPE_ETHERNET
;
1400 pw_type
= PW_TYPE_ETHERNET_TAGGED
;
1403 l2vpn
->pw_type
= DEFAULT_PW_TYPE
;
1405 l2vpn
->pw_type
= pw_type
;
1407 ldp_config_apply(vty
, vty_conf
);
1409 return (CMD_SUCCESS
);
1413 ldp_vty_l2vpn_interface(struct vty
*vty
, struct vty_arg
*args
[])
1415 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1416 struct l2vpn_if
*lif
;
1420 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1421 ifname
= vty_get_arg_value(args
, "ifname");
1423 lif
= l2vpn_if_find(l2vpn
, ifname
);
1427 return (CMD_SUCCESS
);
1430 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1433 ldp_config_apply(vty
, vty_conf
);
1435 return (CMD_SUCCESS
);
1439 return (CMD_SUCCESS
);
1441 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1442 vty_out(vty
, "%% Interface is already in use%s", VTY_NEWLINE
);
1443 return (CMD_SUCCESS
);
1446 lif
= l2vpn_if_new(l2vpn
, ifname
);
1447 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1448 QOBJ_REG(lif
, l2vpn_if
);
1450 ldp_config_apply(vty
, vty_conf
);
1452 return (CMD_SUCCESS
);
1456 ldp_vty_l2vpn_pseudowire(struct vty
*vty
, struct vty_arg
*args
[])
1458 VTY_DECLVAR_CONTEXT(l2vpn
, l2vpn
);
1459 struct l2vpn_pw
*pw
;
1463 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1464 ifname
= vty_get_arg_value(args
, "ifname");
1466 pw
= l2vpn_pw_find(l2vpn
, ifname
);
1470 return (CMD_SUCCESS
);
1473 if (pw
->lsr_id
.s_addr
== INADDR_ANY
|| pw
->pwid
== 0)
1474 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1476 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1479 ldp_config_apply(vty
, vty_conf
);
1481 return (CMD_SUCCESS
);
1485 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1486 return (CMD_SUCCESS
);
1489 if (ldp_iface_is_configured(vty_conf
, ifname
)) {
1490 vty_out(vty
, "%% Interface is already in use%s", VTY_NEWLINE
);
1491 return (CMD_SUCCESS
);
1494 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1495 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1496 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1497 QOBJ_REG(pw
, l2vpn_pw
);
1499 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE
, pw
);
1501 ldp_config_apply(vty
, vty_conf
);
1503 return (CMD_SUCCESS
);
1507 ldp_vty_l2vpn_pw_cword(struct vty
*vty
, struct vty_arg
*args
[])
1509 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1510 const char *preference_str
;
1513 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1514 preference_str
= vty_get_arg_value(args
, "preference");
1517 pw
->flags
|= F_PW_CWORD_CONF
;
1519 if (preference_str
[0] == 'e')
1520 pw
->flags
&= ~F_PW_CWORD_CONF
;
1522 pw
->flags
|= F_PW_CWORD_CONF
;
1525 ldp_config_apply(vty
, vty_conf
);
1527 return (CMD_SUCCESS
);
1531 ldp_vty_l2vpn_pw_nbr_addr(struct vty
*vty
, struct vty_arg
*args
[])
1533 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1535 union ldpd_addr addr
;
1536 const char *addr_str
;
1539 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1540 addr_str
= vty_get_arg_value(args
, "addr");
1542 if (ldp_get_address(addr_str
, &af
, &addr
) == -1 ||
1543 bad_addr(af
, &addr
)) {
1544 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
1545 return (CMD_WARNING
);
1550 memset(&pw
->addr
, 0, sizeof(pw
->addr
));
1551 pw
->flags
&= ~F_PW_STATIC_NBR_ADDR
;
1555 pw
->flags
|= F_PW_STATIC_NBR_ADDR
;
1558 ldp_config_apply(vty
, vty_conf
);
1560 return (CMD_SUCCESS
);
1564 ldp_vty_l2vpn_pw_nbr_id(struct vty
*vty
, struct vty_arg
*args
[])
1566 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1567 struct in_addr lsr_id
;
1568 const char *lsr_id_str
;
1571 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1572 lsr_id_str
= vty_get_arg_value(args
, "lsr-id");
1574 if (inet_pton(AF_INET
, lsr_id_str
, &lsr_id
) != 1 ||
1575 bad_addr_v4(lsr_id
)) {
1576 vty_out(vty
, "%% Malformed address%s", VTY_NEWLINE
);
1577 return (CMD_WARNING
);
1581 pw
->lsr_id
.s_addr
= INADDR_ANY
;
1583 pw
->lsr_id
= lsr_id
;
1585 ldp_config_apply(vty
, vty_conf
);
1587 return (CMD_SUCCESS
);
1591 ldp_vty_l2vpn_pw_pwid(struct vty
*vty
, struct vty_arg
*args
[])
1593 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1596 const char *pwid_str
;
1599 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1600 pwid_str
= vty_get_arg_value(args
, "pwid");
1602 pwid
= strtol(pwid_str
, &ep
, 10);
1603 if (*ep
!= '\0' || pwid
< MIN_PWID_ID
|| pwid
> MAX_PWID_ID
) {
1604 vty_out(vty
, "%% Invalid pw-id%s", VTY_NEWLINE
);
1605 return (CMD_WARNING
);
1613 ldp_config_apply(vty
, vty_conf
);
1615 return (CMD_SUCCESS
);
1619 ldp_vty_l2vpn_pw_pwstatus(struct vty
*vty
, struct vty_arg
*args
[])
1621 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw
, pw
);
1624 disable
= (vty_get_arg_value(args
, "no")) ? 1 : 0;
1627 pw
->flags
|= F_PW_STATUSTLV_CONF
;
1629 pw
->flags
&= ~F_PW_STATUSTLV_CONF
;
1631 ldp_config_apply(vty
, vty_conf
);
1633 return (CMD_SUCCESS
);
1637 iface_new_api(struct ldpd_conf
*conf
, const char *name
)
1639 const char *ifname
= name
;
1640 struct iface
*iface
;
1642 if (ldp_iface_is_configured(conf
, ifname
))
1645 iface
= if_new(name
);
1646 RB_INSERT(iface_head
, &conf
->iface_tree
, iface
);
1647 QOBJ_REG(iface
, iface
);
1652 iface_del_api(struct ldpd_conf
*conf
, struct iface
*iface
)
1655 RB_REMOVE(iface_head
, &conf
->iface_tree
, iface
);
1660 tnbr_new_api(struct ldpd_conf
*conf
, int af
, union ldpd_addr
*addr
)
1664 if (af
== AF_INET6
&& IN6_IS_SCOPE_EMBED(&addr
->v6
))
1667 if (tnbr_find(conf
, af
, addr
))
1670 tnbr
= tnbr_new(af
, addr
);
1671 tnbr
->flags
|= F_TNBR_CONFIGURED
;
1672 RB_INSERT(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1673 QOBJ_REG(tnbr
, tnbr
);
1678 tnbr_del_api(struct ldpd_conf
*conf
, struct tnbr
*tnbr
)
1681 RB_REMOVE(tnbr_head
, &conf
->tnbr_tree
, tnbr
);
1686 nbrp_new_api(struct ldpd_conf
*conf
, struct in_addr lsr_id
)
1688 struct nbr_params
*nbrp
;
1690 if (nbr_params_find(conf
, lsr_id
))
1693 nbrp
= nbr_params_new(lsr_id
);
1694 RB_INSERT(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1695 QOBJ_REG(nbrp
, nbr_params
);
1700 nbrp_del_api(struct ldpd_conf
*conf
, struct nbr_params
*nbrp
)
1703 RB_REMOVE(nbrp_head
, &conf
->nbrp_tree
, nbrp
);
1708 l2vpn_new_api(struct ldpd_conf
*conf
, const char *name
)
1710 struct l2vpn
*l2vpn
;
1712 if (l2vpn_find(conf
, name
))
1715 l2vpn
= l2vpn_new(name
);
1716 l2vpn
->type
= L2VPN_TYPE_VPLS
;
1717 RB_INSERT(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1718 QOBJ_REG(l2vpn
, l2vpn
);
1723 l2vpn_del_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
)
1725 struct l2vpn_if
*lif
;
1726 struct l2vpn_pw
*pw
;
1728 while ((lif
= RB_ROOT(&l2vpn
->if_tree
)) != NULL
) {
1730 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1733 while ((pw
= RB_ROOT(&l2vpn
->pw_tree
)) != NULL
) {
1735 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_tree
, pw
);
1738 while ((pw
= RB_ROOT(&l2vpn
->pw_inactive_tree
)) != NULL
) {
1740 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1744 RB_REMOVE(l2vpn_head
, &conf
->l2vpn_tree
, l2vpn
);
1749 l2vpn_if_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1752 struct l2vpn_if
*lif
;
1754 if (ldp_iface_is_configured(conf
, ifname
))
1757 lif
= l2vpn_if_new(l2vpn
, ifname
);
1758 RB_INSERT(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1759 QOBJ_REG(lif
, l2vpn_if
);
1764 l2vpn_if_del_api(struct l2vpn
*l2vpn
, struct l2vpn_if
*lif
)
1767 RB_REMOVE(l2vpn_if_head
, &l2vpn
->if_tree
, lif
);
1772 l2vpn_pw_new_api(struct ldpd_conf
*conf
, struct l2vpn
*l2vpn
,
1775 struct l2vpn_pw
*pw
;
1777 if (ldp_iface_is_configured(conf
, ifname
))
1780 pw
= l2vpn_pw_new(l2vpn
, ifname
);
1781 pw
->flags
= F_PW_STATUSTLV_CONF
|F_PW_CWORD_CONF
;
1782 RB_INSERT(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);
1783 QOBJ_REG(pw
, l2vpn_pw
);
1788 l2vpn_pw_del_api(struct l2vpn
*l2vpn
, struct l2vpn_pw
*pw
)
1791 RB_REMOVE(l2vpn_pw_head
, &l2vpn
->pw_inactive_tree
, pw
);