]>
git.proxmox.com Git - mirror_frr.git/blob - vtysh/vtysh_config.c
1 /* Configuration generator.
2 * Copyright (C) 2000 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include "vtysh/vtysh.h"
28 #include "vtysh/vtysh_user.h"
30 DEFINE_MGROUP(MVTYSH
, "vtysh")
31 DEFINE_MTYPE_STATIC(MVTYSH
, VTYSH_CONFIG
, "Vtysh configuration")
32 DEFINE_MTYPE_STATIC(MVTYSH
, VTYSH_CONFIG_LINE
, "Vtysh configuration line")
38 /* Configuration node name. */
41 /* Configuration string line. */
44 /* Configuration can be nest. */
45 struct config
*config
;
47 /* Index of this config. */
51 struct list
*config_top
;
54 line_cmp (char *c1
, char *c2
)
56 return strcmp (c1
, c2
);
62 XFREE (MTYPE_VTYSH_CONFIG_LINE
, line
);
65 static struct config
*
68 struct config
*config
;
69 config
= XCALLOC (MTYPE_VTYSH_CONFIG
, sizeof (struct config
));
74 config_cmp (struct config
*c1
, struct config
*c2
)
76 return strcmp (c1
->name
, c2
->name
);
80 config_del (struct config
* config
)
82 list_delete (config
->line
);
84 XFREE (MTYPE_VTYSH_CONFIG_LINE
, config
->name
);
85 XFREE (MTYPE_VTYSH_CONFIG
, config
);
88 static struct config
*
89 config_get (int index
, const char *line
)
91 struct config
*config
;
92 struct config
*config_loop
;
94 struct listnode
*node
, *nnode
;
96 config
= config_loop
= NULL
;
98 master
= vector_lookup_ensure (configvec
, index
);
102 master
= list_new ();
103 master
->del
= (void (*) (void *))config_del
;
104 master
->cmp
= (int (*)(void *, void *)) config_cmp
;
105 vector_set_index (configvec
, index
, master
);
108 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config_loop
))
110 if (strcmp (config_loop
->name
, line
) == 0)
111 config
= config_loop
;
116 config
= config_new ();
117 config
->line
= list_new ();
118 config
->line
->del
= (void (*) (void *))line_del
;
119 config
->line
->cmp
= (int (*)(void *, void *)) line_cmp
;
120 config
->name
= XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
);
121 config
->index
= index
;
122 listnode_add (master
, config
);
128 config_add_line (struct list
*config
, const char *line
)
130 listnode_add (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
134 config_add_line_uniq (struct list
*config
, const char *line
)
136 struct listnode
*node
, *nnode
;
139 for (ALL_LIST_ELEMENTS (config
, node
, nnode
, pnt
))
141 if (strcmp (pnt
, line
) == 0)
144 listnode_add_sort (config
, XSTRDUP (MTYPE_VTYSH_CONFIG_LINE
, line
));
148 vtysh_config_parse_line (void *arg
, const char *line
)
151 static struct config
*config
= NULL
;
161 /* printf ("[%s]\n", line); */
165 /* Suppress exclamation points ! and commented lines. The !s are generated
166 * dynamically in vtysh_config_dump() */
171 /* Store line to current configuration. */
174 if (strncmp (line
, " link-params", strlen (" link-params")) == 0)
176 config_add_line (config
->line
, line
);
177 config
->index
= LINK_PARAMS_NODE
;
179 else if (config
->index
== LINK_PARAMS_NODE
&&
180 strncmp (line
, " exit-link-params", strlen (" exit")) == 0)
182 config_add_line (config
->line
, line
);
183 config
->index
= INTERFACE_NODE
;
185 else if (config
->index
== RMAP_NODE
||
186 config
->index
== INTERFACE_NODE
||
187 config
->index
== NS_NODE
||
188 config
->index
== VTY_NODE
||
189 config
->index
== VRF_NODE
)
190 config_add_line_uniq (config
->line
, line
);
192 config_add_line (config
->line
, line
);
195 config_add_line (config_top
, line
);
198 if (strncmp (line
, "interface", strlen ("interface")) == 0)
199 config
= config_get (INTERFACE_NODE
, line
);
200 else if (strncmp (line
, "logical-router", strlen ("ns")) == 0)
201 config
= config_get (NS_NODE
, line
);
202 else if (strncmp (line
, "vrf", strlen ("vrf")) == 0)
203 config
= config_get (VRF_NODE
, line
);
204 else if (strncmp (line
, "router-id", strlen ("router-id")) == 0)
205 config
= config_get (ZEBRA_NODE
, line
);
206 else if (strncmp (line
, "router rip", strlen ("router rip")) == 0)
207 config
= config_get (RIP_NODE
, line
);
208 else if (strncmp (line
, "router ripng", strlen ("router ripng")) == 0)
209 config
= config_get (RIPNG_NODE
, line
);
210 else if (strncmp (line
, "router eigrp", strlen ("router eigrp")) == 0)
211 config
= config_get (EIGRP_NODE
, line
);
212 else if (strncmp (line
, "router babel", strlen ("router babel")) == 0)
213 config
= config_get (BABEL_NODE
, line
);
214 else if (strncmp (line
, "router ospf", strlen ("router ospf")) == 0)
215 config
= config_get (OSPF_NODE
, line
);
216 else if (strncmp (line
, "router ospf6", strlen ("router ospf6")) == 0)
217 config
= config_get (OSPF6_NODE
, line
);
218 else if (strncmp (line
, "mpls ldp", strlen ("mpls ldp")) == 0)
219 config
= config_get (LDP_NODE
, line
);
220 else if (strncmp (line
, "l2vpn", strlen ("l2vpn")) == 0)
221 config
= config_get (LDP_L2VPN_NODE
, line
);
222 else if (strncmp (line
, "router bgp", strlen ("router bgp")) == 0)
223 config
= config_get (BGP_NODE
, line
);
224 else if (strncmp (line
, "router isis", strlen ("router isis")) == 0)
225 config
= config_get (ISIS_NODE
, line
);
226 else if (strncmp (line
, "route-map", strlen ("route-map")) == 0)
227 config
= config_get (RMAP_NODE
, line
);
228 else if (strncmp (line
, "access-list", strlen ("access-list")) == 0)
229 config
= config_get (ACCESS_NODE
, line
);
230 else if (strncmp (line
, "ipv6 access-list",
231 strlen ("ipv6 access-list")) == 0)
232 config
= config_get (ACCESS_IPV6_NODE
, line
);
233 else if (strncmp (line
, "ip prefix-list",
234 strlen ("ip prefix-list")) == 0)
235 config
= config_get (PREFIX_NODE
, line
);
236 else if (strncmp (line
, "ipv6 prefix-list",
237 strlen ("ipv6 prefix-list")) == 0)
238 config
= config_get (PREFIX_IPV6_NODE
, line
);
239 else if (strncmp (line
, "ip as-path access-list",
240 strlen ("ip as-path access-list")) == 0)
241 config
= config_get (AS_LIST_NODE
, line
);
242 else if (strncmp (line
, "ip community-list", strlen ("ip community-list")) == 0 ||
243 strncmp (line
, "ip extcommunity-list", strlen ("ip extcommunity-list")) == 0)
244 config
= config_get (COMMUNITY_LIST_NODE
, line
);
245 else if (strncmp (line
, "ip route", strlen ("ip route")) == 0)
246 config
= config_get (IP_NODE
, line
);
247 else if (strncmp (line
, "ipv6 route", strlen ("ipv6 route")) == 0)
248 config
= config_get (IP_NODE
, line
);
249 else if (strncmp (line
, "key", strlen ("key")) == 0)
250 config
= config_get (KEYCHAIN_NODE
, line
);
251 else if (strncmp (line
, "line", strlen ("line")) == 0)
252 config
= config_get (VTY_NODE
, line
);
253 else if ( (strncmp (line
, "ipv6 forwarding",
254 strlen ("ipv6 forwarding")) == 0)
255 || (strncmp (line
, "ip forwarding",
256 strlen ("ip forwarding")) == 0) )
257 config
= config_get (FORWARDING_NODE
, line
);
258 else if (strncmp (line
, "service", strlen ("service")) == 0)
259 config
= config_get (SERVICE_NODE
, line
);
260 else if (strncmp (line
, "debug vrf", strlen ("debug vrf")) == 0)
261 config
= config_get (VRF_DEBUG_NODE
, line
);
262 else if (strncmp (line
, "debug", strlen ("debug")) == 0)
263 config
= config_get (DEBUG_NODE
, line
);
264 else if (strncmp (line
, "password", strlen ("password")) == 0
265 || strncmp (line
, "enable password",
266 strlen ("enable password")) == 0)
267 config
= config_get (AAA_NODE
, line
);
268 else if (strncmp (line
, "ip protocol", strlen ("ip protocol")) == 0)
269 config
= config_get (PROTOCOL_NODE
, line
);
270 else if (strncmp (line
, "ipv6 protocol", strlen ("ipv6 protocol")) == 0)
271 config
= config_get (PROTOCOL_NODE
, line
);
272 else if (strncmp (line
, "ip nht", strlen ("ip nht")) == 0)
273 config
= config_get (PROTOCOL_NODE
, line
);
274 else if (strncmp (line
, "ipv6 nht", strlen ("ipv6 nht")) == 0)
275 config
= config_get (PROTOCOL_NODE
, line
);
276 else if (strncmp (line
, "mpls", strlen ("mpls")) == 0)
277 config
= config_get (MPLS_NODE
, line
);
280 if (strncmp (line
, "log", strlen ("log")) == 0
281 || strncmp (line
, "hostname", strlen ("hostname")) == 0
282 || strncmp (line
, "frr", strlen ("frr")) == 0
283 || strncmp (line
, "agentx", strlen ("agentx")) == 0
284 || strncmp (line
, "no log", strlen ("no log")) == 0
286 config_add_line_uniq (config_top
, line
);
288 config_add_line (config_top
, line
);
295 /* Macro to check delimiter is needed between each configuration line
297 #define NO_DELIMITER(I) \
298 ((I) == ACCESS_NODE || (I) == PREFIX_NODE || (I) == IP_NODE \
299 || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \
300 (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \
301 || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \
302 || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE || (I) == MPLS_NODE)
304 /* Display configuration to file pointer. */
306 vtysh_config_dump (FILE *fp
)
308 struct listnode
*node
, *nnode
;
309 struct listnode
*mnode
, *mnnode
;
310 struct config
*config
;
315 for (ALL_LIST_ELEMENTS (config_top
, node
, nnode
, line
))
317 fprintf (fp
, "%s\n", line
);
323 for (i
= 0; i
< vector_active (configvec
); i
++)
324 if ((master
= vector_slot (configvec
, i
)) != NULL
)
326 for (ALL_LIST_ELEMENTS (master
, node
, nnode
, config
))
328 /* Don't print empty sections for interface/vrf. Route maps on the
329 * other hand could have a legitimate empty section at the end.
331 if ((config
->index
== INTERFACE_NODE
|| config
->index
== VRF_NODE
)
332 && list_isempty (config
->line
))
335 fprintf (fp
, "%s\n", config
->name
);
338 for (ALL_LIST_ELEMENTS (config
->line
, mnode
, mnnode
, line
))
340 fprintf (fp
, "%s\n", line
);
343 if (! NO_DELIMITER (i
))
349 if (NO_DELIMITER (i
))
356 for (i
= 0; i
< vector_active (configvec
); i
++)
357 if ((master
= vector_slot (configvec
, i
)) != NULL
)
359 list_delete (master
);
360 vector_slot (configvec
, i
) = NULL
;
362 list_delete_all_node (config_top
);
365 /* Read up configuration file from file_name. */
367 vtysh_read_file (FILE *confp
)
373 vty
->fd
= 0; /* stdout */
374 vty
->type
= VTY_TERM
;
375 vty
->node
= CONFIG_NODE
;
377 vtysh_execute_no_pager ("enable");
378 vtysh_execute_no_pager ("configure terminal");
380 /* Execute configuration file. */
381 ret
= vtysh_config_from_file (vty
, confp
);
383 vtysh_execute_no_pager ("end");
384 vtysh_execute_no_pager ("disable");
391 /* Read up configuration file from config_default_dir. */
393 vtysh_read_config (const char *config_default_dir
)
398 confp
= fopen (config_default_dir
, "r");
401 fprintf (stderr
, "%% Can't open configuration file %s due to '%s'.\n",
402 config_default_dir
, safe_strerror (errno
));
403 return (CMD_ERR_NO_FILE
);
406 ret
= vtysh_read_file (confp
);
412 /* We don't write vtysh specific into file from vtysh. vtysh.conf should
413 * be edited by hand. So, we handle only "write terminal" case here and
414 * integrate vtysh specific conf with conf from daemons.
417 vtysh_config_write ()
420 extern struct host host
;
424 sprintf (line
, "hostname %s", host
.name
);
425 vtysh_config_parse_line(NULL
, line
);
427 if (vtysh_write_integrated
== WRITE_INTEGRATED_NO
)
428 vtysh_config_parse_line (NULL
, "no service integrated-vtysh-config");
429 if (vtysh_write_integrated
== WRITE_INTEGRATED_YES
)
430 vtysh_config_parse_line (NULL
, "service integrated-vtysh-config");
432 user_config_write ();
438 config_top
= list_new ();
439 config_top
->del
= (void (*) (void *))line_del
;
440 configvec
= vector_init (1);