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