]> git.proxmox.com Git - mirror_frr.git/blame - ldpd/ldp_vty_conf.c
Merge pull request #9019 from pjdruddy/ospfv3-early-break-list-walk
[mirror_frr.git] / ldpd / ldp_vty_conf.c
CommitLineData
eac6e3f0
RW
1/*
2 * Copyright (C) 2016 by Open Source Routing.
3 *
180fc2cd
RW
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.
eac6e3f0 8 *
180fc2cd 9 * This program is distributed in the hope that it will be useful, but
eac6e3f0
RW
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.
13 *
180fc2cd
RW
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,
17 * MA 02110-1301 USA
eac6e3f0
RW
18 */
19
20#include <zebra.h>
21
22#include "ldpd.h"
23#include "ldpe.h"
24#include "lde.h"
25#include "log.h"
26
27#include "command.h"
28#include "vrf.h"
29#include "if.h"
30#include "vty.h"
31#include "ldp_vty.h"
32
612c2c15 33static int ldp_config_write(struct vty *);
eac6e3f0
RW
34static void ldp_af_iface_config_write(struct vty *, int);
35static void ldp_af_config_write(struct vty *, int, struct ldpd_conf *,
36 struct ldpd_af_conf *);
612c2c15 37static int ldp_l2vpn_config_write(struct vty *);
eac6e3f0
RW
38static void ldp_l2vpn_pw_config_write(struct vty *, struct l2vpn_pw *);
39static int ldp_vty_get_af(struct vty *);
40static int ldp_iface_is_configured(struct ldpd_conf *, const char *);
eac6e3f0 41
62b346ee 42struct cmd_node ldp_node = {
f4b8291f 43 .name = "ldp",
62b346ee 44 .node = LDP_NODE,
24389580 45 .parent_node = CONFIG_NODE,
62b346ee 46 .prompt = "%s(config-ldp)# ",
612c2c15 47 .config_write = ldp_config_write,
eac6e3f0
RW
48};
49
62b346ee 50struct cmd_node ldp_ipv4_node = {
f4b8291f 51 .name = "ldp ipv4",
62b346ee 52 .node = LDP_IPV4_NODE,
24389580 53 .parent_node = LDP_NODE,
62b346ee 54 .prompt = "%s(config-ldp-af)# ",
eac6e3f0
RW
55};
56
62b346ee 57struct cmd_node ldp_ipv6_node = {
f4b8291f 58 .name = "ldp ipv6",
62b346ee 59 .node = LDP_IPV6_NODE,
24389580 60 .parent_node = LDP_NODE,
62b346ee 61 .prompt = "%s(config-ldp-af)# ",
eac6e3f0
RW
62};
63
62b346ee 64struct cmd_node ldp_ipv4_iface_node = {
f4b8291f 65 .name = "ldp ipv4 interface",
62b346ee 66 .node = LDP_IPV4_IFACE_NODE,
24389580 67 .parent_node = LDP_IPV4_NODE,
62b346ee 68 .prompt = "%s(config-ldp-af-if)# ",
eac6e3f0
RW
69};
70
62b346ee 71struct cmd_node ldp_ipv6_iface_node = {
f4b8291f 72 .name = "ldp ipv6 interface",
62b346ee 73 .node = LDP_IPV6_IFACE_NODE,
24389580 74 .parent_node = LDP_IPV6_NODE,
62b346ee 75 .prompt = "%s(config-ldp-af-if)# ",
eac6e3f0
RW
76};
77
62b346ee 78struct cmd_node ldp_l2vpn_node = {
f4b8291f 79 .name = "ldp l2vpn",
62b346ee 80 .node = LDP_L2VPN_NODE,
24389580 81 .parent_node = CONFIG_NODE,
62b346ee 82 .prompt = "%s(config-l2vpn)# ",
612c2c15 83 .config_write = ldp_l2vpn_config_write,
eac6e3f0
RW
84};
85
62b346ee 86struct cmd_node ldp_pseudowire_node = {
f4b8291f 87 .name = "ldp",
62b346ee 88 .node = LDP_PSEUDOWIRE_NODE,
24389580 89 .parent_node = LDP_L2VPN_NODE,
62b346ee 90 .prompt = "%s(config-l2vpn-pw)# ",
eac6e3f0
RW
91};
92
93int
94ldp_get_address(const char *str, int *af, union ldpd_addr *addr)
95{
0ef34ac5 96 if (!str || !af || !addr)
97 return (-1);
98
eac6e3f0
RW
99 memset(addr, 0, sizeof(*addr));
100
101 if (inet_pton(AF_INET, str, &addr->v4) == 1) {
102 *af = AF_INET;
103 return (0);
104 }
105
106 if (inet_pton(AF_INET6, str, &addr->v6) == 1) {
107 *af = AF_INET6;
108 return (0);
109 }
110
111 return (-1);
112}
113
eac6e3f0
RW
114static void
115ldp_af_iface_config_write(struct vty *vty, int af)
116{
117 struct iface *iface;
118 struct iface_af *ia;
119
7d3d7491 120 RB_FOREACH(iface, iface_head, &ldpd_conf->iface_tree) {
eac6e3f0
RW
121 ia = iface_af_get(iface, af);
122 if (!ia->enabled)
123 continue;
124
5c7571d4
DL
125 vty_out (vty, " !\n");
126 vty_out (vty, " interface %s\n", iface->name);
eac6e3f0
RW
127
128 if (ia->hello_holdtime != LINK_DFLT_HOLDTIME &&
129 ia->hello_holdtime != 0)
5c7571d4 130 vty_out (vty, " discovery hello holdtime %u\n",
96ade3ed 131 ia->hello_holdtime);
eac6e3f0
RW
132 if (ia->hello_interval != DEFAULT_HELLO_INTERVAL &&
133 ia->hello_interval != 0)
5c7571d4 134 vty_out (vty, " discovery hello interval %u\n",
96ade3ed 135 ia->hello_interval);
07679ad9
IR
136
137 vty_out (vty, " exit\n");
eac6e3f0
RW
138 }
139}
140
141static void
142ldp_af_config_write(struct vty *vty, int af, struct ldpd_conf *conf,
143 struct ldpd_af_conf *af_conf)
144{
145 struct tnbr *tnbr;
146
147 if (!(af_conf->flags & F_LDPD_AF_ENABLED))
148 return;
149
5c7571d4
DL
150 vty_out (vty, " !\n");
151 vty_out (vty, " address-family %s\n", af_name(af));
eac6e3f0
RW
152
153 if (af_conf->lhello_holdtime != LINK_DFLT_HOLDTIME &&
154 af_conf->lhello_holdtime != 0 )
5c7571d4 155 vty_out (vty, " discovery hello holdtime %u\n",
96ade3ed 156 af_conf->lhello_holdtime);
eac6e3f0
RW
157 if (af_conf->lhello_interval != DEFAULT_HELLO_INTERVAL &&
158 af_conf->lhello_interval != 0)
5c7571d4 159 vty_out (vty, " discovery hello interval %u\n",
96ade3ed 160 af_conf->lhello_interval);
eac6e3f0 161
45a8eba9
RW
162 if (af_conf->flags & F_LDPD_AF_THELLO_ACCEPT) {
163 vty_out(vty, " discovery targeted-hello accept");
164 if (af_conf->acl_thello_accept_from[0] != '\0')
165 vty_out(vty, " from %s",
166 af_conf->acl_thello_accept_from);
6d3c2ed4 167 vty_out (vty, "\n");
45a8eba9 168 }
eac6e3f0
RW
169
170 if (af_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
171 af_conf->thello_holdtime != 0)
5c7571d4 172 vty_out (vty, " discovery targeted-hello holdtime %u\n",
96ade3ed 173 af_conf->thello_holdtime);
eac6e3f0
RW
174 if (af_conf->thello_interval != DEFAULT_HELLO_INTERVAL &&
175 af_conf->thello_interval != 0)
5c7571d4 176 vty_out (vty, " discovery targeted-hello interval %u\n",
96ade3ed 177 af_conf->thello_interval);
eac6e3f0
RW
178
179 if (ldp_addrisset(af, &af_conf->trans_addr))
5c7571d4 180 vty_out (vty, " discovery transport-address %s\n",
96ade3ed
QY
181 log_addr(af, &af_conf->trans_addr));
182 else
181039f3
DL
183 vty_out (vty,
184 " ! Incomplete config, specify a discovery transport-address\n");
eac6e3f0 185
45a8eba9
RW
186 if ((af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY) ||
187 af_conf->acl_label_allocate_for[0] != '\0') {
188 vty_out(vty, " label local allocate");
189 if (af_conf->flags & F_LDPD_AF_ALLOCHOSTONLY)
190 vty_out(vty, " host-routes");
191 else
192 vty_out(vty, " for %s",
193 af_conf->acl_label_allocate_for);
6d3c2ed4 194 vty_out (vty, "\n");
45a8eba9
RW
195 }
196
197 if (af_conf->acl_label_advertise_for[0] != '\0' ||
198 af_conf->acl_label_advertise_to[0] != '\0') {
199 vty_out(vty, " label local advertise");
200 if (af_conf->acl_label_advertise_to[0] != '\0')
201 vty_out(vty, " to %s",
202 af_conf->acl_label_advertise_to);
203 if (af_conf->acl_label_advertise_for[0] != '\0')
204 vty_out(vty, " for %s",
205 af_conf->acl_label_advertise_for);
6d3c2ed4 206 vty_out (vty, "\n");
45a8eba9
RW
207 }
208
209 if (af_conf->flags & F_LDPD_AF_EXPNULL) {
210 vty_out(vty, " label local advertise explicit-null");
211 if (af_conf->acl_label_expnull_for[0] != '\0')
212 vty_out(vty, " for %s",
213 af_conf->acl_label_expnull_for);
6d3c2ed4 214 vty_out (vty, "\n");
45a8eba9
RW
215 }
216
217 if (af_conf->acl_label_accept_for[0] != '\0' ||
218 af_conf->acl_label_accept_from[0] != '\0') {
219 vty_out(vty, " label remote accept");
220 if (af_conf->acl_label_accept_from[0] != '\0')
221 vty_out(vty, " from %s",
222 af_conf->acl_label_accept_from);
223 if (af_conf->acl_label_accept_for[0] != '\0')
224 vty_out(vty, " for %s",
225 af_conf->acl_label_accept_for);
6d3c2ed4 226 vty_out (vty, "\n");
45a8eba9 227 }
eac6e3f0
RW
228
229 if (af_conf->flags & F_LDPD_AF_NO_GTSM)
5c7571d4 230 vty_out (vty, " ttl-security disable\n");
eac6e3f0
RW
231
232 if (af_conf->keepalive != DEFAULT_KEEPALIVE)
5c7571d4 233 vty_out (vty, " session holdtime %u\n",af_conf->keepalive);
eac6e3f0 234
7989cdba 235 RB_FOREACH(tnbr, tnbr_head, &ldpd_conf->tnbr_tree) {
eac6e3f0 236 if (tnbr->af == af) {
5c7571d4
DL
237 vty_out (vty, " !\n");
238 vty_out (vty, " neighbor %s targeted\n",
96ade3ed 239 log_addr(tnbr->af, &tnbr->addr));
eac6e3f0
RW
240 }
241 }
242
243 ldp_af_iface_config_write(vty, af);
244
3b2d98c5 245 vty_out(vty, " !\n");
983bd6f7 246 vty_out(vty, " exit-address-family\n");
eac6e3f0
RW
247}
248
612c2c15 249static int
eac6e3f0
RW
250ldp_config_write(struct vty *vty)
251{
252 struct nbr_params *nbrp;
253
254 if (!(ldpd_conf->flags & F_LDPD_ENABLED))
255 return (0);
256
5c7571d4 257 vty_out (vty, "mpls ldp\n");
eac6e3f0 258
975a328e 259 if (ldpd_conf->rtr_id.s_addr != INADDR_ANY)
903a7226 260 vty_out(vty, " router-id %pI4\n", &ldpd_conf->rtr_id);
eac6e3f0
RW
261
262 if (ldpd_conf->lhello_holdtime != LINK_DFLT_HOLDTIME &&
263 ldpd_conf->lhello_holdtime != 0)
5c7571d4 264 vty_out (vty, " discovery hello holdtime %u\n",
96ade3ed 265 ldpd_conf->lhello_holdtime);
eac6e3f0
RW
266 if (ldpd_conf->lhello_interval != DEFAULT_HELLO_INTERVAL &&
267 ldpd_conf->lhello_interval != 0)
5c7571d4 268 vty_out (vty, " discovery hello interval %u\n",
96ade3ed 269 ldpd_conf->lhello_interval);
eac6e3f0
RW
270
271 if (ldpd_conf->thello_holdtime != TARGETED_DFLT_HOLDTIME &&
272 ldpd_conf->thello_holdtime != 0)
5c7571d4 273 vty_out (vty, " discovery targeted-hello holdtime %u\n",
96ade3ed 274 ldpd_conf->thello_holdtime);
eac6e3f0
RW
275 if (ldpd_conf->thello_interval != DEFAULT_HELLO_INTERVAL &&
276 ldpd_conf->thello_interval != 0)
5c7571d4 277 vty_out (vty, " discovery targeted-hello interval %u\n",
96ade3ed 278 ldpd_conf->thello_interval);
eac6e3f0
RW
279
280 if (ldpd_conf->trans_pref == DUAL_STACK_LDPOV4)
5c7571d4
DL
281 vty_out (vty,
282 " dual-stack transport-connection prefer ipv4\n");
eac6e3f0
RW
283
284 if (ldpd_conf->flags & F_LDPD_DS_CISCO_INTEROP)
5c7571d4 285 vty_out (vty, " dual-stack cisco-interop\n");
eac6e3f0 286
aff1743c
KS
287 if (ldpd_conf->flags & F_LDPD_ORDERED_CONTROL)
288 vty_out (vty, " ordered-control\n");
289
e1894ff7
KS
290 if (ldpd_conf->wait_for_sync_interval != DFLT_WAIT_FOR_SYNC &&
291 ldpd_conf->wait_for_sync_interval != 0)
292 vty_out (vty, " wait-for-sync %u\n",
293 ldpd_conf->wait_for_sync_interval);
294
ff5279ba 295 if (ldpd_conf->flags & F_LDPD_ALLOW_BROKEN_LSP)
296 vty_out(vty, " install allow-broken-lsp\n");
297
76c4abd1 298 RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
eac6e3f0 299 if (nbrp->flags & F_NBRP_KEEPALIVE)
903a7226
MS
300 vty_out (vty, " neighbor %pI4 session holdtime %u\n",
301 &nbrp->lsr_id,nbrp->keepalive);
eac6e3f0
RW
302
303 if (nbrp->flags & F_NBRP_GTSM) {
304 if (nbrp->gtsm_enabled)
903a7226 305 vty_out (vty, " neighbor %pI4 ttl-security hops %u\n", &nbrp->lsr_id,
96ade3ed 306 nbrp->gtsm_hops);
eac6e3f0 307 else
903a7226 308 vty_out (vty, " neighbor %pI4 ttl-security disable\n",&nbrp->lsr_id);
eac6e3f0
RW
309 }
310
311 if (nbrp->auth.method == AUTH_MD5SIG)
903a7226
MS
312 vty_out (vty, " neighbor %pI4 password %s\n",
313 &nbrp->lsr_id,nbrp->auth.md5key);
eac6e3f0
RW
314 }
315
316 ldp_af_config_write(vty, AF_INET, ldpd_conf, &ldpd_conf->ipv4);
317 ldp_af_config_write(vty, AF_INET6, ldpd_conf, &ldpd_conf->ipv6);
5c7571d4 318 vty_out (vty, " !\n");
07679ad9 319 vty_out (vty, "exit\n");
5c7571d4 320 vty_out (vty, "!\n");
eac6e3f0
RW
321
322 return (1);
323}
324
325static void
326ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw)
327{
328 int missing_lsrid = 0;
329 int missing_pwid = 0;
330
5c7571d4
DL
331 vty_out (vty, " !\n");
332 vty_out (vty, " member pseudowire %s\n", pw->ifname);
eac6e3f0
RW
333
334 if (pw->lsr_id.s_addr != INADDR_ANY)
903a7226 335 vty_out (vty, " neighbor lsr-id %pI4\n",&pw->lsr_id);
96ade3ed
QY
336 else
337 missing_lsrid = 1;
eac6e3f0
RW
338
339 if (pw->flags & F_PW_STATIC_NBR_ADDR)
5c7571d4 340 vty_out (vty, " neighbor address %s\n",
96ade3ed 341 log_addr(pw->af, &pw->addr));
eac6e3f0
RW
342
343 if (pw->pwid != 0)
5c7571d4 344 vty_out (vty, " pw-id %u\n", pw->pwid);
eac6e3f0
RW
345 else
346 missing_pwid = 1;
347
348 if (!(pw->flags & F_PW_CWORD_CONF))
5c7571d4 349 vty_out (vty, " control-word exclude\n");
eac6e3f0
RW
350
351 if (!(pw->flags & F_PW_STATUSTLV_CONF))
5c7571d4 352 vty_out (vty, " pw-status disable\n");
eac6e3f0
RW
353
354 if (missing_lsrid)
181039f3
DL
355 vty_out (vty,
356 " ! Incomplete config, specify a neighbor lsr-id\n");
eac6e3f0 357 if (missing_pwid)
5c7571d4 358 vty_out (vty," ! Incomplete config, specify a pw-id\n");
07679ad9
IR
359
360 vty_out (vty, " exit\n");
eac6e3f0
RW
361}
362
612c2c15 363static int
eac6e3f0
RW
364ldp_l2vpn_config_write(struct vty *vty)
365{
366 struct l2vpn *l2vpn;
367 struct l2vpn_if *lif;
368 struct l2vpn_pw *pw;
369
90d7e7bd 370 RB_FOREACH(l2vpn, l2vpn_head, &ldpd_conf->l2vpn_tree) {
5c7571d4 371 vty_out (vty, "l2vpn %s type vpls\n", l2vpn->name);
eac6e3f0
RW
372
373 if (l2vpn->pw_type != DEFAULT_PW_TYPE)
5c7571d4 374 vty_out (vty, " vc type ethernet-tagged\n");
eac6e3f0
RW
375
376 if (l2vpn->mtu != DEFAULT_L2VPN_MTU)
5c7571d4 377 vty_out (vty, " mtu %u\n", l2vpn->mtu);
eac6e3f0
RW
378
379 if (l2vpn->br_ifname[0] != '\0')
5c7571d4 380 vty_out (vty, " bridge %s\n",l2vpn->br_ifname);
eac6e3f0 381
029c1958 382 RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
5c7571d4 383 vty_out (vty, " member interface %s\n",lif->ifname);
eac6e3f0 384
20bacaeb 385 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
eac6e3f0 386 ldp_l2vpn_pw_config_write(vty, pw);
20bacaeb 387 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
eac6e3f0
RW
388 ldp_l2vpn_pw_config_write(vty, pw);
389
5c7571d4 390 vty_out (vty, " !\n");
07679ad9 391 vty_out (vty, "exit\n");
5c7571d4 392 vty_out (vty, "!\n");
eac6e3f0
RW
393 }
394
395 return (0);
396}
397
398static int
399ldp_vty_get_af(struct vty *vty)
400{
401 switch (vty->node) {
402 case LDP_IPV4_NODE:
403 case LDP_IPV4_IFACE_NODE:
404 return (AF_INET);
405 case LDP_IPV6_NODE:
406 case LDP_IPV6_IFACE_NODE:
407 return (AF_INET6);
408 default:
409 fatalx("ldp_vty_get_af: unexpected node");
410 }
411}
412
413static int
414ldp_iface_is_configured(struct ldpd_conf *xconf, const char *ifname)
415{
416 struct l2vpn *l2vpn;
417
418 if (if_lookup_name(xconf, ifname))
419 return (1);
420
90d7e7bd 421 RB_FOREACH(l2vpn, l2vpn_head, &xconf->l2vpn_tree) {
52bd4c23 422 if (l2vpn_if_find(l2vpn, ifname))
eac6e3f0 423 return (1);
52bd4c23 424 if (l2vpn_pw_find(l2vpn, ifname))
eac6e3f0
RW
425 return (1);
426 }
427
428 return (0);
429}
430
431int
1224e5c4 432ldp_vty_mpls_ldp(struct vty *vty, const char *negate)
eac6e3f0 433{
1224e5c4 434 if (negate)
eac6e3f0
RW
435 vty_conf->flags &= ~F_LDPD_ENABLED;
436 else {
437 vty->node = LDP_NODE;
438 vty_conf->flags |= F_LDPD_ENABLED;
439 }
440
ce510d2e
FR
441 /* register / de-register to recv info from zebra */
442 ldp_zebra_regdereg_zebra_info(!negate);
443
e4a82008 444 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
445
446 return (CMD_SUCCESS);
447}
448
449int
1224e5c4 450ldp_vty_address_family(struct vty *vty, const char *negate, const char *af_str)
eac6e3f0 451{
eac6e3f0
RW
452 struct ldpd_af_conf *af_conf;
453 int af;
eac6e3f0 454
e59294e2 455 if (af_str == NULL)
456 return (CMD_WARNING_CONFIG_FAILED);
457
eac6e3f0
RW
458 if (strcmp(af_str, "ipv4") == 0) {
459 af = AF_INET;
460 af_conf = &vty_conf->ipv4;
461 } else if (strcmp(af_str, "ipv6") == 0) {
462 af = AF_INET6;
463 af_conf = &vty_conf->ipv6;
56b8a8d2 464 } else
f1a05de9 465 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0 466
1224e5c4 467 if (negate) {
eac6e3f0 468 af_conf->flags &= ~F_LDPD_AF_ENABLED;
e4a82008 469 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
470 return (CMD_SUCCESS);
471 }
472
473 switch (af) {
474 case AF_INET:
475 vty->node = LDP_IPV4_NODE;
476 break;
477 case AF_INET6:
478 vty->node = LDP_IPV6_NODE;
479 break;
480 default:
481 fatalx("ldp_vty_address_family: unknown af");
482 }
483 af_conf->flags |= F_LDPD_AF_ENABLED;
484
e4a82008 485 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
486
487 return (CMD_SUCCESS);
488}
489
16cd3d9d
RW
490int ldp_vty_disc_holdtime(struct vty *vty, const char *negate,
491 enum hello_type hello_type, long secs)
eac6e3f0 492{
eac6e3f0
RW
493 struct ldpd_af_conf *af_conf;
494 struct iface *iface;
495 struct iface_af *ia;
496 int af;
eac6e3f0
RW
497 switch (vty->node) {
498 case LDP_NODE:
1224e5c4 499 if (negate) {
eac6e3f0
RW
500 switch (hello_type) {
501 case HELLO_LINK:
502 vty_conf->lhello_holdtime = LINK_DFLT_HOLDTIME;
503 break;
504 case HELLO_TARGETED:
505 vty_conf->thello_holdtime =
506 TARGETED_DFLT_HOLDTIME;
507 break;
508 }
509 } else {
510 switch (hello_type) {
511 case HELLO_LINK:
512 vty_conf->lhello_holdtime = secs;
513 break;
514 case HELLO_TARGETED:
515 vty_conf->thello_holdtime = secs;
516 break;
517 }
518 }
e4a82008 519 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
520 break;
521 case LDP_IPV4_NODE:
522 case LDP_IPV6_NODE:
523 af = ldp_vty_get_af(vty);
524 af_conf = ldp_af_conf_get(vty_conf, af);
525
1224e5c4 526 if (negate) {
eac6e3f0
RW
527 switch (hello_type) {
528 case HELLO_LINK:
529 af_conf->lhello_holdtime = 0;
530 break;
531 case HELLO_TARGETED:
532 af_conf->thello_holdtime = 0;
533 break;
534 }
535 } else {
536 switch (hello_type) {
537 case HELLO_LINK:
538 af_conf->lhello_holdtime = secs;
539 break;
540 case HELLO_TARGETED:
541 af_conf->thello_holdtime = secs;
542 break;
543 }
544 }
e4a82008 545 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
546 break;
547 case LDP_IPV4_IFACE_NODE:
548 case LDP_IPV6_IFACE_NODE:
549 af = ldp_vty_get_af(vty);
1d75a89d 550 iface = VTY_GET_CONTEXT(iface);
dbce3582 551 VTY_CHECK_CONTEXT(iface);
eac6e3f0 552
0b47280e 553 ia = iface_af_get(iface, af);
1224e5c4 554 if (negate)
eac6e3f0
RW
555 ia->hello_holdtime = 0;
556 else
557 ia->hello_holdtime = secs;
1d75a89d 558
e4a82008 559 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
560 break;
561 default:
562 fatalx("ldp_vty_disc_holdtime: unexpected node");
563 }
564
eac6e3f0
RW
565 return (CMD_SUCCESS);
566}
567
568int
1224e5c4 569ldp_vty_disc_interval(struct vty *vty, const char *negate,
16cd3d9d 570 enum hello_type hello_type, long secs)
eac6e3f0 571{
eac6e3f0
RW
572 struct ldpd_af_conf *af_conf;
573 struct iface *iface;
574 struct iface_af *ia;
575 int af;
eac6e3f0 576
eac6e3f0
RW
577 switch (vty->node) {
578 case LDP_NODE:
1224e5c4 579 if (negate) {
eac6e3f0
RW
580 switch (hello_type) {
581 case HELLO_LINK:
cd49efda
RW
582 vty_conf->lhello_interval =
583 DEFAULT_HELLO_INTERVAL;
eac6e3f0
RW
584 break;
585 case HELLO_TARGETED:
586 vty_conf->thello_interval =
cd49efda 587 DEFAULT_HELLO_INTERVAL;
eac6e3f0
RW
588 break;
589 }
590 } else {
591 switch (hello_type) {
592 case HELLO_LINK:
593 vty_conf->lhello_interval = secs;
594 break;
595 case HELLO_TARGETED:
596 vty_conf->thello_interval = secs;
597 break;
598 }
599 }
e4a82008 600 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
601 break;
602 case LDP_IPV4_NODE:
603 case LDP_IPV6_NODE:
604 af = ldp_vty_get_af(vty);
605 af_conf = ldp_af_conf_get(vty_conf, af);
606
1224e5c4 607 if (negate) {
eac6e3f0
RW
608 switch (hello_type) {
609 case HELLO_LINK:
610 af_conf->lhello_interval = 0;
611 break;
612 case HELLO_TARGETED:
613 af_conf->thello_interval = 0;
614 break;
615 }
616 } else {
617 switch (hello_type) {
618 case HELLO_LINK:
619 af_conf->lhello_interval = secs;
620 break;
621 case HELLO_TARGETED:
622 af_conf->thello_interval = secs;
623 break;
624 }
625 }
e4a82008 626 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
627 break;
628 case LDP_IPV4_IFACE_NODE:
629 case LDP_IPV6_IFACE_NODE:
630 af = ldp_vty_get_af(vty);
1d75a89d 631 iface = VTY_GET_CONTEXT(iface);
dbce3582 632 VTY_CHECK_CONTEXT(iface);
eac6e3f0 633
0b47280e 634 ia = iface_af_get(iface, af);
1224e5c4 635 if (negate)
eac6e3f0
RW
636 ia->hello_interval = 0;
637 else
638 ia->hello_interval = secs;
1d75a89d 639
e4a82008 640 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
641 break;
642 default:
643 fatalx("ldp_vty_disc_interval: unexpected node");
644 }
645
eac6e3f0
RW
646 return (CMD_SUCCESS);
647}
648
649int
1224e5c4 650ldp_vty_targeted_hello_accept(struct vty *vty, const char *negate,
c740f7d3 651 const char *acl_from_str)
eac6e3f0 652{
eac6e3f0
RW
653 struct ldpd_af_conf *af_conf;
654 int af;
eac6e3f0
RW
655
656 af = ldp_vty_get_af(vty);
657 af_conf = ldp_af_conf_get(vty_conf, af);
658
1224e5c4 659 if (negate) {
eac6e3f0 660 af_conf->flags &= ~F_LDPD_AF_THELLO_ACCEPT;
45a8eba9
RW
661 af_conf->acl_thello_accept_from[0] = '\0';
662 } else {
eac6e3f0 663 af_conf->flags |= F_LDPD_AF_THELLO_ACCEPT;
45a8eba9
RW
664 if (acl_from_str)
665 strlcpy(af_conf->acl_thello_accept_from, acl_from_str,
666 sizeof(af_conf->acl_thello_accept_from));
667 else
668 af_conf->acl_thello_accept_from[0] = '\0';
669 }
eac6e3f0 670
e4a82008 671 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
672
673 return (CMD_SUCCESS);
674}
675
c740f7d3 676int
1224e5c4
RW
677ldp_vty_nbr_session_holdtime(struct vty *vty, const char *negate,
678 struct in_addr lsr_id, long secs)
eac6e3f0 679{
eac6e3f0 680 struct nbr_params *nbrp;
eac6e3f0 681
1224e5c4 682 if (bad_addr_v4(lsr_id)) {
5c7571d4 683 vty_out (vty, "%% Malformed address\n");
f1a05de9 684 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
685 }
686
1d75a89d
RW
687 nbrp = nbr_params_find(vty_conf, lsr_id);
688
1224e5c4 689 if (negate) {
eac6e3f0 690 if (nbrp == NULL)
56b8a8d2 691 return (CMD_SUCCESS);
eac6e3f0
RW
692
693 nbrp->keepalive = 0;
694 nbrp->flags &= ~F_NBRP_KEEPALIVE;
695 } else {
696 if (nbrp == NULL) {
697 nbrp = nbr_params_new(lsr_id);
76c4abd1 698 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 699 QOBJ_REG(nbrp, nbr_params);
eac6e3f0 700 } else if (nbrp->keepalive == secs)
56b8a8d2 701 return (CMD_SUCCESS);
eac6e3f0
RW
702
703 nbrp->keepalive = secs;
704 nbrp->flags |= F_NBRP_KEEPALIVE;
705 }
706
e4a82008 707 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
708
709 return (CMD_SUCCESS);
eac6e3f0
RW
710}
711
c740f7d3 712int
1224e5c4 713ldp_vty_af_session_holdtime(struct vty *vty, const char *negate, long secs)
eac6e3f0 714{
eac6e3f0
RW
715 struct ldpd_af_conf *af_conf;
716 int af;
eac6e3f0 717
eac6e3f0
RW
718 af = ldp_vty_get_af(vty);
719 af_conf = ldp_af_conf_get(vty_conf, af);
720
1224e5c4 721 if (negate)
eac6e3f0
RW
722 af_conf->keepalive = DEFAULT_KEEPALIVE;
723 else
724 af_conf->keepalive = secs;
725
e4a82008 726 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
727
728 return (CMD_SUCCESS);
729}
730
731int
1224e5c4 732ldp_vty_interface(struct vty *vty, const char *negate, const char *ifname)
eac6e3f0 733{
eac6e3f0
RW
734 int af;
735 struct iface *iface;
736 struct iface_af *ia;
eac6e3f0 737
e59294e2 738 if (ifname == NULL) {
739 vty_out (vty, "%% Missing IF name\n");
740 return (CMD_WARNING_CONFIG_FAILED);
741 }
742
eac6e3f0
RW
743 af = ldp_vty_get_af(vty);
744 iface = if_lookup_name(vty_conf, ifname);
745
1224e5c4 746 if (negate) {
eac6e3f0 747 if (iface == NULL)
56b8a8d2 748 return (CMD_SUCCESS);
eac6e3f0
RW
749
750 ia = iface_af_get(iface, af);
751 if (ia->enabled == 0)
56b8a8d2 752 return (CMD_SUCCESS);
eac6e3f0
RW
753
754 ia->enabled = 0;
271327b1
RW
755 ia->hello_holdtime = 0;
756 ia->hello_interval = 0;
1d75a89d 757
e4a82008 758 ldp_config_apply(vty, vty_conf);
1d75a89d 759
eac6e3f0
RW
760 return (CMD_SUCCESS);
761 }
762
eac6e3f0
RW
763 if (iface == NULL) {
764 if (ldp_iface_is_configured(vty_conf, ifname)) {
5c7571d4 765 vty_out (vty,"%% Interface is already in use\n");
56b8a8d2 766 return (CMD_SUCCESS);
eac6e3f0
RW
767 }
768
52b530fc 769 iface = if_new(ifname);
eac6e3f0
RW
770 ia = iface_af_get(iface, af);
771 ia->enabled = 1;
7d3d7491 772 RB_INSERT(iface_head, &vty_conf->iface_tree, iface);
1d75a89d
RW
773 QOBJ_REG(iface, iface);
774
e4a82008 775 ldp_config_apply(vty, vty_conf);
eac6e3f0 776 } else {
eac6e3f0 777 ia = iface_af_get(iface, af);
0b47280e
RW
778 if (!ia->enabled) {
779 ia->enabled = 1;
e4a82008 780 ldp_config_apply(vty, vty_conf);
56b8a8d2 781 }
0b47280e
RW
782 }
783
784 switch (af) {
785 case AF_INET:
1d75a89d 786 VTY_PUSH_CONTEXT(LDP_IPV4_IFACE_NODE, iface);
0b47280e
RW
787 break;
788 case AF_INET6:
1d75a89d 789 VTY_PUSH_CONTEXT(LDP_IPV6_IFACE_NODE, iface);
0b47280e
RW
790 break;
791 default:
792 break;
eac6e3f0
RW
793 }
794
eac6e3f0 795 return (CMD_SUCCESS);
eac6e3f0
RW
796}
797
798int
1224e5c4 799ldp_vty_trans_addr(struct vty *vty, const char *negate, const char *addr_str)
eac6e3f0 800{
eac6e3f0
RW
801 struct ldpd_af_conf *af_conf;
802 int af;
eac6e3f0 803
eac6e3f0
RW
804 af = ldp_vty_get_af(vty);
805 af_conf = ldp_af_conf_get(vty_conf, af);
806
1224e5c4 807 if (negate)
eac6e3f0
RW
808 memset(&af_conf->trans_addr, 0, sizeof(af_conf->trans_addr));
809 else {
e59294e2 810 if (addr_str == NULL
811 || inet_pton(af, addr_str, &af_conf->trans_addr) != 1
812 || bad_addr(af, &af_conf->trans_addr)) {
5c7571d4 813 vty_out (vty, "%% Malformed address\n");
56b8a8d2 814 return (CMD_SUCCESS);
eac6e3f0
RW
815 }
816 }
817
e4a82008 818 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
819
820 return (CMD_SUCCESS);
eac6e3f0
RW
821}
822
823int
1224e5c4 824ldp_vty_neighbor_targeted(struct vty *vty, const char *negate, const char *addr_str)
eac6e3f0 825{
eac6e3f0
RW
826 int af;
827 union ldpd_addr addr;
828 struct tnbr *tnbr;
eac6e3f0
RW
829
830 af = ldp_vty_get_af(vty);
831
e59294e2 832 if (addr_str == NULL || inet_pton(af, addr_str, &addr) != 1 ||
eac6e3f0 833 bad_addr(af, &addr)) {
5c7571d4 834 vty_out (vty, "%% Malformed address\n");
f1a05de9 835 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
836 }
837 if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&addr.v6)) {
5c7571d4 838 vty_out (vty, "%% Address can not be link-local\n");
f1a05de9 839 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
840 }
841
eac6e3f0
RW
842 tnbr = tnbr_find(vty_conf, af, &addr);
843
1224e5c4 844 if (negate) {
eac6e3f0 845 if (tnbr == NULL)
56b8a8d2 846 return (CMD_SUCCESS);
eac6e3f0 847
1d75a89d 848 QOBJ_UNREG(tnbr);
7989cdba 849 RB_REMOVE(tnbr_head, &vty_conf->tnbr_tree, tnbr);
eac6e3f0 850 free(tnbr);
1d75a89d 851
e4a82008 852 ldp_config_apply(vty, vty_conf);
1d75a89d 853
eac6e3f0
RW
854 return (CMD_SUCCESS);
855 }
856
857 if (tnbr)
56b8a8d2 858 return (CMD_SUCCESS);
eac6e3f0
RW
859
860 tnbr = tnbr_new(af, &addr);
861 tnbr->flags |= F_TNBR_CONFIGURED;
7989cdba 862 RB_INSERT(tnbr_head, &vty_conf->tnbr_tree, tnbr);
1d75a89d 863 QOBJ_REG(tnbr, tnbr);
eac6e3f0 864
e4a82008 865 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
866
867 return (CMD_SUCCESS);
eac6e3f0
RW
868}
869
870int
1224e5c4 871ldp_vty_label_advertise(struct vty *vty, const char *negate, const char *acl_to_str,
c740f7d3 872 const char *acl_for_str)
eac6e3f0 873{
eac6e3f0
RW
874 struct ldpd_af_conf *af_conf;
875 int af;
eac6e3f0 876
eac6e3f0
RW
877 af = ldp_vty_get_af(vty);
878 af_conf = ldp_af_conf_get(vty_conf, af);
879
1224e5c4 880 if (negate) {
45a8eba9
RW
881 af_conf->acl_label_advertise_to[0] = '\0';
882 af_conf->acl_label_advertise_for[0] = '\0';
883 } else {
884 if (acl_to_str)
885 strlcpy(af_conf->acl_label_advertise_to, acl_to_str,
886 sizeof(af_conf->acl_label_advertise_to));
887 else
888 af_conf->acl_label_advertise_to[0] = '\0';
889 if (acl_for_str)
890 strlcpy(af_conf->acl_label_advertise_for, acl_for_str,
891 sizeof(af_conf->acl_label_advertise_for));
892 else
893 af_conf->acl_label_advertise_for[0] = '\0';
894 }
895
e4a82008 896 ldp_config_apply(vty, vty_conf);
45a8eba9
RW
897
898 return (CMD_SUCCESS);
899}
900
901int
1224e5c4 902ldp_vty_label_allocate(struct vty *vty, const char *negate, const char *host_routes,
c740f7d3 903 const char *acl_for_str)
45a8eba9 904{
45a8eba9
RW
905 struct ldpd_af_conf *af_conf;
906 int af;
45a8eba9 907
45a8eba9
RW
908 af = ldp_vty_get_af(vty);
909 af_conf = ldp_af_conf_get(vty_conf, af);
910
911 af_conf->flags &= ~F_LDPD_AF_ALLOCHOSTONLY;
912 af_conf->acl_label_allocate_for[0] = '\0';
1224e5c4 913 if (!negate) {
c740f7d3 914 if (host_routes)
45a8eba9
RW
915 af_conf->flags |= F_LDPD_AF_ALLOCHOSTONLY;
916 else
917 strlcpy(af_conf->acl_label_allocate_for, acl_for_str,
918 sizeof(af_conf->acl_label_allocate_for));
919 }
920
e4a82008 921 ldp_config_apply(vty, vty_conf);
45a8eba9
RW
922
923 return (CMD_SUCCESS);
924}
925
926int
1224e5c4 927ldp_vty_label_expnull(struct vty *vty, const char *negate, const char *acl_for_str)
45a8eba9 928{
45a8eba9
RW
929 struct ldpd_af_conf *af_conf;
930 int af;
45a8eba9 931
45a8eba9
RW
932 af = ldp_vty_get_af(vty);
933 af_conf = ldp_af_conf_get(vty_conf, af);
934
1224e5c4 935 if (negate) {
eac6e3f0 936 af_conf->flags &= ~F_LDPD_AF_EXPNULL;
45a8eba9
RW
937 af_conf->acl_label_expnull_for[0] = '\0';
938 } else {
eac6e3f0 939 af_conf->flags |= F_LDPD_AF_EXPNULL;
45a8eba9
RW
940 if (acl_for_str)
941 strlcpy(af_conf->acl_label_expnull_for, acl_for_str,
942 sizeof(af_conf->acl_label_expnull_for));
943 else
944 af_conf->acl_label_expnull_for[0] = '\0';
945 }
946
e4a82008 947 ldp_config_apply(vty, vty_conf);
45a8eba9
RW
948
949 return (CMD_SUCCESS);
950}
951
952int
1224e5c4 953ldp_vty_label_accept(struct vty *vty, const char *negate, const char *acl_from_str,
c740f7d3 954 const char *acl_for_str)
45a8eba9 955{
45a8eba9
RW
956 struct ldpd_af_conf *af_conf;
957 int af;
45a8eba9 958
45a8eba9
RW
959 af = ldp_vty_get_af(vty);
960 af_conf = ldp_af_conf_get(vty_conf, af);
961
1224e5c4 962 if (negate) {
45a8eba9
RW
963 af_conf->acl_label_accept_from[0] = '\0';
964 af_conf->acl_label_accept_for[0] = '\0';
965 } else {
966 if (acl_from_str)
967 strlcpy(af_conf->acl_label_accept_from, acl_from_str,
968 sizeof(af_conf->acl_label_accept_from));
969 else
970 af_conf->acl_label_accept_from[0] = '\0';
971 if (acl_for_str)
972 strlcpy(af_conf->acl_label_accept_for, acl_for_str,
973 sizeof(af_conf->acl_label_accept_for));
974 else
975 af_conf->acl_label_accept_for[0] = '\0';
976 }
eac6e3f0 977
e4a82008 978 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
979
980 return (CMD_SUCCESS);
981}
982
983int
1224e5c4 984ldp_vty_ttl_security(struct vty *vty, const char *negate)
eac6e3f0 985{
eac6e3f0
RW
986 struct ldpd_af_conf *af_conf;
987 int af;
eac6e3f0 988
eac6e3f0
RW
989 af = ldp_vty_get_af(vty);
990 af_conf = ldp_af_conf_get(vty_conf, af);
991
1224e5c4 992 if (negate)
eac6e3f0
RW
993 af_conf->flags &= ~F_LDPD_AF_NO_GTSM;
994 else
995 af_conf->flags |= F_LDPD_AF_NO_GTSM;
996
e4a82008 997 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
998
999 return (CMD_SUCCESS);
1000}
1001
1002int
1224e5c4 1003ldp_vty_router_id(struct vty *vty, const char *negate, struct in_addr address)
eac6e3f0 1004{
1224e5c4 1005 if (negate)
eac6e3f0
RW
1006 vty_conf->rtr_id.s_addr = INADDR_ANY;
1007 else {
1224e5c4 1008 if (bad_addr_v4(address)) {
5c7571d4 1009 vty_out (vty, "%% Malformed address\n");
56b8a8d2 1010 return (CMD_SUCCESS);
eac6e3f0 1011 }
1224e5c4 1012 vty_conf->rtr_id = address;
eac6e3f0
RW
1013 }
1014
e4a82008 1015 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1016
1017 return (CMD_SUCCESS);
eac6e3f0
RW
1018}
1019
aff1743c
KS
1020int
1021ldp_vty_ordered_control(struct vty *vty, const char *negate)
1022{
1023 if (negate)
1024 vty_conf->flags &= ~F_LDPD_ORDERED_CONTROL;
1025 else
1026 vty_conf->flags |= F_LDPD_ORDERED_CONTROL;
1027
1028 ldp_config_apply(vty, vty_conf);
1029
1030 return (CMD_SUCCESS);
1031}
1032
e1894ff7
KS
1033int ldp_vty_wait_for_sync_interval(struct vty *vty, const char *negate,
1034 long secs)
1035{
1036 switch (vty->node) {
1037 case LDP_NODE:
1038 if (negate)
1039 vty_conf->wait_for_sync_interval = DFLT_WAIT_FOR_SYNC;
1040 else
1041 vty_conf->wait_for_sync_interval = secs;
1042
1043 ldp_config_apply(vty, vty_conf);
1044 break;
1045 default:
1046 fatalx("ldp_vty_wait_for_sync_interval: unexpected node");
1047 }
1048 return (CMD_SUCCESS);
1049}
1050
ff5279ba 1051int
1052ldp_vty_allow_broken_lsp(struct vty *vty, const char *negate)
1053{
1054 if (negate)
1055 vty_conf->flags &= ~F_LDPD_ALLOW_BROKEN_LSP;
1056 else
1057 vty_conf->flags |= F_LDPD_ALLOW_BROKEN_LSP;
1058
1059 ldp_config_apply(vty, vty_conf);
1060
1061 return (CMD_SUCCESS);
1062}
1063
eac6e3f0 1064int
1224e5c4 1065ldp_vty_ds_cisco_interop(struct vty *vty, const char * negate)
eac6e3f0 1066{
1224e5c4 1067 if (negate)
eac6e3f0
RW
1068 vty_conf->flags &= ~F_LDPD_DS_CISCO_INTEROP;
1069 else
1070 vty_conf->flags |= F_LDPD_DS_CISCO_INTEROP;
1071
e4a82008 1072 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1073
1074 return (CMD_SUCCESS);
1075}
1076
1077int
1224e5c4 1078ldp_vty_trans_pref_ipv4(struct vty *vty, const char *negate)
eac6e3f0 1079{
1224e5c4 1080 if (negate)
eac6e3f0
RW
1081 vty_conf->trans_pref = DUAL_STACK_LDPOV6;
1082 else
1083 vty_conf->trans_pref = DUAL_STACK_LDPOV4;
1084
e4a82008 1085 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1086
1087 return (CMD_SUCCESS);
1088}
1089
1090int
1224e5c4 1091ldp_vty_neighbor_password(struct vty *vty, const char *negate, struct in_addr lsr_id,
c740f7d3 1092 const char *password_str)
eac6e3f0 1093{
eac6e3f0
RW
1094 size_t password_len;
1095 struct nbr_params *nbrp;
eac6e3f0 1096
e59294e2 1097 if (password_str == NULL) {
1098 vty_out (vty, "%% Missing password\n");
1099 return (CMD_WARNING_CONFIG_FAILED);
1100 }
1101
1224e5c4 1102 if (bad_addr_v4(lsr_id)) {
5c7571d4 1103 vty_out (vty, "%% Malformed address\n");
f1a05de9 1104 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
1105 }
1106
eac6e3f0
RW
1107 nbrp = nbr_params_find(vty_conf, lsr_id);
1108
1224e5c4 1109 if (negate) {
eac6e3f0 1110 if (nbrp == NULL)
56b8a8d2 1111 return (CMD_SUCCESS);
eac6e3f0
RW
1112
1113 memset(&nbrp->auth, 0, sizeof(nbrp->auth));
1114 nbrp->auth.method = AUTH_NONE;
1115 } else {
1116 if (nbrp == NULL) {
1117 nbrp = nbr_params_new(lsr_id);
76c4abd1 1118 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 1119 QOBJ_REG(nbrp, nbr_params);
eac6e3f0
RW
1120 } else if (nbrp->auth.method == AUTH_MD5SIG &&
1121 strcmp(nbrp->auth.md5key, password_str) == 0)
56b8a8d2 1122 return (CMD_SUCCESS);
eac6e3f0
RW
1123
1124 password_len = strlcpy(nbrp->auth.md5key, password_str,
1125 sizeof(nbrp->auth.md5key));
1126 if (password_len >= sizeof(nbrp->auth.md5key))
3efd0893 1127 vty_out(vty, "%% password has been truncated to %zu characters.", sizeof(nbrp->auth.md5key) - 1);
25db1317 1128 nbrp->auth.md5key_len = strlen(nbrp->auth.md5key);
eac6e3f0
RW
1129 nbrp->auth.method = AUTH_MD5SIG;
1130 }
1131
e4a82008 1132 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1133
1134 return (CMD_SUCCESS);
eac6e3f0
RW
1135}
1136
1137int
1224e5c4
RW
1138ldp_vty_neighbor_ttl_security(struct vty *vty, const char *negate,
1139 struct in_addr lsr_id, const char *hops_str)
eac6e3f0 1140{
eac6e3f0
RW
1141 struct nbr_params *nbrp;
1142 long int hops = 0;
1143 char *ep;
eac6e3f0 1144
1224e5c4 1145 if (bad_addr_v4(lsr_id)) {
5c7571d4 1146 vty_out (vty, "%% Malformed address\n");
f1a05de9 1147 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
1148 }
1149
1150 if (hops_str) {
1151 hops = strtol(hops_str, &ep, 10);
1152 if (*ep != '\0' || hops < 1 || hops > 254) {
5c7571d4 1153 vty_out (vty, "%% Invalid hop count\n");
eac6e3f0
RW
1154 return (CMD_SUCCESS);
1155 }
1156 }
1157
eac6e3f0
RW
1158 nbrp = nbr_params_find(vty_conf, lsr_id);
1159
1224e5c4 1160 if (negate) {
eac6e3f0 1161 if (nbrp == NULL)
56b8a8d2 1162 return (CMD_SUCCESS);
eac6e3f0
RW
1163
1164 nbrp->flags &= ~(F_NBRP_GTSM|F_NBRP_GTSM_HOPS);
1165 nbrp->gtsm_enabled = 0;
1166 nbrp->gtsm_hops = 0;
1167 } else {
1168 if (nbrp == NULL) {
1169 nbrp = nbr_params_new(lsr_id);
76c4abd1 1170 RB_INSERT(nbrp_head, &vty_conf->nbrp_tree, nbrp);
1d75a89d 1171 QOBJ_REG(nbrp, nbr_params);
eac6e3f0
RW
1172 }
1173
1174 nbrp->flags |= F_NBRP_GTSM;
1175 nbrp->flags &= ~F_NBRP_GTSM_HOPS;
1176 if (hops_str) {
1177 nbrp->gtsm_enabled = 1;
1178 nbrp->gtsm_hops = hops;
1179 nbrp->flags |= F_NBRP_GTSM_HOPS;
1180 } else
1181 nbrp->gtsm_enabled = 0;
1182 }
1183
e4a82008 1184 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1185
1186 return (CMD_SUCCESS);
eac6e3f0
RW
1187}
1188
1189int
1224e5c4 1190ldp_vty_l2vpn(struct vty *vty, const char *negate, const char *name_str)
eac6e3f0 1191{
eac6e3f0 1192 struct l2vpn *l2vpn;
1d75a89d
RW
1193 struct l2vpn_if *lif;
1194 struct l2vpn_pw *pw;
eac6e3f0 1195
e59294e2 1196 if (name_str == NULL) {
1197 vty_out (vty, "%% Missing name\n");
1198 return (CMD_WARNING_CONFIG_FAILED);
1199 }
1200
eac6e3f0
RW
1201 l2vpn = l2vpn_find(vty_conf, name_str);
1202
1224e5c4 1203 if (negate) {
eac6e3f0 1204 if (l2vpn == NULL)
56b8a8d2 1205 return (CMD_SUCCESS);
eac6e3f0 1206
1d75a89d
RW
1207 RB_FOREACH(lif, l2vpn_if_head, &l2vpn->if_tree)
1208 QOBJ_UNREG(lif);
1209 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_tree)
1210 QOBJ_UNREG(pw);
1211 RB_FOREACH(pw, l2vpn_pw_head, &l2vpn->pw_inactive_tree)
1212 QOBJ_UNREG(pw);
1213 QOBJ_UNREG(l2vpn);
90d7e7bd 1214 RB_REMOVE(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
eac6e3f0 1215 l2vpn_del(l2vpn);
1d75a89d 1216
e4a82008 1217 ldp_config_apply(vty, vty_conf);
1d75a89d 1218
eac6e3f0
RW
1219 return (CMD_SUCCESS);
1220 }
1221
0b47280e 1222 if (l2vpn) {
1d75a89d 1223 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
56b8a8d2 1224 return (CMD_SUCCESS);
0b47280e 1225 }
eac6e3f0
RW
1226
1227 l2vpn = l2vpn_new(name_str);
1228 l2vpn->type = L2VPN_TYPE_VPLS;
90d7e7bd 1229 RB_INSERT(l2vpn_head, &vty_conf->l2vpn_tree, l2vpn);
1d75a89d
RW
1230 QOBJ_REG(l2vpn, l2vpn);
1231
1232 VTY_PUSH_CONTEXT(LDP_L2VPN_NODE, l2vpn);
eac6e3f0 1233
e4a82008 1234 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1235
1236 return (CMD_SUCCESS);
eac6e3f0
RW
1237}
1238
1239int
1224e5c4 1240ldp_vty_l2vpn_bridge(struct vty *vty, const char *negate, const char *ifname)
eac6e3f0 1241{
1d75a89d 1242 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1243
1224e5c4 1244 if (negate)
eac6e3f0 1245 memset(l2vpn->br_ifname, 0, sizeof(l2vpn->br_ifname));
e59294e2 1246 else {
1247 if (ifname == NULL) {
1248 vty_out (vty, "%% Missing IF name\n");
1249 return (CMD_WARNING_CONFIG_FAILED);
1250 }
eac6e3f0 1251 strlcpy(l2vpn->br_ifname, ifname, sizeof(l2vpn->br_ifname));
e59294e2 1252 }
eac6e3f0 1253
e4a82008 1254 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1255
1256 return (CMD_SUCCESS);
1257}
1258
1259int
1224e5c4 1260ldp_vty_l2vpn_mtu(struct vty *vty, const char *negate, long mtu)
eac6e3f0 1261{
1d75a89d 1262 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1263
1224e5c4 1264 if (negate)
eac6e3f0
RW
1265 l2vpn->mtu = DEFAULT_L2VPN_MTU;
1266 else
1267 l2vpn->mtu = mtu;
1268
e4a82008 1269 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1270
1271 return (CMD_SUCCESS);
1272}
1273
1274int
1224e5c4 1275ldp_vty_l2vpn_pwtype(struct vty *vty, const char *negate, const char *type_str)
eac6e3f0 1276{
1d75a89d 1277 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1278 int pw_type;
eac6e3f0 1279
e59294e2 1280 if (type_str == NULL) {
1281 vty_out (vty, "%% Missing type\n");
1282 return (CMD_WARNING_CONFIG_FAILED);
1283 }
1284
eac6e3f0
RW
1285 if (strcmp(type_str, "ethernet") == 0)
1286 pw_type = PW_TYPE_ETHERNET;
1287 else
1288 pw_type = PW_TYPE_ETHERNET_TAGGED;
1289
1224e5c4 1290 if (negate)
eac6e3f0
RW
1291 l2vpn->pw_type = DEFAULT_PW_TYPE;
1292 else
1293 l2vpn->pw_type = pw_type;
1294
e4a82008 1295 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1296
1297 return (CMD_SUCCESS);
1298}
1299
1300int
1224e5c4 1301ldp_vty_l2vpn_interface(struct vty *vty, const char *negate, const char *ifname)
eac6e3f0 1302{
1d75a89d 1303 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1304 struct l2vpn_if *lif;
eac6e3f0 1305
e59294e2 1306 if (ifname == NULL) {
1307 vty_out (vty, "%% Missing IF name\n");
1308 return (CMD_WARNING_CONFIG_FAILED);
1309 }
1310
52bd4c23 1311 lif = l2vpn_if_find(l2vpn, ifname);
eac6e3f0 1312
1224e5c4 1313 if (negate) {
eac6e3f0 1314 if (lif == NULL)
56b8a8d2 1315 return (CMD_SUCCESS);
eac6e3f0 1316
1d75a89d 1317 QOBJ_UNREG(lif);
029c1958 1318 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
eac6e3f0 1319 free(lif);
1d75a89d 1320
e4a82008 1321 ldp_config_apply(vty, vty_conf);
1d75a89d 1322
eac6e3f0
RW
1323 return (CMD_SUCCESS);
1324 }
1325
1326 if (lif)
56b8a8d2 1327 return (CMD_SUCCESS);
eac6e3f0
RW
1328
1329 if (ldp_iface_is_configured(vty_conf, ifname)) {
5c7571d4 1330 vty_out (vty, "%% Interface is already in use\n");
56b8a8d2 1331 return (CMD_SUCCESS);
eac6e3f0
RW
1332 }
1333
52b530fc 1334 lif = l2vpn_if_new(l2vpn, ifname);
029c1958 1335 RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
1d75a89d 1336 QOBJ_REG(lif, l2vpn_if);
eac6e3f0 1337
e4a82008 1338 ldp_config_apply(vty, vty_conf);
eac6e3f0 1339
eac6e3f0
RW
1340 return (CMD_SUCCESS);
1341}
1342
1343int
1224e5c4 1344ldp_vty_l2vpn_pseudowire(struct vty *vty, const char *negate, const char *ifname)
eac6e3f0 1345{
1d75a89d 1346 VTY_DECLVAR_CONTEXT(l2vpn, l2vpn);
eac6e3f0 1347 struct l2vpn_pw *pw;
eac6e3f0 1348
e59294e2 1349 if (ifname == NULL) {
1350 vty_out (vty, "%% Missing IF name\n");
1351 return (CMD_WARNING_CONFIG_FAILED);
1352 }
1353
52bd4c23 1354 pw = l2vpn_pw_find(l2vpn, ifname);
eac6e3f0 1355
1224e5c4 1356 if (negate) {
eac6e3f0 1357 if (pw == NULL)
56b8a8d2 1358 return (CMD_SUCCESS);
eac6e3f0 1359
1d75a89d
RW
1360 QOBJ_UNREG(pw);
1361 if (pw->lsr_id.s_addr == INADDR_ANY || pw->pwid == 0)
1362 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
1363 else
1364 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
eac6e3f0 1365 free(pw);
1d75a89d 1366
e4a82008 1367 ldp_config_apply(vty, vty_conf);
1d75a89d 1368
eac6e3f0
RW
1369 return (CMD_SUCCESS);
1370 }
1371
1372 if (pw) {
1d75a89d 1373 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
56b8a8d2 1374 return (CMD_SUCCESS);
eac6e3f0
RW
1375 }
1376
1377 if (ldp_iface_is_configured(vty_conf, ifname)) {
5c7571d4 1378 vty_out (vty, "%% Interface is already in use\n");
56b8a8d2 1379 return (CMD_SUCCESS);
eac6e3f0
RW
1380 }
1381
52b530fc 1382 pw = l2vpn_pw_new(l2vpn, ifname);
eac6e3f0 1383 pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
20bacaeb 1384 RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
1d75a89d
RW
1385 QOBJ_REG(pw, l2vpn_pw);
1386
1387 VTY_PUSH_CONTEXT_SUB(LDP_PSEUDOWIRE_NODE, pw);
eac6e3f0 1388
e4a82008 1389 ldp_config_apply(vty, vty_conf);
eac6e3f0 1390
eac6e3f0 1391 return (CMD_SUCCESS);
eac6e3f0
RW
1392}
1393
1394int
1224e5c4 1395ldp_vty_l2vpn_pw_cword(struct vty *vty, const char *negate, const char *preference_str)
eac6e3f0 1396{
1d75a89d 1397 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0 1398
1224e5c4 1399 if (negate)
eac6e3f0
RW
1400 pw->flags |= F_PW_CWORD_CONF;
1401 else {
e59294e2 1402 if (!preference_str) {
1403 vty_out (vty, "%% Missing preference\n");
1404 return (CMD_WARNING_CONFIG_FAILED);
1405 }
eac6e3f0
RW
1406 if (preference_str[0] == 'e')
1407 pw->flags &= ~F_PW_CWORD_CONF;
1408 else
1409 pw->flags |= F_PW_CWORD_CONF;
1410 }
1411
e4a82008 1412 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1413
1414 return (CMD_SUCCESS);
1415}
1416
1417int
1224e5c4 1418ldp_vty_l2vpn_pw_nbr_addr(struct vty *vty, const char *negate, const char *addr_str)
eac6e3f0 1419{
1d75a89d 1420 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0
RW
1421 int af;
1422 union ldpd_addr addr;
eac6e3f0
RW
1423
1424 if (ldp_get_address(addr_str, &af, &addr) == -1 ||
1425 bad_addr(af, &addr)) {
5c7571d4 1426 vty_out (vty, "%% Malformed address\n");
f1a05de9 1427 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
1428 }
1429
1224e5c4 1430 if (negate) {
eac6e3f0
RW
1431 pw->af = AF_UNSPEC;
1432 memset(&pw->addr, 0, sizeof(pw->addr));
1433 pw->flags &= ~F_PW_STATIC_NBR_ADDR;
1434 } else {
1435 pw->af = af;
1436 pw->addr = addr;
1437 pw->flags |= F_PW_STATIC_NBR_ADDR;
1438 }
1439
e4a82008 1440 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1441
1442 return (CMD_SUCCESS);
1443}
1444
1445int
1224e5c4 1446ldp_vty_l2vpn_pw_nbr_id(struct vty *vty, const char *negate, struct in_addr lsr_id)
eac6e3f0 1447{
1d75a89d 1448 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0 1449
1224e5c4 1450 if (bad_addr_v4(lsr_id)) {
5c7571d4 1451 vty_out (vty, "%% Malformed address\n");
f1a05de9 1452 return (CMD_WARNING_CONFIG_FAILED);
eac6e3f0
RW
1453 }
1454
1224e5c4 1455 if (negate)
eac6e3f0
RW
1456 pw->lsr_id.s_addr = INADDR_ANY;
1457 else
1458 pw->lsr_id = lsr_id;
1459
e4a82008 1460 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1461
1462 return (CMD_SUCCESS);
1463}
1464
1465int
1224e5c4 1466ldp_vty_l2vpn_pw_pwid(struct vty *vty, const char *negate, long pwid)
eac6e3f0 1467{
1d75a89d 1468 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0 1469
1224e5c4 1470 if (negate)
eac6e3f0
RW
1471 pw->pwid = 0;
1472 else
1473 pw->pwid = pwid;
1474
e4a82008 1475 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1476
1477 return (CMD_SUCCESS);
1478}
1479
1480int
1224e5c4 1481ldp_vty_l2vpn_pw_pwstatus(struct vty *vty, const char *negate)
eac6e3f0 1482{
1d75a89d 1483 VTY_DECLVAR_CONTEXT_SUB(l2vpn_pw, pw);
eac6e3f0 1484
1224e5c4 1485 if (negate)
eac6e3f0
RW
1486 pw->flags |= F_PW_STATUSTLV_CONF;
1487 else
1488 pw->flags &= ~F_PW_STATUSTLV_CONF;
1489
e4a82008 1490 ldp_config_apply(vty, vty_conf);
eac6e3f0
RW
1491
1492 return (CMD_SUCCESS);
1493}
1494
bbee85d2
RW
1495struct iface *
1496iface_new_api(struct ldpd_conf *conf, const char *name)
1497{
1498 const char *ifname = name;
1499 struct iface *iface;
bbee85d2
RW
1500
1501 if (ldp_iface_is_configured(conf, ifname))
5afba51d 1502 return (NULL);
bbee85d2 1503
52b530fc 1504 iface = if_new(name);
7d3d7491 1505 RB_INSERT(iface_head, &conf->iface_tree, iface);
1d75a89d 1506 QOBJ_REG(iface, iface);
bbee85d2
RW
1507 return (iface);
1508}
1509
1510void
7d3d7491 1511iface_del_api(struct ldpd_conf *conf, struct iface *iface)
bbee85d2 1512{
1d75a89d 1513 QOBJ_UNREG(iface);
7d3d7491 1514 RB_REMOVE(iface_head, &conf->iface_tree, iface);
bbee85d2
RW
1515 free(iface);
1516}
1517
1518struct tnbr *
1519tnbr_new_api(struct ldpd_conf *conf, int af, union ldpd_addr *addr)
1520{
1521 struct tnbr *tnbr;
1522
1523 if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&addr->v6))
1524 return (NULL);
1525
1526 if (tnbr_find(conf, af, addr))
1527 return (NULL);
1528
1529 tnbr = tnbr_new(af, addr);
1530 tnbr->flags |= F_TNBR_CONFIGURED;
7989cdba 1531 RB_INSERT(tnbr_head, &conf->tnbr_tree, tnbr);
1d75a89d 1532 QOBJ_REG(tnbr, tnbr);
bbee85d2
RW
1533 return (tnbr);
1534}
1535
1536void
7989cdba 1537tnbr_del_api(struct ldpd_conf *conf, struct tnbr *tnbr)
bbee85d2 1538{
1d75a89d 1539 QOBJ_UNREG(tnbr);
7989cdba 1540 RB_REMOVE(tnbr_head, &conf->tnbr_tree, tnbr);
bbee85d2
RW
1541 free(tnbr);
1542}
1543
1544struct nbr_params *
1545nbrp_new_api(struct ldpd_conf *conf, struct in_addr lsr_id)
1546{
1547 struct nbr_params *nbrp;
1548
1549 if (nbr_params_find(conf, lsr_id))
1550 return (NULL);
1551
1552 nbrp = nbr_params_new(lsr_id);
76c4abd1 1553 RB_INSERT(nbrp_head, &conf->nbrp_tree, nbrp);
1d75a89d 1554 QOBJ_REG(nbrp, nbr_params);
bbee85d2
RW
1555 return (nbrp);
1556}
1557
1558void
76c4abd1 1559nbrp_del_api(struct ldpd_conf *conf, struct nbr_params *nbrp)
bbee85d2 1560{
1d75a89d 1561 QOBJ_UNREG(nbrp);
76c4abd1 1562 RB_REMOVE(nbrp_head, &conf->nbrp_tree, nbrp);
bbee85d2
RW
1563 free(nbrp);
1564}
1565
1566struct l2vpn *
1567l2vpn_new_api(struct ldpd_conf *conf, const char *name)
1568{
1569 struct l2vpn *l2vpn;
1570
1571 if (l2vpn_find(conf, name))
1572 return (NULL);
1573
1574 l2vpn = l2vpn_new(name);
1575 l2vpn->type = L2VPN_TYPE_VPLS;
90d7e7bd 1576 RB_INSERT(l2vpn_head, &conf->l2vpn_tree, l2vpn);
1d75a89d 1577 QOBJ_REG(l2vpn, l2vpn);
bbee85d2
RW
1578 return (l2vpn);
1579}
1580
1581void
90d7e7bd 1582l2vpn_del_api(struct ldpd_conf *conf, struct l2vpn *l2vpn)
bbee85d2
RW
1583{
1584 struct l2vpn_if *lif;
1585 struct l2vpn_pw *pw;
1586
55cd0f61
DS
1587 while (!RB_EMPTY(l2vpn_if_head, &l2vpn->if_tree)) {
1588 lif = RB_ROOT(l2vpn_if_head, &l2vpn->if_tree);
1589
1d75a89d 1590 QOBJ_UNREG(lif);
029c1958 1591 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
bbee85d2
RW
1592 free(lif);
1593 }
55cd0f61
DS
1594 while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_tree)) {
1595 pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_tree);
1596
1d75a89d 1597 QOBJ_UNREG(pw);
20bacaeb 1598 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_tree, pw);
bbee85d2
RW
1599 free(pw);
1600 }
55cd0f61
DS
1601 while (!RB_EMPTY(l2vpn_pw_head, &l2vpn->pw_inactive_tree)) {
1602 pw = RB_ROOT(l2vpn_pw_head, &l2vpn->pw_inactive_tree);
1603
1d75a89d 1604 QOBJ_UNREG(pw);
20bacaeb 1605 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
bbee85d2
RW
1606 free(pw);
1607 }
1d75a89d 1608 QOBJ_UNREG(l2vpn);
90d7e7bd 1609 RB_REMOVE(l2vpn_head, &conf->l2vpn_tree, l2vpn);
bbee85d2
RW
1610 free(l2vpn);
1611}
1612
1613struct l2vpn_if *
1614l2vpn_if_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
1615 const char *ifname)
1616{
1617 struct l2vpn_if *lif;
bbee85d2
RW
1618
1619 if (ldp_iface_is_configured(conf, ifname))
1620 return (NULL);
1621
52b530fc 1622 lif = l2vpn_if_new(l2vpn, ifname);
029c1958 1623 RB_INSERT(l2vpn_if_head, &l2vpn->if_tree, lif);
1d75a89d 1624 QOBJ_REG(lif, l2vpn_if);
bbee85d2
RW
1625 return (lif);
1626}
1627
1628void
029c1958 1629l2vpn_if_del_api(struct l2vpn *l2vpn, struct l2vpn_if *lif)
bbee85d2 1630{
1d75a89d 1631 QOBJ_UNREG(lif);
029c1958 1632 RB_REMOVE(l2vpn_if_head, &l2vpn->if_tree, lif);
bbee85d2
RW
1633 free(lif);
1634}
1635
1636struct l2vpn_pw *
1637l2vpn_pw_new_api(struct ldpd_conf *conf, struct l2vpn *l2vpn,
1638 const char *ifname)
1639{
1640 struct l2vpn_pw *pw;
bbee85d2
RW
1641
1642 if (ldp_iface_is_configured(conf, ifname))
1643 return (NULL);
1644
52b530fc 1645 pw = l2vpn_pw_new(l2vpn, ifname);
bbee85d2 1646 pw->flags = F_PW_STATUSTLV_CONF|F_PW_CWORD_CONF;
20bacaeb 1647 RB_INSERT(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
1d75a89d 1648 QOBJ_REG(pw, l2vpn_pw);
bbee85d2
RW
1649 return (pw);
1650}
1651
1652void
20bacaeb 1653l2vpn_pw_del_api(struct l2vpn *l2vpn, struct l2vpn_pw *pw)
bbee85d2 1654{
1d75a89d 1655 QOBJ_UNREG(pw);
20bacaeb 1656 RB_REMOVE(l2vpn_pw_head, &l2vpn->pw_inactive_tree, pw);
bbee85d2
RW
1657 free(pw);
1658}