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